upanie wrote on Tuesday, January 22, 2019:
Forgive me if I’m not clear but there is no place where I wrote that 4.8.4 fails.
4.8.4 just can’t compile V10.0.0 because it contains things that compiler 4.8.4 can’t understand.
That’s why I used the older FreeRtos V9.0.0 to be able to build it with the newest and the old (4.8.4) compiler.
I just wanted to prevent questions about trying the newest version of FreeRTOS.
The newest V10.0.0 crashest the same way as the V9.0.0 does when compiled with 8.x.x
Looks like changes between these versions do not introduce any bugs in this area.
Because of that I assumed that V9.0.0 would be the best choose as it can be built with 4.8.4 and 5.x.x and 8.x.x compilers.
And again the program works fine only when is compiled with 4.8.4. Newer compilers give binaries that crash.
I’m afraid ‘started to crash in some situations’ does not provide enough
information to start a thread on what might be the solution. Can you
say which situations, and how the system crashed (does it raise an
exception, does a configASSERT() get hit, etc.).
I wrote here that I described the problem in the repo Bitbucket and there are a bit more details.
But OK, I will write it here too.
Let’s say we have two binaries: binA and binB
binA is built with gcc 4.8.4 and binA is built with gcc 8.2.1
The simple idea of the test program is:
We have two tasks:
- task1 waits on queue and if data are present it sends it to the UART
- task2 is writing some string and sleeps for 5 seconds
And basically that’s it. Here is the code:
void task1(void *pvData) {
(void)pvData;
vTaskDelay(100);
while (1) {
while (xQueueReceive(usart_incoming_queue, &data, portMAX_DELAY) == pdTRUE) {
xprintf("Task 1 RCV: %c\n", data);
}
}
}
void task2(void *pvData) {
(void)pvData;
int it = 0;
while (1) {
vTaskDelay(5000);
xprintf("Task 2: %d\n", it++);
// xQueueSendToBack(usart_incoming_queue, &data, portMAX_DELAY);
}
}
xTaskHandle th_1, th_2;
void create_tasks(void) {
xTaskCreate(task1, (const char *) "TSK1", 64, NULL, tskIDLE_PRIORITY+1, &th_1);
xTaskCreate(task2, (const char *) "TSK2", 64, NULL, tskIDLE_PRIORITY+1, &th_2);
}
The full code can be found i the repo.
And here it goes:
binA works absolutely fine with no problems whatsoever.
binB works fine until a byte goes into the queue. Then portYIELD_WITHIN_API() (in xQueueGenericReceive) exits and in this moment stack is corrupted. pxQueue points to some random memory which contains some garbage, which is weird as the pointer is held in R0 register if I understand it correctly… Then some part of xQueueGenericReceive tries to work with the data and simply crashes. Then hard fault handler is called.
I can’t tel anything more detailed. It is hard to debug this problem.
Now, when I compile the same code with gcc 5.3.1 it crashes even if the queue is empty. But I don’t know where becuse I didn’t investigated it with this version of the compiler.
As far as I understand FreeRTOS itself works fine. It really does the job correctly when compiled with 4.8.4. I did a lot of reading and debuging the code of FreeRTOS and it looks really fine.
So I’m not sure if this is the correct place to ask for help. Maybe I should look for help on some gcc forum. But maybe I’m not the only one who experienced such problem with FreeRTOS, new GCC and STM32F030C6. If not then this place is probably the best one.
I can add that gcc 8.2.1 produce text section about 5% larger than gcc 4.8.4
Maybe some part of context switch is wrongly compiled or maybe I’m doing something totally wrong. I don’t knwo and that’s why I ask other people for help.