BriscoeTech / Arduino-FreeRTOS-SAMD21

A port of FreeRTOS that runs on Arduino Samd21 boards
63 stars 19 forks source link

system lockups on queue or semaphore creation #8

Closed cheetor5923 closed 4 years ago

cheetor5923 commented 5 years ago

Hi There

At work here we've been working on a rather complex multitasking system on the Industruino platform. after we'd got 90% of the codebase complete all that remained was to create the queues to allow each process to talk to each other. Here the fun began. Following examples on the FreeRTOS website led to some very strange lockups and undefined behaviour of the device..

After some rather extensive debugging(and reading lots of assembly code) we managed to track down the problem to the pvPortMalloc subroutine. It turned out that in some cases the call to malloc() itself would fail internally and never return, not even return a NULL. For example trying to create a queue before creating tasks and starting the scheduler would always lock the system up hard. even though the example code from the FreeRTOS team for the SAMD boards showed this as being perfectly valid... Eventual solution was to dump heap_3.c entirely for heap_4.c instead. even then it was not possible to create semaphores or queues before starting the scheduler (although in this case it failed gracefully, performing the blink routine and returning NULL)

I suspect there may be something broken behind the scenes with malloc on the ATSAMD21G18 platform. I'm wondering is a move to heap_4 would be better for the project as a whole?

BriscoeTech commented 5 years ago

Hello cheetor5923,

Thanks for posting this! Its funny because I stumbled upon something funny last week and came to the same conclusion that the system needs heap_4!

I was attempting to make some c++ objects before starting the rtos and when I went to use them the objects didn't work. What left a bad taste in my mouth was when my monitor thread deleted itself afew minutes later, the c++ objects spontaneously worked as expected!

Doing some googling I found the posts below and tried heap_4 out which solved my problems. My guess is arduino has more C++ code than we realize, we may be fragmenting the heap when the destructors are called. If the heap is fragmented and we try and grab a large piece of memory, that could be what causes the malloc to fail and lock up the rtos. When I switched over to heap_4, my code started working as expected, it must be going and using the holes in memory or combining the adjacent blocks and removing the wasted space.

https://www.freertos.org/FreeRTOS_Support_Forum_Archive/May_2017/freertos_Heap_and_FreeRtos_new_c610c383j.html

https://www.freertos.org/FreeRTOS_Support_Forum_Archive/September_2016/freertos_New_object_not_created_properly_0df37042j.html

https://www.freertos.org/a00111.html

Thanks for confirming my suspicions. I will be pushing that change sometime soon :-)

cheetor5923 commented 5 years ago

Yes.. behind the scenes the Arduino codebase is somewhat of a horrid evil mix of C and C++, it is decidedly not 'tidy'. And naturally on an embedded system one has be very cautious with memory and dynamic allocation.. BTW, related to https://github.com/BriscoeTech/Arduino-FreeRTOS-SAMD21/issues/2 I'm already using the FreeRTOS 10 version of heap_4.

BriscoeTech commented 5 years ago

Hello @cheetor5923

With the help of the community the current release now has the ability to enable FreeRtos to manage all the malloc/free/realloc/calloc calls of the microcontroller, this might help deal with unresolved strange memory issues.

Did moving to heap_4 fix all your maloc problem? If not try v1.0.0 and enable the wrapping of the memory functions.

I am interested in hearing if this makes a difference in your application. Thanks!

cheetor5923 commented 4 years ago

Yes, the change has fixed up all the problems I was having. Now works as intended.