Bare Metal vs RTOS Architecture

hirohiro wrote on Saturday, July 20, 2019:

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 read_accel and update_display 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 :slight_smile:

aggarg-aws wrote on Saturday, July 20, 2019:

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.

rtel wrote on Saturday, July 20, 2019:

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/RTOS_Task_Notification_As_Counting_Semaphore.html

hirohiro wrote on Saturday, July 20, 2019:

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

hirohiro wrote on Sunday, July 21, 2019:

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

rtel wrote on Sunday, July 21, 2019:

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.

hirohiro wrote on Sunday, July 21, 2019:

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?

richarddamon wrote on Sunday, July 21, 2019:

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.

hirohiro wrote on Sunday, July 21, 2019:

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?

richarddamon wrote on Sunday, July 21, 2019:

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.

joconnor37 wrote on Sunday, July 21, 2019:

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/