Во-первых, я собираюсь использовать Giant Gecko EFM32 с помощью SiLabs IDE и хочу отслеживать использование моей задачи с помощью 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: в функции
vTaskStartScheduler':
ulHighFrequencyTimerTicks ‘./FreeRTOS/efm32gg/tasks.o:
C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU
ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:1532: undefined
reference to
В функцииuxTaskGetSystemState':
ulHighFrequencyTimerTicks ‘./FreeRTOS/efm32gg/tasks.o:
C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU
ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:1815: undefined
reference to
В функцииvTaskSwitchContext':
ulHighFrequencyTimerTicks ‘collect2.exe: ошибка: ld
C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU
ARM v4.8.3 - Debug/../FreeRTOS/efm32gg/tasks.c:2173: undefined
reference to
вернул 1 состояние выхода make: *** [STK3700_freertos_tickless.axf] Ошибка
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, не работает.
Какая настройка отсутствует? Допустимо ли перенести определение высокой отметки в tasks.c?
Заранее спасибо Крис
Добавлены функции в 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 );
}
}
Но теперь моя ошибка — неопределенная ссылка:
Готовое здание: ../src/main.c Цель строительства:
STK3700_freertos_tickless.axf Вызов: GNU ARM C Linker
arm-none-eabi-gcc -g -gdwarf-2 -mcpu = кортекс-m3 -mthumb -T
«STK3700_freertos_tickless.ld» -Xlinker —gc-section -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: в функцииLcdPrint':
vTaskGetRunTimeStats ‘collect2.exe: ошибка: ld вернул 1 состояние выхода
C:\Users\Chris\SimplicityStudio\v3_workspace\STK3700_freertos_tickless\GNU
ARM v4.8.3 - Debug/../src/main.c:61: undefined reference to
make: *** [STK3700_freertos_tickless.axf] Ошибка 1
У меня есть #include «FreeRTOSConfig.h» #include «FreeRTOS.h» и #include «task.h» в моем файле main.c. Task.h содержит:
void vTaskGetRunTimeStats (char * pcWriteBuffer) PRIVILEGED_FUNCTION;
Есть последние идеи? Почти готово! С
Скрап обновления 1, код работает — чистый проект сделал свое дело.
Но теперь это действительно проблема heap_1.c, застрявшая в функции assertEFM.
file "../FreeRTOS/efm32gg/heap_1.c"line 153
Я попытаюсь увеличить стек +, используя меньший код sprintf. Бест, С
Я думаю, что здесь смешано несколько вещей.
Во-первых, я не знаю, где ulHighFrequencyTimerTicks обычно определяется или увеличивается, это не переменная FreeRTOS, поэтому предположим, что это часть приложения. Это имело бы смысл, поскольку статистика времени выполнения требует наличия часов, предоставляемых приложением (так как часы зависят от доступного оборудования). В любом случае, это просто переменная, поэтому применяются обычные правила области видимости Си. Я ожидаю, что он будет объявлен и увеличен в одном файле, но затем определение portGET_RUN_TIME_COUNTER_VALUE () для ссылки на него означает, что вы пытаетесь ссылаться на него из отдельного файла — отсюда ошибка компоновщика. Это можно исправить, оставив переменную там, где она была, и объявив ее как extern только в файле, который пытается использовать ее вне области видимости. Или реализуйте функцию get в файле, который объявляет ulHighFrequenyTimerTicks, который просто возвращает значение переменной, и определяете 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 (), или вы пытаетесь освободить поврежденный блок памяти, или вы пытаетесь освободить тот же блок памяти дважды.
Других решений пока нет …