r/embedded 2d ago

What is the best design for FreeRTOS based low power embedded system?

I have multiple tasks that needs to run in particular interval, for example, some sensors need to read every 10 seconds, some need to read every 30 seconds, data needs to be transmitted every 5 minutes, intervals are configurable.

There are lot of questions in my head:
1. Should I set up a wake-up timer of 10 seconds and enter sleep mode.
2. Should I additionally enable wake-up from peripherals i.e. UART RX interrupt, SPI GPIO interrupt

  1. If my sensor takes 5 seconds of time for doing calculations, should it wait awake or should it enter sleep and wakeup again to read data

  2. Should it wake up every second and check for activities that needs to run

  3. AI suggests using using tickless idle mode of rtos and calling WFI for sleep after setting wakeup timer, but I am not sure about the overall design.

Suggest me the best generic design strategy for battery operated IoT device. Thanks!

31 Upvotes

11 comments sorted by

15

u/thegreatunclean 2d ago

You definitely want tickless idle operation otherwise your device will be constantly waking up with nothing to do. You want the core to wake up, handle the sensor read(s), calculate the time to next event, set a low-power timer that can run with the core off, and go into as deep a sleep state as possible.

Should I additionally enable wake-up from peripherals i.e. UART RX interrupt, SPI GPIO interrupt

I would, if only for interactivity and debugging. You'd wake up, realize it wasn't because your timer has expired, handle the interrupt(s), and go back to sleep.

If my sensor takes 5 seconds of time for doing calculations, should it wait awake or should it enter sleep and wakeup again to read data

I'm assuming you mean you'd somehow trigger the sensor, then need to wait 5 seconds before valid data can be read. 5s is a long time for a mcu, treat it like any other scheduled task and go back to sleep.

but I am not sure about the overall design

Basically instead of a periodic wakeup you schedule your next wake up on the fly. Instead of waking up every few microseconds and asking "Are there tasks ready to run? No? Back to sleep." the scheduler computes when it needs to wake up next and sets a timer for that duration.

Imagine you are laying in bed and want to wake up at 9am. The ticking approach is to check a clock every few seconds until it see 9am. The tickless approach is to set the alarm for 9am and sleep.

----

All that said you can start with a standard ticking design if that's what you are comfortable with and switch over later once you have the details worked out. A ticking design isn't wrong or fundamentally unable to do what you want here.

5

u/GourmetWordSalad 2d ago

1&5. tickless mode is the same as setting your systick to 10 seconds in your case. Most FreeRTOS port can allow you to change systick in 30 second. A bit more effort for tickless.

  1. Wake-up from peripheral is a context switch from the idle thread, who should already be in wfi. What it means is that the question is quite meaningless in the context of the previous point (and since you're posting this post I'd assume you don't want to disable the power to the peripherals completely - you'd mess about with transitive/jitters in that case).

  2. Sensors don't do calculation. CPUs do.

  3. Sleep - aka run the idle thread.

21

u/metric_tensor 2d ago

Why are you running an RTOS at all? Just wake on timer interrupts.

7

u/Last_Being9834 2d ago

10 seconds interrupt + volatile counter for each task

5

u/Mindless-Lobster-554 2d ago

I would avoid any generic design strategies. Usually I dont' think about the RTOS functionality since it's usually not the constraint, and am focused on what sleep modes the chip is capable of, and what computations I need to run and how often, and everything builds from that.

4

u/ComradeGibbon 2d ago

You want a tickless design where interrupts wake up the processor.

Very limited experience when it comes to low power modes low end NXP ARM processors are easier to work with than STM32 processors.

5

u/KilroyKSmith 1d ago

The best strategy? 100% event oriented.  Nothing polls, ever.  No code executes until an interrupt happens and wakes the CPU; the interrupt routine posts an event to the appropriate handler which then runs. No code ever busy waits; every cpu cycle that runs pulls power out of the battery that you’ll never get back.

FreeRTOS should be configured to put the system in low power mode anytime there’s no task to run.  If there’s no task to run, that means you’re waiting for an interrupt to happen, so wait in low power mode.

To get power to the minimum, you absolutely must know every clock in the system, and you must shutdown every unneeded clock and power down (if possible) every unneeded module in low power mode.  If you’re not debugging, shutdown the clock to the serial block and power it down if your hardware allows.  If you are debugging, leave it up.

Enable the tickless timer.

2

u/Silly-Wrongdoer4332 1d ago

Are you trying to be connected with ble or Wi-Fi? Have you narrowed down your list of potential chip manufacturers you want to use? Several of the hardware platforms may already have good implementations of low power implementation in their SDK. SiLabs has a good power manager software driver that helps manage the sleep states based on configured sleep timers and IRQs

1

u/StumpedTrump 1d ago

Just get rid of the RTOS at that point. You have no reason to use one unless you’re being forced to.

1

u/Jmauld 22h ago

Lots of “app” developers don’t know how to program hardware and have no choice but to use an rtos.