Author Topic: FreeRTOS - where should the CPU be spending most of its time?  (Read 4502 times)

0 Members and 1 Guest are viewing this topic.

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
This seems about right, for co-operative multitasking i.e. a task yielding to RTOS when it has nothing to do



As I see it, the CPU has to spend time somewhere and that should be mostly in the RTOS.

The hang_around() function is a dumb wait used for LEDs at startup and it wastes a couple of seconds so features significantly over the sample interval.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline strawberry

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: lv
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #1 on: July 17, 2023, 04:30:09 pm »
not expert. could it be that it uses 60%CPU just to switch between two idle tasks(1000x/s collecting some garbage)?
is it possible to estimate exact CPU usage or what exactly going on in MCU?
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4173
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #2 on: July 17, 2023, 06:11:22 pm »
The cpu should be in a wfi
 

Offline rounin

  • Regular Contributor
  • *
  • Posts: 123
  • Country: us
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #3 on: July 17, 2023, 06:43:08 pm »
I call some sleep function from vApplicationIdleHook. Define configUSE_IDLE_HOOK to 1.

Eg WFI, HAL_PWR_EnterSLEEPMode, ...
 

Online jc101

  • Frequent Contributor
  • **
  • Posts: 681
  • Country: gb
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #4 on: July 17, 2023, 09:14:16 pm »
Weird as prvCheckTasksWaitingTermination is only ever called by Idle, so I'd lump those two together.  FreeRTOS will drop into Idle if nothing else needs to be done, plus associated housekeeping.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4463
  • Country: nz
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #5 on: July 17, 2023, 10:12:51 pm »
Weird as prvCheckTasksWaitingTermination is only ever called by Idle, so I'd lump those two together.  FreeRTOS will drop into Idle if nothing else needs to be done, plus associated housekeeping.

So that's over 88% of the time.

Note also that if a sampling profiler finds you at an WFI that counts as "all the time is being spent in that function".

If it can even make a sample without waking up the CPU. (Some cores/ISAs have a completely separate hardware debug unit)
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #6 on: July 18, 2023, 02:14:04 pm »
This time I have run it overnight



What is a WFI?

Quote
FreeRTOS will drop into Idle if nothing else needs to be done, plus associated housekeeping.

So the timings look about right. We are looking at 92% spent in the RTOS, so the CPU is spending just 10% of the time running this lot (RTOS tasks)



which is remarkable, if not surprising to me, having been working on this thing for 2-3 years and being constantly amazed at the speed.

SPI GPS processing
ETH http server updating a status page at 1Hz
Fast USB debugs
TLS session every 60 secs (crypto takes 3 secs)
etc

Maybe I could do some bitcoin mining?
« Last Edit: July 18, 2023, 02:16:24 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4278
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #7 on: July 18, 2023, 02:24:22 pm »
WFI = wait for interrupt

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #8 on: July 18, 2023, 03:23:44 pm »
Right - but surely every task which is

1 - stuck in a loop of its own e.g. for (;;) {}
2 - has called osDelay(100);

is waiting for an interrupt: the 1kHz Systick which drives the RTOS.

The 2nd case is much more efficient.

The 1st case is what happens in 3rd party code which just waits somewhere. In my project it is probably just MbedTLS which does that. It spends about 3 seconds doing crypto for the TLS setup. AIUI this involves a "bignum" library which is the last two RTOS tasks in that list above. However it is likely that nothing can be done about this, because the CPU is not waiting for something external.

But MbedTLS illustrates the difference between case 1 and case 2 above, because during those 3 secs the RTOS pretty well grinds to a halt. It still runs but much slower.

I don't think FreeRTOS has detection of "time wasting loops" which I think some have. It is perhaps done by dropping the priority of such tasks if the variation in program counter value (code address) is less than say 100 bytes.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 836
  • Country: es
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #9 on: July 19, 2023, 12:31:20 pm »
WFI is not some abstract task state, it’s a CPU instruction, so it will be a part of some specific function.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #10 on: July 19, 2023, 12:38:21 pm »
The only time I used WFI was during a CPU shutdown procedure, where - upon VCC loss detection - I want VCC to last as long as possible to protect a FLASH write. I shut down the ETH PHY (that does a lot), other stuff, then CPU shutdown, and then WFI in a loop because an interrupt can wake it all up again. I posted all the shutdown details in a thread here.

Does FreeRTOS use WFI? Not AFAIK. It would not do much anyway because other interrupts are running all the time anyway. I would expect the RTOS to be continually stepping through the task list.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3523
  • Country: it
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #11 on: July 19, 2023, 01:20:55 pm »
The only time I used WFI was during a CPU shutdown procedure, where - upon VCC loss detection - I want VCC to last as long as possible to protect a FLASH write. I shut down the ETH PHY (that does a lot), other stuff, then CPU shutdown, and then WFI in a loop because an interrupt can wake it all up again. I posted all the shutdown details in a thread here.

Does FreeRTOS use WFI? Not AFAIK. It would not do much anyway because other interrupts are running all the time anyway. I would expect the RTOS to be continually stepping through the task list.

You're missing the point. If most of the time the application looping through the idle task (and you're not doing anything in the idle task) you way just want to WFI (or enter a lower power state and WFI). Any interrupt will resume operation. The interrupt may be the task scheduler timer interrupt, or another interrupt that will/should/could wake another task
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #12 on: July 19, 2023, 02:17:09 pm »
I don't understand the benefit, except some very marginal benefit in power consumption, but there will be all kinds of potential issues e.g. with the ETH controller going to sleep, etc.

The key here may be that the CPU spends ~90% of its time in the RTOS, so while a 32F4 has only a slight potential for power saving (I found in my tests that by far the biggest savings come from ETH PHY shutdown) one may still get something useful.

Unfortunately I have never really dug properly into the sleep modes, in the context of an instant wakeup from one.

If there were no async interrupts, the RTOS could be modded to sleep when it has finished its processing (after each 1ms tick) but it would have to be something which has an immediate wakeup.
« Last Edit: July 19, 2023, 04:15:59 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 445
  • Country: be
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #13 on: July 19, 2023, 05:43:37 pm »
Does FreeRTOS use WFI? Not AFAIK.

You can see it for yourself. Examine Source/tasks.c and go straight to static portTASK_FUNCTION( prvIdleTask, pvParameters ) and especially
Code: [Select]
    #if ( configUSE_IDLE_HOOK == 1 )
        {
            extern void vApplicationIdleHook( void );

                /* Call the user defined function from within the idle task.  This
             * allows the application designer to add background functionality
             * without the overhead of a separate task.
             * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
             * CALL A FUNCTION THAT MIGHT BLOCK. */
            vApplicationIdleHook();
        }
    #endif /* configUSE_IDLE_HOOK */

Do you define these?

To see what is actually being executed, say arm-none-eabi-objdump -d port.o and search for prvIdleTask.
 
The following users thanked this post: peter-h

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #14 on: July 19, 2023, 07:18:03 pm »
I see these but they are not defined. The idle task is started by vTaskStartScheduler() does various cleanups. The way it is defined (portTASK_FUNCTION) I do not understand but it obviously works

Code: [Select]
/*
 * -----------------------------------------------------------
 * The Idle task.
 * ----------------------------------------------------------
 *
 * The portTASK_FUNCTION() macro is used to allow port/compiler specific
 * language extensions.  The equivalent prototype for this function is:
 *
 * void prvIdleTask( void *pvParameters );
 *
 */
static portTASK_FUNCTION( prvIdleTask, pvParameters )
{
/* Stop warnings. */
( void ) pvParameters;

/** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE
SCHEDULER IS STARTED. **/

/* In case a task that has a secure context deletes itself, in which case
the idle task is responsible for deleting the task's secure context, if
any. */
portTASK_CALLS_SECURE_FUNCTIONS();

for( ;; )
{
/* See if any tasks have deleted themselves - if so then the idle task
is responsible for freeing the deleted task's TCB and stack. */
prvCheckTasksWaitingTermination();

#if ( configUSE_PREEMPTION == 0 )
{
/* If we are not using preemption we keep forcing a task switch to
see if any other task has become available.  If we are using
preemption we don't need to do this as any task becoming available
will automatically get the processor anyway. */
taskYIELD();
}
#endif /* configUSE_PREEMPTION */

#if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) )
{
/* When using preemption tasks of equal priority will be
timesliced.  If a task that is sharing the idle priority is ready
to run then the idle task should yield before the end of the
timeslice.

A critical region is not required here as we are just reading from
the list, and an occasional incorrect value will not matter.  If
the ready list at the idle priority contains more than one task
then a task other than the idle task is ready to execute. */
if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 )
{
taskYIELD();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */

#if ( configUSE_IDLE_HOOK == 1 )
{
extern void vApplicationIdleHook( void );

/* Call the user defined function from within the idle task.  This
allows the application designer to add background functionality
without the overhead of a separate task.
NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES,
CALL A FUNCTION THAT MIGHT BLOCK. */
vApplicationIdleHook();
}
#endif /* configUSE_IDLE_HOOK */

/* This conditional compilation should use inequality to 0, not equality
to 1.  This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
user defined low power mode implementations require
configUSE_TICKLESS_IDLE to be set to a value other than 1. */
#if ( configUSE_TICKLESS_IDLE != 0 )
{
TickType_t xExpectedIdleTime;

/* It is not desirable to suspend then resume the scheduler on
each iteration of the idle task.  Therefore, a preliminary
test of the expected idle time is performed without the
scheduler suspended.  The result here is not necessarily
valid. */
xExpectedIdleTime = prvGetExpectedIdleTime();

if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{
vTaskSuspendAll();
{
/* Now the scheduler is suspended, the expected idle
time can be sampled again, and this time its value can
be used. */
configASSERT( xNextTaskUnblockTime >= xTickCount );
xExpectedIdleTime = prvGetExpectedIdleTime();

/* Define the following macro to set xExpectedIdleTime to 0
if the application does not want
portSUPPRESS_TICKS_AND_SLEEP() to be called. */
configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime );

if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP )
{
traceLOW_POWER_IDLE_BEGIN();
portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
traceLOW_POWER_IDLE_END();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
( void ) xTaskResumeAll();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* configUSE_TICKLESS_IDLE */
}
}

portSUPPRESS_TICKS_AND_SLEEP doesn't appear to be defined. Presumably this would be totally system specific, based on what can be put to sleep for a few hundred microseconds.

Interesting... what could one do with a 32F417? I had a dig around and found it mentioned here
https://www.st.com/resource/en/user_manual/um1722-developing-applications-on-stm32cube-with-rtos-stmicroelectronics.pdf
but only in the tickless RTOS mode, which I am not using.

The use of sleep mode(s) seems incredibly complex once peripherals, including external ones, and stuff like SPI, are to be accounted for.
« Last Edit: July 19, 2023, 08:34:56 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4463
  • Country: nz
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #15 on: July 19, 2023, 10:04:53 pm »
I don't understand the benefit, except some very marginal benefit in power consumption

In many applications of RTOS the energy savings of using WFI and/or sleep modes can be 90% to 99.9%.

Yes, even if it has to wake up to do something every ms. There are a hell of a lot of ns in a ms.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #16 on: July 20, 2023, 01:48:26 am »
How are the peripheral issues handled?

I would be really interested in some real-world examples.

Obviously if all you are doing is on-chip and GPIO just reads switches and flashes LEDs etc, putting the CPU to sleep is trivial. And for many things you don't need async interrupts, so the next interrupt will always be the RTOS tick, and that can be 100Hz, not the usual 1kHz.

But if say you are running USB CDC/MSC then you will be screwing up the USB Host with random response times. The ST implementation of USB is (after init) interrupt driven, so maybe that works. ETH? No chance AFAICS. Talking to things like SPI FLASH?
« Last Edit: July 20, 2023, 08:01:48 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3884
  • Country: us
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #17 on: July 20, 2023, 08:18:46 am »
You can pretty much always do WFI while idle, but whether you can put peripherals in a lower power mode depends greatly on what those peripherals are and whether they have a low power mode that still can detect activity and wake up.  There isn't really a way around just reading the manual for the device to see what it can do   For instance with slow interfaces you might be able to shut down the peripherals but use a pin change interrupt to wake when a transmission starts.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #18 on: July 20, 2023, 08:44:34 am »
Yeah... I can see one spending months chasing around really weird and very hard to track down problems with peripheral behaviour.

I guess one would start by making the WFI conditional on some stuff not being active e.g. you will probably already have a mutex on r/w to an SPI FLASH, and you will want to not do WFI if that mutex is locked. In fact you will probably have a mutex on an SPI channel as a whole.

Maybe use DMA for serial and SPI? That avoids the crap 1-char buffering provided by ST. But that means not shutting down peripherals.

And lots and lots of other stuff like that.

Curiously I have found almost no examples of this online.

Looks like only the Sleep mode could be used



Next, the DS suggests Run mode to Sleep mode drops Icc from 102mA to 77mA, only! With all peripherals disabled it drops from 54mA to 27mA. This is at 168MHz, 32F417.

Then there are all kinds of other tables showing Icc under lots of conditions, but if one sticks to a mode where the Systick will wake you up, and the HSO (say 25MHz) remained running, I don't see much point in doing this unless your power situation is already critical, in return for the considerable increase in development time and testing required.

Maybe other CPUs are much better - the "L" chips?

The worst may be compatibility testing e.g. USB. Currently I am implementing the primitive USB client mode which is reportedly used by FLASH sticks i.e. Host activity triggers an ISR which does everything including a 15ms FLASH write, and hangs up the target for the 15ms. With a 1ms RTOS tick it all still runs but 15x slower; what a surprise ;) This is primitive but is 100% compatible across Host USB implementations. Other approaches, sending back a BUSY packet immediately upon starting the FLASH write and hoping the Host will retry, etc, have been tried but are complex, practically nobody knows how to do them (apart from the one guy on ST forum who never actually tells you how), the ST-provided code hooks for BUSY/NAK do not actually work, and the final code cannot possibly be tested across the Host spectrum.

ETH, I don't even want to think about. You probably want to just shut it down totally (for a good Icc gain) until somebody starts the HTTP server :) But then you won't know they started it, will you? ;) And you still need to have a PSU big enough to run that mode...

What am I missing?
« Last Edit: July 20, 2023, 08:48:22 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline lucazader

  • Regular Contributor
  • *
  • Posts: 221
  • Country: au
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #19 on: July 20, 2023, 09:24:06 am »
In an application running F7 and F4 MCUs at work in freeRTOS simply adding __WFI() in the idlehook dropped our system consumption from ~110mA to ~50mA (lots of other things sitll running on the board including a seperate RF comms module etc that aren't sleeping). Huge win for any battery operated device.

This device acts as a USB host as well as communication over uart to the RF processor etc.
The addition of WFI() was simple, and caused no issues for us with nay of the peripherals.

Was a big enough win for us to hit our device battery life targets and enabled us to move onto other more challenging issues in the project.
« Last Edit: July 20, 2023, 09:26:43 am by lucazader »
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3884
  • Country: us
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #20 on: July 20, 2023, 09:49:41 am »
I guess one would start by making the WFI conditional on some stuff not being active e.g. you will probably already have a mutex on r/w to an SPI FLASH, and you will want to not do WFI if that mutex is locked. In fact you will probably have a mutex on an SPI channel as a whole.

It shouldn't be that complicated, you shouldn't need to mess with a mutex or anything, at least for basic sleep mode that just shuts off the CPU.  Think of it from the perspective of the scheduler:  If there are no runnable tasks, then your CPU has nothing to do except wait until a task becomes runnable. Generally that will only happen when an interrupt occurs (either IO or a timer} so the scheduler will call an idle task that executes WFI.  After WFI completes, it will return to the scheduler to see if any tasks have been marked runnable from an ISR.  If so they are executed until they all are blocked then the idle task runs again.

This of course only works if your IO is all interrupt driven or polled slow enough that it makes sense to use a timer.  Its ok to have occasional busy waiting: that will be done from a runnable task and have priority over the idle task.  But if you need to be constantly polling for work at a high rate then it doesn't make sense.

DMA can help reduce how often you wake up but isn't needed.  All you need is interrupt driven IO.
 

Online Tation

  • Regular Contributor
  • *
  • Posts: 81
  • Country: pt
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #21 on: July 20, 2023, 09:55:11 am »
I would expect the RTOS to be continually stepping through the task list.

This is pointless if it is known that there are no tasks able to run. And there will not be runable tasks if all tasks are idling/waiting AND no interrupt arrives.

The RTOS should do a WFI when it detects that all tasks are idling/waiting: the processor sleeps, peripherals not (provided that you have not configured any deep sleep configuration that also stops peripherals). Any interrupt will wake the processor, perform the required ISR and then execute the task scheduler. If your ISR has fired any RTOS signal, the related tasks will be invoked by the scheduler, if not, the core will sleep again (thus, direct peripheral management in the ISR will also work). Awakening from this sleep mode usually takes just a handful of clock cycles.

If your code is 90 % of the time in the RTOS, expect a reduction in power consumption (of the core, not of the whole chip) of near 90 % when allowing the RTOS to sleep.

No need for mutexes or any other mechanism to manage this, it is a well known, out-of-the-box, technique. So put that WFI in the place expected by the RTOS and forget.

Regards.

« Last Edit: July 20, 2023, 09:58:18 am by Tation »
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3822
  • Country: nl
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #22 on: July 20, 2023, 11:29:45 am »
I'm not particularly up to date with FreeRTOS internals, but in general it depends on your application.
If your application is mostly ISR, event and timer based, then it's likely most of the time is spent in your RTOS "sleep()" or "idle()" function.
If your application is doing a lot of (ugly) I/O polling from various tasks, then you can set up your RTOS to divide the time over the most critical polling parts.

But overall, the best advise is to learn how the internals of your RTOS work, and then figure out of where it spends it's time makes sense or not.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 4087
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #23 on: July 20, 2023, 02:42:48 pm »
Interesting!

No ETH cable:
With WFI, 3.3V rail 119mA
Without WFI, 147mA

With ETH running:
With WFI, 3.3V rail 165mA
Without WFI, 193mA

28mA saving. Note there is a lot of stuff running off that 3.3V rail; not just the CPU.

And so far all seems to work. More testing tonight.

Is there anything worth checking specifically?

This is all I did:

Code: [Select]


// This gets called when RTOS idle task has nothing to do

void vApplicationIdleHook (void)
{
#define __WFI() __asm volatile ("wfi")
__WFI();
}



Interesting that my post above I refer to a 25mA saving in the DS, so I am getting very slightly more but basically that.

And instead of sitting mostly in "task waiting" it now shows "unknown function"





If the above is the whole story, that is excellent. Digging around online to see what others have done, I see all kinds of other stuff like disable_irq() before WFI but it's not clear what this is for. You would need enough buffering on UARTs to handle the worst case there, etc.

Quote
adding __WFI() in the idlehook dropped our system consumption from ~110mA to ~50mA

Unless your CPU is very different from mine, you must have been doing more than just the WFI which just sleeps the CPU. Even the DS says you won't get more than about 25mA.

I can see one could use a GPIO to drive a MOSFET around the WFI to turn off external stuff but I can't see obvious candidates where a 0-1ms turnoff would be beneficial. Maybe someone can think of something? It was Clive Sinclair who did something like that... LEDs would be obvious but then they will be dimmer so you have to drive the current up :)

« Last Edit: July 20, 2023, 04:05:01 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8755
  • Country: fi
Re: FreeRTOS - where should the CPU be spending most of its time?
« Reply #24 on: July 20, 2023, 04:26:58 pm »
It would be weird to disable interrupts and then instruct the CPU to Wait For Interrupt. But people suggest the weirdest things.

Indeed, if you replace while(1) or while(flag_written_in_isr) with WFI, there is no need for anything special like mutexes, it should be just this simple.

For a robust design though, don't make the assumption of having no other spurious wakeups for unexpected reasons. In other words, don't assume that since CPU got past WFI/WFE, a certain interrupt or event did indeed happen; always check for flags (peripheral registers or variables written by your ISR) and if nothing happened, go back to sleep (WFI/WFE).
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf