首先,我正在使用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:
如果我将其放在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中将其作为外部错误无法正常工作。
缺少哪个设置?将高刻度线定义移到task.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 );
}
所有编译都可以,并且基于STK3700_freertos_tickless示例代码,在以下函数中调用了我的vTaskGetRunTimeStats:
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 );
}
}
但是现在我的错误是 undefined 的引用:
我的main.c文件中包含#include“FreeRTOSConfig.h” #include“FreeRTOS.h”和#include“task.h”。 Task.h包含:
void vTaskGetRunTimeStats(char * pcWriteBuffer)PRIVILEGED_FUNCTION;
还有什么想法吗?差不多好了! C
更新2:
报废更新1,代码有效-干净的项目可以解决问题。
但是,现在确实是一个被放到assertEFM函数中的heap_1.c问题。
file "../FreeRTOS/efm32gg/heap_1.c"
line 153
我也会尝试使用较小的sprintf代码来增加堆栈+。最好,C
最佳答案
我认为这里有些事情混在一起。
首先,我不知道ulHighFrequencyTimerTicks通常在何处定义或递增,它不是FreeRTOS变量,因此假定它是应用程序的一部分。这将是有道理的,因为运行时状态需要应用程序提供的时钟(因为该时钟取决于可用的硬件)。无论如何,它只是一个变量,因此适用常规C范围规则。我希望它会在一个文件中声明并递增,但是随后定义portGET_RUN_TIME_COUNTER_VALUE()引用它意味着您试图从一个单独的文件中引用它-因此出现链接器错误。可以通过以下方式解决此问题:将变量保留在原来的位置,然后在试图超出范围使用该文件的文件中将其声明为extern。或者,在声明ulHighFrequenyTimerTicks的文件中实现一个“get”函数,该函数仅返回变量的值,然后定义portGET_RUN_TIME_COUNTER_VALUE()来调用该函数。
(要回答其他评论,portGET_RUN_TIME_COUNTER_VALUE()只需计算一个值即可,该值可以是函数返回值,也可以直接引用变量:http://www.freertos.org/rtos-run-time-stats.html)
接下来,configUSE_STATS_FORMATTING_FUNCTIONS不必为1即可使用vTaskGetRunTimeState()。仅当您想使用将收集的统计信息格式化为人类可读表格的辅助功能之一时,才需要为1。 http://www.freertos.org/a00110.html#configUSE_STATS_FORMATTING_FUNCTIONS
然后,如上所述,卡在vPortFree()中与链接程序问题无关。我假设您被卡在configASSERT()中了吗?如果是这样,则您试图释放未通过调用pvPortMalloc()首先分配的内存块,或者试图释放已损坏的内存块,或者试图释放相同的内存块。两次。