jcxz 236 6 июля, 2022 Опубликовано 6 июля, 2022 · Жалоба В 06.07.2022 в 19:32, Arlleex сказал: Весьма полезно иметь там именно то, что нужно (функцию-ловушку prvTaskExitError()), а не мусор. Улететь в специально придуманную функцию куда приятнее, чем улететь хрен пойми куда и часами искать этот баг, Если выхода из таска не имеется, то и штатным образом "улететь" - в принципе не получится. Так как отсутствуют сами команды возврата из функции (или отсутствует путь, по которому CPU может до них добраться). А при улёте нештатным образом (коли такое случится), совершенно не факт, что как адрес возврата будет воспринято именно то слово, о котором судачите. Тогда уж надо весь стек этим адресом возврата заполнять. В 06.07.2022 в 19:32, Arlleex сказал: учитывая, что порой люди сами не понимают ими же написанных программ. Не знаю как там в Кейле, но IAR позволяет назначить main()-функции задачи РТОС префиксы: __noreturn __task. В этом случае вроде компилятор должен выдавать варнинг, коли криворукий программёр в беспамятстве где-то допустит выход из такой функции. Сам я их всегда использую в таких случаях. Кроме того это полезно повышением оптимальности кода (хоть и чуток). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 6 июля, 2022 Опубликовано 6 июля, 2022 · Жалоба On 7/6/2022 at 4:50 PM, Arlleex said: Ну все, configTASK_RETURN_ADDRESS не задан, Сделал поиск по файлам, в FreeRTOS такое определение вообще ни где не встречается. Может быть оно как-то иначе называется ? И в описании FReeRTOS не вижу. https://freertos.org/a00110.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 6 июля, 2022 Опубликовано 6 июля, 2022 · Жалоба 54 минуты назад, jcxz сказал: Если выхода из таска не имеется, то и штатным образом "улететь" - в принципе не получится... Функция prvTaskExitError() только для того и придумана, чтобы пнуть под зад незадачливого программиста, замечтавшегося о прекрасном и случайно где-то в дебрях таска написавшего return. Я привел пример (выше), где именно так и произошло, хотя человек изначально, вроде, даже и не предполагал, что написал фигню. Этот хук не предназначен для случаев, когда стек испорчен каким бы то ни было образом. Цитата Не знаю как там в Кейле, но IAR позволяет назначить main()-функции задачи РТОС префиксы: __noreturn __task... Не знаю, что делает __task, но __noreturn точно есть. 49 минут назад, MiklPolikov сказал: Сделал поиск по файлам, в FreeRTOS такое определение вообще ни где не встречается. Может быть оно как-то иначе называется? Я смотрел первый попавшийся на просторах тыртырнета port.c. Вижу, что версия там древняя V7.6.0 и там было вот так Спойлер /* Let the user override the pre-loading of the initial LR with the address of prvTaskExitError() in case is messes up unwinding of the stack in the debugger. */ #ifdef configTASK_RETURN_ADDRESS #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS #else #define portTASK_RETURN_ADDRESS prvTaskExitError #endif ... portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) { /* Simulate the stack frame as it would be created by a context switch interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */ pxTopOfStack--; *pxTopOfStack = ( portSTACK_TYPE ) portTASK_RETURN_ADDRESS; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } В новом, свежем, уже так Спойлер StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, TaskFunction_t pxCode, void * pvParameters ) { /* Simulate the stack frame as it would be created by a context switch * interrupt. */ pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ return pxTopOfStack; } Соответственно, если у Вас версия свежая, то адрес prvTaskExitError() будет жестко прибит в стекфрейм и #define-ми это не регулируется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться