FreeRTOS vTaskGetRunTimeStats

FreeRTOS vTaskGetRunTimeStats

首先,我正在使用 SiLabs IDE 在 Giant Gecko EFM32 上构建,并希望通过 vTaskGetRunTimeStats() 跟踪我的任务使用情况。所以首先,我使用 STK3700_freertos_tickless 有两个任务 - 其中一个是我添加的:

static char cBuffer[ 512 ];
vTaskGetRunTimeStats( cBuffer );

给我的 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

现在,首先 - 我删除了:

volatile unsigned long ulHighFrequencyTimerTicks;

并将其移动到 tasks.c,因为我得到:

./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 function uxTaskGetSystemState': 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 function vTaskSwitchContext': 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

如果我把它放在 tasks.c 中以消除错误,那么我的演示就会卡在

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 );
}

增加我的堆没有任何帮助。我知道我应该解决第一个错误,但是将它作为外部文件放在 FreeRTOSConfig.h 中是行不通的。

缺少哪个设置?将 high tick def 移动到 tasks.c 是否有效?

提前致谢,克里斯

更新 1:

在 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()

和main.c分别为:

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 );
}

所有编译都很好,我的 vTaskGetRunTimeStats 在以下函数中被调用,基于 STK3700_freertos_tickless 示例代码:

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 );

  }
}

但现在我的错误是一个未定义的引用:

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

我的 main.c 文件中有 #include "FreeRTOSConfig.h" #include "FreeRTOS.h" 和 #include "task.h"。 Task.h 包含: void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION;

最后有什么想法吗?差不多好了! C

更新 2:

忘记更新 1,代码有效 - 一个项目清理就成功了。

但现在确实是一个 heap_1.c 卡在 assertEFM 函数中的问题。

file    "../FreeRTOS/efm32gg/heap_1.c"  
line    153 

我会尝试增加堆栈 + 也使用较小的 sprintf 代码。最好的,C

我认为这里有几件事混淆了。

首先,我不知道 ulHighFrequencyTimerTicks 通常在哪里定义或递增,它不是 FreeRTOS 变量,因此假设它是应用程序的一部分。这是有道理的,因为 run-time-stats 需要应用程序提供的时钟(因为时钟取决于可用的硬件)。在任何情况下,它都只是一个变量,所以正常的 C 作用域规则适用。我希望它将在一个文件中声明并递增,但随后定义 portGET_RUN_TIME_COUNTER_VALUE() 以引用它意味着您正试图从一个单独的文件中引用它 - 因此链接器错误。这可以通过将变量保留在原处并在试图在范围外使用它的文件中将其声明为 extern 来解决。或者,在声明 ulHighFrequenyTimerTicks 的文件中实现一个 'get' 函数,它只是 return 变量的值,并定义 portGET_RUN_TIME_COUNTER_VALUE() 来调用该函数。

(要回答其他评论 portGET_RUN_TIME_COUNTER_VALUE() 只需要评估一个值,它可以是函数 return 值,或者直接引用变量:http://www.freertos.org/rtos-run-time-stats.html)

接下来,configUSE_STATS_FORMATTING_FUNCTIONS 不需要为 1 即可使用 vTaskGetRunTimeState()。如果您想使用将收集的统计信息格式化为人类可读的格式的辅助函数之一,它只需要为 1 table。 http://www.freertos.org/a00110.html#configUSE_STATS_FORMATTING_FUNCTIONS

然后,如前所述,卡在 vPortFree() 中与链接器问题无关。我假设你被卡在了 configASSERT() 中?如果是这样,那么您正试图释放一个未首先通过调用 pvPortMalloc() 分配的内存块,或者您正试图释放一个已损坏的内存块,或者您正试图释放同一块内存两次。