Reputation: 131
Firstly, I'm building on the Giant Gecko EFM32 using SiLabs IDE and want to track my task usage via vTaskGetRunTimeStats(). So firstly, I use the STK3700_freertos_tickless which has two tasks - one of which I add:
static char cBuffer[ 512 ];
vTaskGetRunTimeStats( cBuffer );
To my FreeRTOSConfig.h:
#define configUSE_TRACE_FACILITY ( 1 )
#define configGENERATE_RUN_TIME_STATS ( 1 )
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL )
#define configUSE_STATS_FORMATTING_FUNCTIONS ( 1 )
#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerTicks
Now, firstly - I removed:
volatile unsigned long ulHighFrequencyTimerTicks;
And moved it to tasks.c as I was getting:
./FreeRTOS/efm32gg/tasks.o: In function
vTaskStartScheduler': C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:1532: undefined reference to
ulHighFrequencyTimerTicks' ./FreeRTOS/efm32gg/tasks.o: In functionuxTaskGetSystemState': C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:1815: undefined reference to
ulHighFrequencyTimerTicks' ./FreeRTOS/efm32gg/tasks.o: In functionvTaskSwitchContext': C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:2173: undefined reference to
ulHighFrequencyTimerTicks' collect2.exe: error: ld returned 1 exit status make: *** [STK3700_freertos_tickless.axf] Error 1
If I put it in tasks.c to remove the error, then my demo gets stuck in
void vPortFree( void *pv )
{
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
heap_4.c for alternative implementations, and the memory management pages of
http://www.FreeRTOS.org for more information. */
( void ) pv;
/* Force an assert as it is invalid to call this function. */
configASSERT( pv == NULL );
}
Increasing my heap does nothing to help. I know I should resolve the first error, but there putting it as an extern in FreeRTOSConfig.h isn't working.
Which setting is missing? Is it valid to move the high tick def to tasks.c?
Thanks in advance, Chris
Added functions in the FreeRTOSconfig.h:
/* Run time stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS ( 1 )
extern volatile unsigned long ulHighFrequencyTimerTicks;
extern void vConfigureTimerForRunTimeStats( void );
extern unsigned long vGetTimerForRunTimeStats( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() vGetTimerForRunTimeStats()
And main.c respectively:
void vConfigureTimerForRunTimeStats( void ) {
CMU->HFRCOCTRL = 0x8; // Set High Freq. RC Osc. to 1 MHz
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_TIMER3; // Enable clock for Timer3
TIMER3->CNT = 0x0;
TIMER3->CTRL = ( TIMER3->CTRL & ~_TIMER_CTRL_PRESC_MASK) | TIMER_CTRL_PRESC_DIV1024; // Prescaler needed to reduce resolution, 1024
TIMER3->CMD = 0x1; // Start Timer3
}
unsigned long vGetTimerForRunTimeStats( void ) {
return ( TIMER3->CNT );
}
All compiles fine and my vTaskGetRunTimeStats is called in the following function, based on the STK3700_freertos_tickless example code:
static void LcdPrint(void *pParameters)
{
pParameters = pParameters; /* to quiet warnings */
static char sBuffer[ 240 ]; // 40 B per task
for (;;)
{
/* Wait for semaphore, then display next number */
if (pdTRUE == xSemaphoreTake(sem, portMAX_DELAY)) {
SegmentLCD_Write(text);
}
vTaskGetRunTimeStats( ( char * ) sBuffer );
}
}
But now my error is an undefined reference:
Finished building: ../src/main.c Building target: STK3700_freertos_tickless.axf Invoking: GNU ARM C Linker arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "STK3700_freertos_tickless.ld" -Xlinker --gc-sections -Xlinker -Map="STK3700_freertos_tickless.map" --specs=nano.specs -o STK3700_freertos_tickless.axf "./src/low_power_tick_management.o" "./src/main.o" "./emlib/em_assert.o" "./emlib/em_burtc.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_int.o" "./emlib/em_lcd.o" "./emlib/em_rmu.o" "./emlib/em_rtc.o" "./emlib/em_system.o" "./FreeRTOS/efm32gg/croutine.o" "./FreeRTOS/efm32gg/heap_1.o" "./FreeRTOS/efm32gg/list.o" "./FreeRTOS/efm32gg/port_gcc.o" "./FreeRTOS/efm32gg/queue.o" "./FreeRTOS/efm32gg/tasks.o" "./FreeRTOS/efm32gg/timers.o" "./Drivers/segmentlcd.o" "./Drivers/sleep.o" "./CMSIS/efm32gg/startup_gcc_efm32gg.o" "./CMSIS/efm32gg/system_efm32gg.o" "./BSP/bsp_trace.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group ./src/main.o: In function
LcdPrint': C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU ARM v4.8.3 - Debug/../src/main.c:61: undefined reference to
vTaskGetRunTimeStats' collect2.exe: error: ld returned 1 exit status make: *** [STK3700_freertos_tickless.axf] Error 1
I have #include "FreeRTOSConfig.h" #include "FreeRTOS.h" and #include "task.h" in my main.c file. Task.h contains: void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION;
Any last ideas? Almost there! C
forget update 1, the code works - a project clean did the trick.
But now it really is a heap_1.c issue being stuck in assertEFM function.
file "../FreeRTOS/efm32gg/heap_1.c"
line 153
I'll try increasing the stack + using the smaller sprintf code too. Best, C
Upvotes: 1
Views: 10169
Reputation: 3246
I think there are several things mixed up here.
First, I don't know where ulHighFrequencyTimerTicks is normally defined or incremented, it is not a FreeRTOS variable so assume it is part of the application. That would make sense as run-time-stats require a clock provided by the application (as the clock is dependent on the available hardware). In any case, it is just a variable, so the normal C scope rules apply. I expect it will be declared and incremented in one file, but then defining portGET_RUN_TIME_COUNTER_VALUE() to reference it means you are trying to reference it from a separate file - hence the linker error. That can be fixed by leaving the variable where it was, and declaring it as extern just in the file that is trying to use it out of scope. Or, implement a 'get' function in the file that declares ulHighFrequenyTimerTicks that just returns the variable's value, and define portGET_RUN_TIME_COUNTER_VALUE() to call the function.
(To answer the other comment portGET_RUN_TIME_COUNTER_VALUE() just needs to evaluate to a value, which can be a function return value, or a direct reference to a variable: http://www.freertos.org/rtos-run-time-stats.html)
Next, configUSE_STATS_FORMATTING_FUNCTIONS does not need to be 1 to use vTaskGetRunTimeState(). It only needs to be 1 if you want to use one of the helper functions that will format the collected stats into a human readable table. http://www.freertos.org/a00110.html#configUSE_STATS_FORMATTING_FUNCTIONS
Then, as already mentioned, getting stuck in vPortFree() is not related to a linker issue. I assume you are getting stuck in the configASSERT()? If so, then you are trying to free a block of memory that was not first allocated by calling pvPortMalloc(), or you are trying to free a block of memory that has been corrupted, or you are trying to free the same block of memory twice.
Upvotes: 1