I am building a project for STM32
based on libopencm3
and FreeRTOS
with one task: blinking LED with a delay.
void vApplicationStackOverflowHook(TaskHandle_t *pxTask, signed portCHAR *pcTaskName)
{
(void)pxTask;
(void)pcTaskName;
gpio_set(GPIOD, GPIO14);
while (1);
}
void vLedToggle(void *args)
{
while (1)
{
gpio_toggle(GPIOD, GPIO12);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
int main(void)
{
clock_setup();
gpio_setup();
xTaskCreate(vLedToggle, "vLedToggle", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
vTaskStartScheduler();
return 0;
}
Building is done with optimization disabled. As a result, incomprehensible functioning of the software (yes, the inclusion of optimization solves the problem, but I want to understand what is the reason for this behavior).
I noticed a strange thing: initially the LED is off, after the microcontroller starts up, it turns on, but it no longer goes out. It turns out that the program falls into blocking_handler()
due to Hard Fault (blocking_handler()
- standard libopencm3 stub for specific exceptions). But why this happens is not clear. I debug in VSCode
using JLink
. Unfortunately, the call did not find anything interesting on the stack (the last function is my attempt to get information about the error; removing the written code, the program will appear in blocking_handler()
):
The second strange thing: if put a breakpoint at the beginning of the task, step through all the functions (with enter in each), everything works perfectly.
No interrupts are used. The OS is configured according to the documentation and examples (I can publish the contents of the file, if necessary; configASSERT()
is defined). I tried to get the contents of the registers according to the instructions on the FreeRTOS
website, but to no avail - pc
, for example, contains: 0xA5A5A5A4
.
(If replace vTaskDelay()
with a banal cycle, then everything works.)
What could be the problem and how to deal with it without changing the level of optimization?