Bare Metal vs RTOS Architecture

I’m fairly new to FreeRTOS and I’m hoping some more experienced users can offer some advice on how it is best to architect my application Summary of application: – monitor accelerometer (I2C) at 1.5kHz and run a basic algorithm to detect if a threshold is crossed for a certain window – monitor user input via push buttons – keep LCD display updated with feedback – log accelerometer data over serial to PC What I would do in a non-RTOS environment is use a HW timer that will fire an interrupt at 1.5kHz for the accel, and maybe another at 10Hz to refresh the display. Both of these timers would set a flag indicating readaccel and updatedisplay while the buttons’s GPIO IRQ would set a button flag. Finally a main loop would trigger non-blocking I2C reads to the accel and non-blocking reads from the display on these flags, and the serial would just run during any free cycles. I’d like to implement this in FreeRTOS since down the line we will likely be adding a BLE radio to the mix which will should run in it’s own task and not break the rest of the code. Can someone suggest a task structure that would make sense for this application? I don’t want my current path to influence the suggestions but if that question is too broad then here’s what I’m struggling with more specifically:
  1. Should I use one task to handle high frequency I2C read, and one task with software timers for low frequency UI interactions?
  2. Where do I handle pushing data out that fast over UART?
  3. Can I get away with a blocking I2C driver with the RTOS?
  4. For the UI task should I create 2 software timers for updating display and polling buttons or just use one and use it to increment a counter which would trigger the two? How would I wait on either timer if I’m using two?
Any suggestions would be much appreciated. Maybe I’m over thinking things but I would like to design it right from the start 🙂

Bare Metal vs RTOS Architecture

One way of designing this application can be:
  • One task for monitoring accelerometer – You can configure this task to wake up at periodic intervals (using vTaskDelay) according to how frequently you want to monitor accelerometer.
  • One task for monitoring input via push buttons – Configure this task to wait for a task notification which is delivered from GPIO IRQ (using xTaskNotifyWait and xTaskNotifyFromISR).
  • One task for updating LCD display – This task is unblocked whenever the display needs to be updated. You can use task notification or semaphore for signaling this task from some other task (depending on when the display needs to be updated).
  • One logging task – Have a queue to which accelerometer task writes the data and this task reads the data from that queue (xQueueSend and xQueueReceive) and sends over serial.
Thanks.

Bare Metal vs RTOS Architecture

I will kick things off by suggestion that, because of its speed, I would stick with using a hardware timer to trigger the 1.5 KHz read of the accelerometer – that will ensure the accuracy of the read period. If possible do the whole I2C transaction in interrupts (hopefully offloaded to some kind of DMA control where the source of the data is the I2C peripheral if your hardware supports it – Atmel used to do a really nice job of that kind of DMA). Once the I2C transaction is complete you can just trigger a task (similar to your flag) to process the results however you want – you can see some code snippets here for how that can be done: https://www.freertos.org/RTOSTaskNotificationAsCounting_Semaphore.html

Bare Metal vs RTOS Architecture

Thanks for the suggestion. It seems like the number of tasks will balloon quickly if I separate things like monitoring button presses into their own task. Is there a reason to not combine that with LCD? I think the overhead of tasks can get expensive

Bare Metal vs RTOS Architecture

Hmm that’s interesting. I didn’t know about these task notifications yet, thanks!

Bare Metal vs RTOS Architecture

Is there a reason to not combine that with LCD? I think the overhead of tasks can get expensive
Very dependent on your application – if the button an LCD are always coupled and nothing else uses the LED, etc. then it can make sense to have them in the same task for sure.

Bare Metal vs RTOS Architecture

This is where I get a little lost. In reality I have 3 LEDs, an LCD, and 2 buttons. The buttons can be used primarily to interact with the display menu’s but also can be used to trigger things like switching modes (via holds) completely outside of the LCD menu. The LEDs are used to communicate various states depending on the operating mode. I was thinking to group these all under a non-critical task since some latency is acceptable. However, the button and LCD are not always coupled since a long press for example would just push an event upstream to a different module and not affect the display. Does it still make sense then?

Bare Metal vs RTOS Architecture

My general guideline is that I make one task for each external event/device that send request/information to the processor ‘unbidden’. This means that if there is a device that I send a message to and it then returns a reply, I don’t need a new task for that. I would likely make the log output a seperate task so it sending data doesn’t interfere with the collection of data from the accelerometer. Your 1.5kHz accelerometer reading is perhaps one of the tougher tasks. That is fast enough I would prefer NOT to make that based on the tick timer. One thing to look at is if you can setup the accelerameter to automatically sample at that rate and give you an interrupt to read the data. Also at that rate the communication to the accelerometer is likely going to use up a lot of your I2C band width, as 1.5 kHz is only 666us per sample, and even at 400kHz I2C rate that is only 266 BITS of information (29 bytes) (and the I2C Start/Stop signal take time, as well as sendingthe needed address info). For the UI, I would use a single task to poll the buttons and periodically update the display.assuming you can set them to be on an integer ratio. If there are multiple source that can kick off a display update (not just on a time basis) then you might want a seperate task for display update.

Bare Metal vs RTOS Architecture

That makes sense, thanks! I will definitely try to do some optimization of the accel by making use of the on board fifo, but I was also mostly curious how that sort of task would be handled. In the case that it did need to be polled at such a high rate, how would that be handled? Would the task need to tight poll a status flag that is set by a hardware timer?

Bare Metal vs RTOS Architecture

Tasks should never be polling a signal, except maybe at a very low rate like your UI checking the state of the buttons (with a block on a timer in between). You want an interrupt to trigger things off. That interupt can be the timer tick for lower rate periodic things, or a special hardware timer for some faster things, or a device interrupt signal. Inside that ISR, you might be able to directly kick off the action, or it might send a notification or data to a task.

Bare Metal vs RTOS Architecture

A thought: If the 1.5kHz sampling rate of the accelerometer is chosen paying homage to the Nyquist Sampling Theorem, then I would use hardware timing to give a “most” accurate 1.5kHz sampling frequency……….
From: hirohiro hirohiro@users.sourceforge.net Sent: Sunday, July 21, 2019 01:59 To: [freertos:discussion] 382005@discussion.freertos.p.re.sourceforge.net Subject: [freertos:discussion] Re: Bare Metal vs RTOS Architecture That makes sense, thanks! I will definitely try to do some optimization of the accel by making use of the on board fifo, but I was also mostly curious how that sort of task would be handled. In the case that it did need to be polled at such a high rate, how would that be handled? Would the task need to tight poll a status flag that is set by a hardware timer?
Bare Metal vs RTOS Architecturehttps://sourceforge.net/p/freertos/discussion/382005/thread/82e1bebc02/?limit=25#bea4/3565
Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/ To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/