-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unclear micro ros FreeRTOS Task stack consumption and consequences for stack monitoring in FreeRTOS #110
Comments
Usually, micro-ROS uses a considerable amount of stack. How much are you configuring? |
I configured 700 in CubeMX (that is 2800 Bytes). I did this based on the figures provided on the micro ros website and some other discussion here. |
Try to configure > 20 kB of stack for the micro-ROS task |
Well I can do, but where is the rational behind this? Why is there no possiblity to check how much stack is really needed? |
You can set a higher stack, and once you have the application properly running, you will be able to check the max stack consumption. Then you will be able to tune to the minimum required. |
How can I check the actual stack consumption? The function uxTaskGetStackHighWaterMark () is always returning the maximum of the available stack |
So, if it is returning the maximum value, your task is not using stack at all. |
No, this is not the intended behavior. What if you set more than 20kB, it is replicable? |
Hi Pablo,
I’m quite busy today. Allow me to postpone that question till next Monday.
Best Regards
Markus
Von: Pablo Garrido ***@***.***>
Gesendet: Freitag, 4. August 2023 07:38
An: micro-ROS/micro_ros_stm32cubemx_utils ***@***.***>
Cc: Krug, Markus ***@***.***>; Author ***@***.***>
Betreff: Re: [micro-ROS/micro_ros_stm32cubemx_utils] Unclear micro ros FreeRTOS Task stack consumption and consequences for stack monitoring in FreeRTOS (Issue #110)
No, this is not the intended behavior. What if you set more than 20kB, it is replicable?
—
Reply to this email directly, view it on GitHub<#110 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BAIMGVAWSQWZFRKTR5IKMVDXTSDBVANCNFSM6AAAAAA3BAZR64>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Hello, Preperation:
Result:
I'm even more surprised that this hasn't reported by other programmers so far. Did I fail somewhere and run into a pit hole that doesn't exist if I haven't overlooked something? |
Take a look at the profiling results in our testbench: https://github.com/micro-ROS/micro_ros_renesas_testbench/actions/runs/5781727309 Maybe a good idea is to check the stack consumption when the transport open function is called for the first time, this will provide a good overview of which is the real stack consumption of the actual micro-ROS stack without the transport. I'm not sure about which is your transport, but also, I'm not sure how much stack requires the USB or UART ST stack to work. |
Hi, Best Regards |
We, as maintainers of micro-ROS, can take a look at your issue and solve it if finally is a problem in the micro-ROS stack. In any case, we will need some details (your code, configuration, target hardware, etc) about your project to try to replicate this, because as far as we test, the stack consumption is inside the known limits. |
Are you setting the micro-ROS allocators? You can share your main file just here to take a first look |
This is the function that does all the micro ros init. The variable support is defined as global variable because it is use it in other files/tasks as well.
|
Maybe it is a good idea to test another allocator instead of the provided one. A wrapper on top of malloc, free, calloc and so on shall work. Regarding |
I commented out the provided freeRTOS_xxx allocators and got a more realistic behaviour of the task stack usage (that is now using the standard malloc/free - not even the FreeRTOS versions). I will do further checks on that. Still surprised that this hasn't been reported before. I'm aware of the non thread safety of the rcl API calls - which for me is a major topic for future enhancements of the micro ros libraray. I don't understand why the micro ros library provides a lot of RTOS examples but the underlying functionality is not thread safe. |
By default the micro-ROS API is not thread-safe. -> Calm, enable this flag that that's it...
Regarding the allocators: we made custom allocators for this package some time ago, due to the fact that freeRTOS do not provide a proper realloc (required by micro-ROS). As far as I understand, somehow these allocators are no longer working or at least not working properly on your platform (heap smashes over the stack?). In any case, is a good (and common) practice in micro-ROS to create custom allocators to handle properly the heap allocation required at micro-ROS initialization. You can find information about this here: https://docs.vulcanexus.org/en/latest/rst/tutorials/micro/memory_management/memory_management.html#allocators |
Hi, The provided allocators definiatly cause some trouble in stack violation/overrun. I replaced them by the FreeRTOS standard versions (+ calloc and realloc in a custom version) and the heap/stack tools start showing resonable values. I will do further tests and come back afterwards. Best Regards |
So, add to your micro-ROS build procedure the definition of |
Hi, My build procedure is exactly the same like described on https://github.com/micro-ROS/micro_ros_stm32cubemx_utils. I add the path to the Makefile and the toolchain.cmake but still get the error: Best Regards |
Share a volume to the docker builder here where your include paths for those required headers are accesible: And add them to be accessible via the CMake toolchain usin something like include_directories: |
I finally managed to create a new library with the profile UCLIENT_PROFILE_MULTITHREAD and set the symbol PLATFORM_NAME_FREERTOS. However, the resulting library is blocking rcl calls now. So even my first call to rclc_support_init() hangs till the timeout push it further. Certainly without success and therefore I cannot execute my application further. |
Where is your application blocking at RCL level? |
It blocks during the call rclc_support_init(). The call comes back after 4-5 seconds but didn't suceed. Therefore all the following API calls run into problems. |
Does it works with the non DMA transport? |
I tried with the interrupt version and also have no success. I removed the DMA setting, kept the interrupt and use the interrupt transport routines. Acutally the receive ISR is never hit. I guess the initialization is first sending a message to the agent and it will answer afterwards. So it seems the initial sending does not happen. But this is just guessing. |
Does the micro-ROS Agent receive anything? Use the |
Hi, |
One more things around the memory allocation problems: If the original (coming from heap4.c) malloc function is used the function call rclc_node_init_default() fails with 'bad allocation' as the return value. If I use the provided pvPortMallocMicroROS() it works. Actually I couldn't find an explaination for this. |
One question comes to my mind. Why are the rcl API using dynamic memory allocation/deallocation/reallocation anyway? At least for the initialization routines. Didn't they work only on pointers as input parameters ? So the memory for them can be allocated before calling the functions. |
We do not maintain RCL, it is a ROS 2 layer. We only maintain the micro-ROS build system, the RMW for XRCE-DDS and the actual middleware. The former two, dynamic memory free. |
Hi, |
To me it looks like there is an unfortunate override of the FreeRTOS task stack pointer in some layer. The overwriting does not seem to be accidental but mistakenly puts the stack pointer at the very end of the available area. The access coming afterwards then leads to the overflow. |
I tested today with 3 publisher and 2 subscriber. The publishers have a frequency of 100Hz, 20Hz. The subscribers are received with 1Hz. The uC I use is a Cortex M4F with 80MHz. So far everything fine. |
Was this also with multithread support? So were you able to build both multithreaded AND custom allocators? |
Hi, no multithread is not working for STM32 series and FreeRTOS. Something in the ROS2 layers seems to corrupt the memory. Because the publish function call is realized as blocking call I used a semaphore for protecting it (because I use the publish call in 3 different FreeRTOS tasks). |
Hi @DrMarkusKrug . Encountering the same issue with Tried wrapping the allocator on Thanks in advance |
Hi, I did the following:
And then simply wrote a wrapper to the standard C allocation functions: void myFree(void * pointer, void * state) void * myCalloc(size_t number_of_elements, size_t size_of_element, void * state) void * myRealloc(void * pointer, size_t size, void * state) This works because the necessary memory is taken from the heap outside the FreeRTOS heap (so you might need to adopt your linker script to separte the memory into different sections). In my case (STM32L4KC) there are two RAM sections anyway. One of them I'm using exclusively for the FreeRTOS heap. So here is the snippet for the linker script: and and somewhere in the file custom_memory_manager.c: I found some important hints how to start in this video: Finally I have to say I'm quite disappointed about the quality and performance of the entire ROS2+MicroROS code. I expected far more because all of these robot projects seems to use them and not much critics are reported. I guess the reason for this is: I only used MicroROS because one of my customer insist. Best Regards |
I like to understand the task stack consumption of micro ros, for the task that contains the node initialization commands (rclc_support_init(), rclc_node_init_default(), rclc_node_init_default()).
I observed that regardless how much stack I'm configuring for this task, the function call uxTaskGetStackHighWaterMark() is reporting zero bytes left after calling rclc_support_init(). This leads to the fact that the FreeRTOS stack monitoring mechanism is not working (because it requires a minimum of 16 bytes remaining on the stack).
Is this really the expeced behaviour of the micro ros stack allocation? If that is the case a programmer has to make sure that all variables that belong to this task are declared and allocated before calling rclc_support_init(). Additionally the FreeRTOS stack monitoring cannot be used in the entire application - which is really a critical point from my point of view.
Did I miss anything?
Best Regards Markus
The text was updated successfully, but these errors were encountered: