This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

interesting! BIOS_GetCpuFreq() return a wrong value?

Other Parts Discussed in Thread: OMAPL138, SYSBIOS

On my customized board (based on OMAPL138) there is a 25MHz crystal OSC. But the function BIOS_GetCpuFreq() of my SYSBIOS project calculates a result which is 24000000 not 25000000. Why?

  • Hi Jingang,

    Which version of the SYS/BIOS are you using? Can you share your application's .cfg file?

    BIOS_getCPUFreq() returns BIOS_cpuFreq. Have you checked this link?: software-dl.ti.com/.../BIOS.html

    Vikram
  • Hi Vikram,

    I'm using tirtos_c6000_2_00_01_23/product/bios_6_40_01_15. My app's .cfg file locates in my office PC and can't be copied out.

    Actually what I done about Clock in my .cfg file is just a modification of Timer Id from Any to 1. Tick period (us) is still 1000. tickSource is TickSource_TIMER. tickMode is TickMode_PERIODIC. PLLM in GEL file is replaced from 24 to 23 (before plus 1) due to 25MHz OSCIN.

    BIOS_GetCpuFreq(*) locates in BIOS.c which is called by ti/sysbios/timers/timer64/Timer.c before entering main(). I just used step into/over operation and watched its return value in BIOS initialization stage. I didn't use BIOS_GetCpuFreq(*) in my app code.

  • We can see something in this picture.

  • Jingang,

    You will have to update the BIOS_cpuFreq as described in this thread which answers a similar question as yours. Please see the thread.

    Vikram

  • Hi Vikram,

    I read that thread which tells a way to solve the problem by setting a static value in .cfg file and I think this might work.

    But I wanna say something else. Yesterday I add BIOS_GetCpuFreq() in main() of my app code and it gets a 300MHZ value after GEL file loaded. I am wondering how this function works exactly. Does it just return a static value we people set or BIOS sets by default or calculate a value base on user's physical hardware? If the latter, no matter how my hardware changes (eg. another crystal applied) I don't need to adjust my BIOS setting. I think this is good. After all, BIOS is a black box to we customers.

    By the way, I changed PRD12 register of the Timer which is specified by BIOS's tick to 25000 and it also works.

    Thanks very much!

  • Jingang,

    The 300MHz value is not from the GEL file but from the XDC platform file. The file can be found in <TI-RTOS>/products/<BIOS>/packages/ti/platforms/evmOMAPL138/Platform.xdc. The clock rate for the two cores are provided in this file. Please note changing the values in this file will not change the value in your application. The package has to be recompiled and we do not recommend recompiling it. Instead please follow the instructions in the thread that I shared.

    Unfortunately, TI-RTOS does not have the support for dynamic CPU frequency calculation currently. It can be only set statically.

    Also, we wouldn't recommend directly accessing the timer registers especially for the timers that TI-RTOS manages. It may cause problems. The recommend way is to use the available TI-RTOS interfaces and configuration options to adjust the values.

    Hope this helps.
    Vikram
  • Vikram, many thanks.

    I still have question. Before entering main(), BIOS_GetCpuFreq() returns a 24000000 value. After entering main() it returns a 300000000 one. How does the 24000000 come from?

    Further, my app platform file is created by myself. If I change the 'Clock Speed (MHz)' in this file the Platform.xdc file will be effected or not?

    One more, if I change the function - device_PLL0(0,23,1,0,1,11,5) to device_PLL0(0,24,1,0,1,11,5) in my GEL file, will the XDC update a value of 25*(24+1)/2=312.5MHz but not 300MHz?

    oops, so many questions...^_^
  • Jingang,

    At which point in the boot process did you check the frequency? The TI-RTOS initializations are part of the boot process which happens before reaching main. It depends on where you checked the value.

    Yes, if you have created a custom platform. Are you using the platform wizard to create the platform?

    No, XDCtools does not read the GEL file.

    Vikram

  • Vikram,

    I observed BIOS_GetCpuFreq() twice. By setting a breakpoint in Timer.c showing in the picture posted above, and coding this function in my main(){...}, after compile and download .out file, click the 'System Reset' icon and the 'Restart' one then we will see the PC (program counter) located at that breakpoint. Step into then till reach BIOS_GetCpuFreq(). A 24000000 result shows up. Carry on until reach main() and we will get a 300000000 result from BIOS_GetCpuFreq(). That's the sequence.

    I create my platform by CCSv6->File->New->Project...->RTSC-->New RTSC Platform->Next->customization of page1-> set 300 in Clock Speed item and other configuration about memory->OK.

  • Jingang,

    I think you are checking before the cpu frequency value has been initialized in TI-RTOS.

    Yes, that's the recommended way for creating a platform. You can change the value through that GUI.

    Vikram

  • Vikram,

    Final question, where can I configure/modifiy the OSCIN value?

  • Jingang,

    For OMAPL138, SYS/BIOS does not have support for configuring/modifying OSCIN. It is either set through GEL file (in debug) or through the user application (in non debug). SYS/BIOS only needs the cpu frequency which has to be set through BIOS_setCpuFreq() (if it has changed from the default value in platform)

    Vikram
  • Vikram, thanks.

    'It is either set through GEL file (in debug) or through the user application (in non debug)'. How can I implement these two methods in code?

    Best Regards,

  • Since BIOS_GetCpuFreq() just returns the hard-coded value in your RTSC platform, I spawn a task that measures the CPU freq using a known clock such as the 32768Hz RTC:

    Void measure_clocks(UArg arg0, UArg arg1)
    {
    	unsigned int start_cpu, start_rtc, end_cpu, end_rtc;
    	Types_FreqHz F;
    	printf("Entering measure_clocks()...\n");
    	SysMin_flush();
    
    	BIOS_getCpuFreq(&F);
    	printf("CPU Freq: %d Hz\n",(int)F.lo);
    
    	TimestampProvider_getFreq(&F);
    	printf("TimestampProvider Freq: %d Hz\n",(int)F.lo);
    
    	// check the cpu freq against the RTC
    	start_cpu = Timestamp_get32();
    	start_rtc = TimestampProvider_get32();
    	while(TimestampProvider_get32() - start_rtc < F.lo){
    		Task_sleep(10);
    	}
    	end_rtc = TimestampProvider_get32();
    	end_cpu = Timestamp_get32();
    
    	float cpu_freq, dt;
    	dt = (end_rtc-start_rtc);
    	dt *= 1.0/F.lo;
    	cpu_freq = (end_cpu - start_cpu)/dt;
    	printf("Measure CPU Freq: %d MHz\n", (int)(cpu_freq/1e6));
    
    	printf("Leaving measure_clocks()...\n");
    	SysMin_flush();
    }

    Enabling the correct TimestampProvider that uses the RTC depends on the target, but I think it is usually:

    var TimerProvider = xdc.useModule('ti.sysbios.timers.dmtimer.TimestampProvider');

  • Hi Brain,

    Your code shall work fine I think.

    My puzzle in fact is that the PRD12 value of the timer for generating RTOS tick which set by SYSBIOS can't be adjusted according to customers' crystal OSCIN. It's always calculated by using a 24MHz OSCIN even I changed my crystal to 25MHz.

    I tried method below and PRD12 is still according to 24MHz OSCIN.

    var BIOS = xdc.useModule('ti.sysbios.BIOS');

    BIOS.cpuFreq.lo = 300000000;

    BIOS.cpuFreq.hi = 0;

    PRD12 value is set during RTOS initialization period before entering main().