Electronic – Discussing FreeRTOS architecture for sort of a data logger application

embeddedfreertosrtos

I'm fairly new to RTOS architecture and been reading up on articles on FreeRTOS.org, but as it's commonly agreed, practice clears things up even more.

I have a basic project idea which I'd ideally want to be RTOS-based as I'll explain below along with some questions:

My understanding is RTOS comes in handy when you're computing multiple tasks concurrently. Based on that, I came up with the idea which involves a BLE-supported MCU, sensors, BLE-supported app, and some sort of a display component be it LCD, and how it works is a request is sent over BLE from an app, which is processed by the MCU, and does the following concurrently:

  • sending the data from the desired sensor back to the app over BLE
  • updating the display with the value on an LCD

In an RTOS context, I'd then have:

  • TaskA – constantly reads the requests coming over BLE from an app

  • Process the request in either TaskA or a different task (?), and obtain the desired data and put it in queueB.

  • TaskB – as soon as queueB is no longer empty, send the data out to the app over BLE

  • TaskC – as soon as queueB is no longer empty, update the display with the data

I think with this approach, there isn't any shared data that I need to worry about locking mechanisms…unless I'm missing something. Is the use of RTOS justified? If not, what else could be done?

A usecase:

I have a BLE-compatible phone (acting as a central) with an app that's connected to, say, the BLE of nRF52 (acting as a peripheral). After the connection, the user wants to retrieve some information from sensorA, so they send out "A", which is received by the peripheral device, processes it, and responds back to the central with the desired data which was requested, and at the same time, the LCD display is updated with the data as well

Best Answer

First off, good choice of using FreeRTOS, I've used several RTOS and FreeRTOS is by far the most stable and perhaps the best-written code of any embedded library I've seen so far.

Although the downside of an RTOS is that it will take you some processing from the MCU, and the task switch has a computing cost (delay). That is why it is better used on some fairly powerful MCUs.

Don't imagine that an RTOS will make your MCU faster, especially if you need to handle a graphic library and a display. It allows, however, to write much cleaner and modular code and handle systems of larger complexity.

Don't forget that despite you can have multiple tasks, only one can execute at a time, when a task switch occurs, the stack memory will be copied and this has a processing cost that is not negligible.

In your situation, you only have 3 things to achieve which are reading the sensor, updating the display, and sending the data over Bluetooth, which is not so many tasks, and is fairly simple, perhaps simpler to achieve without an RTOS. Using an RTOS may be overkill for that application and will introduce delays in your system. I personally wouldn't use an RTOS for that application.

However, if you wish to use an RTOS, your general vision is fine, the tricky part is about the task priorities and when to switch tasks, this mostly depends on your application.

We can guess that the display update probably can be the lowest priority.

Then it really depends on what the data are used for. If you are doing some sort of monitoring and you don't want to lose any data, you can set up the sensor read as the higher priority hand have a large queue. Depending on the sensor you use, if you can generate an interrupt from the sensor when you have data (like a Ready pin, or a timer) you can then use an interrupt outside the RTOS to write the data in a buffer or in DMA memory, then use a CRITICAL section in the RTOS to copy the data. You can also use double buffer implementation with a MUTEX and this sort of thing.

On the other hand, if you wish to have low latency to the app and don't care about sometimes losing data, you can set the BLE task as the highest priority.

Implementation is really dependant of what you want to achieve.

Edit Add: When to use an RTOS: Basically when you have an MCU handling several logic tasks of different nature, and you want non-blocking code.

Before Rtos, this was mostly done by state machine architecture. However, state machine architecture is difficult to maintain, and easily ends up in disaster, like the microchip harmony stack which is all state machine based, it becomes a huge mess as you start to have several libraries. Rtos allows a much cleaner way to handle that kind of needs, and allows to cleanly separate the code and is way more manageable, especially when you have a lot of code.

It is also much simpler to write non blocking code with an rtos than state machine or callbacks as you can just write blocking code and call the task switch function on the blocking parts of the code, which allows to have a readable flow.

Related Topic