Форум программистов, компьютерный форум, киберфорум
locm
Войти
Регистрация
Восстановить пароль

STM32F103C8T6, FreeRTOS - ошибка vTaskSwitchContext

Запись от locm размещена 16.03.2018 в 22:50
Показов 5315 Комментарии 0

При сборке проекта содержащего FreeRTOS компилятором GCC с активной опцией "Link-time optimization" появляется ошибка undefined reference to `vTaskSwitchContext' в функции xPortPendSVHandler файла port.c.
Код функции.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void xPortPendSVHandler(void)
{
    /* This is a naked function. */
 
    __asm volatile
    (
    "   mrs r0, psp                         \n"
    "   isb                                 \n"
    "                                       \n"
    "   ldr r3, pxCurrentTCBConst           \n" /* Get the location of the current TCB. */
    "   ldr r2, [r3]                        \n"
    "                                       \n"
    "   stmdb r0!, {r4-r11}                 \n" /* Save the remaining registers. */
    "   str r0, [r2]                        \n" /* Save the new top of stack into the first member of the TCB. */
    "                                       \n"
    "   stmdb sp!, {r3, r14}                \n"
    "   mov r0, %0                          \n"
    "   msr basepri, r0                     \n"
    "   bl vTaskSwitchContext               \n"
    "   mov r0, #0                          \n"
    "   msr basepri, r0                     \n"
    "   ldmia sp!, {r3, r14}                \n"
    "                                       \n" /* Restore the context, including the critical nesting count. */
    "   ldr r1, [r3]                        \n"
    "   ldr r0, [r1]                        \n" /* The first item in pxCurrentTCB is the task top of stack. */
    "   ldmia r0!, {r4-r11}                 \n" /* Pop the registers. */
    "   msr psp, r0                         \n"
    "   isb                                 \n"
    "   bx r14                              \n"
    "                                       \n"
    "   .align 4                            \n"
    "pxCurrentTCBConst: .word pxCurrentTCB  \n"
    ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
    );
}
Она представляет собой асм. вставку из которой вызывается функция vTaskSwitchContext, на отсутствие которой ругается компилятор. Подчеркну, что это происходит только при компиляции с опцией "Link-time optimization", позволяющей выполнять оптимизацию на этапе линковки.
Кроме этой асм. вставки, функция vTaskSwitchContext вызывается еще из одной, находящейся в функции xPortPendSVHandler также из port.c и из кода - функции xPortStartScheduler файла port.c. Там предпринята попытка исправить упомянутую ошибку, поскольку перед вызовом есть комментарий.
C
1
2
3
4
5
6
    /* Should never get here as the tasks will now be executing!  Call the task
    exit error function to prevent compiler warnings about a static function
    not being called in the case that the application writer overrides this
    functionality by defining configTASK_RETURN_ADDRESS.  Call
    vTaskSwitchContext() so link time optimisation does not remove the
    symbol. */
Но поскольку вызов только один, то оптимизатор при уровне выше -O0, по видимому вместо вызова функции производит ее непосредственную вставку в код, т. е. поступает как с inline функцией.

Исправить ошибку довольно просто. Нужно найти реализацию функции vTaskSwitchContext (она в файле tasks.c) и сообщить оптимизатору что функция используется добавив __attribute__((used)) перед началом функции.
После этого проект нормально собирается.

Тестовый проект с одной задачей.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "stm32f10x_conf.h"
 
#include "FreeRTOS.h"
#include "task.h"
 
TaskHandle_t hTask_Blink;
 
void TaskBlink(void const *argument)
{
  while(1)
  {
    GPIO_SetBits(GPIOC, GPIO_Pin_13);
    vTaskDelay(400);
    GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    vTaskDelay(400);
  }
}
 
int main(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 
    GPIO_Init(GPIOC, &GPIO_InitStructure);
 
    // Создание задач.
    xTaskCreate((TaskFunction_t) TaskBlink, "Blink",
                configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, hTask_Blink);
 
    vTaskStartScheduler(); // Запуск планировщика задач.
 
    while(1)
    {
    }
}
Но если залить прошивку в МК то выяснится что она не работает. Необходимо в проект (например FreeRTOSConfig.h) добавить строки, производящие ассоциацию вызовов прерываний с функциями FreeRTOS.
C
1
2
3
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
Вложения
Тип файла: 7z FreeRTOS_10.0.1_Blink.7z (295.2 Кб, 369 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru