micro-ROS / micro_ros_setup

Support macros for building micro-ROS-based firmware.
Apache License 2.0
336 stars 128 forks source link

Multithread support in freeRTOS #669

Closed N-K1998 closed 8 months ago

N-K1998 commented 8 months ago

Issue template

I am building an application with different tasks running in FreeRTOS. An application with one publisher in one task and the subscribers in the main one. My question is what the multithread support do? Does it simply add the feature of making the library thread-safe? In the context of a custom transport, is it possible to have different threads running the code of the transport layer? If you can provide some documentation about this feature it could be very useful.

Thank you

pablogs9 commented 8 months ago

It simply makes the micro-ROS middleware thread-safe, be careful because that does not mean that all RCL / RCLC APIs are thread-safe. Check the documentation for each one on the corresponding API doc.

Here you have documentation: https://docs.vulcanexus.org/en/latest/rst/microros_documentation/user_api/user_api_multithreading.html

N-K1998 commented 8 months ago

Ok, thank you. Do the executors block the freeRTOS scheduler even in the multithreaded version of microros?

pablogs9 commented 8 months ago

Not sure what means "block the FreeRTOS scheduler". The executor spin is a function call that will no yield / sleep to the scheduler. So if the task with the higher priority calls spin() forever it won't let other tasks run.

N-K1998 commented 8 months ago

I was referring to one of your answers in the previous issues: "Avoid using rclc_executor_spin in embedded systems, it can freeze your scheduler.

Use this approach:

while(1){ delay execution for letting other tasks to run spin some the rclc executor }"

So it can freeze the scheduler if it is executed in the higher priority task.

pablogs9 commented 8 months ago

rclc_executor_spin will not return if everything goes normal. That means that if you run rclc_executor_spin in the highest priority task, other tasks won't be executed.

Maybe "freeze" is not the most proper way of saying that the scheduler will prioritize the highest priority task's workload.

So, the approach shall be:

while(1){
  delay execution for letting other tasks to run
  spin some the rclc executor
}
N-K1998 commented 8 months ago

Ok perfect, last question. Supposing to have a custom transport, the custom functions will only be called in the thread/task where the rmw_uros_set_custom_transport has been called right? I mean, there are no task/thread creations for each task using rcl_publish or using executors.

pablogs9 commented 8 months ago

Internally the micro-ROS stack does not create any thread/task in any case.

rmw_uros_set_custom_transport just sets the required callbacks for the transport operation.

The transport callbacks will be called when required:

But, those transport API are protected from multithread operation with the micro-ROS Thread Safe mode.

N-K1998 commented 8 months ago

Where can I find a transport implementation that works with multithreading? Just to understand how it should be implemented.

pablogs9 commented 8 months ago

all transport implementations are thread-safe if the library is configured as thread safe. The library uses the transport API in a thread safe way.

N-K1998 commented 8 months ago

I understand, thank you.