Hi guys,

sorry for my super late reply.

Am 08.11.2015 um 01:15 schrieb Niklas Hauser:
Hi Alex,

This project looks great.

We also have an extensive concept for cooperative, stackless multitasking, 
based on Dunkels Protothreads [19], which we expanded on with Resumable 
Functions [20] which are used in all device drivers to make communication 
non-blocking and allow multiple device drivers on the same bus to safely access 

This form of multithreading is very resource friendly since it does not require 
context switches and only the main call stack (literally 2 bytes of RAM per 
However, this is quite an advanced topic and there are disadvantages to this 
approach compared to a full real-time operating system (power efficiency, hard 
real-time), such as mbed os or riot-os, however, they do not necessarily work 
well on AVRs.

Could you please expand on the disadvantages to power-efficiency or hard 
real-time ? And how bad are those ?

Some background first:

The protothreads are constantly being polled for state changes in their `run()` 
method regardless of that being useful or not.
This makes it very simple to implement timer logics, since they do not require 
to register callbacks, you simply wait until the timer expired:

        xpcc::PeriodicTimer timer(200); // expire every 200ms
        MyAmazingThread::run() {
                PT_BEGIN();     // protothread begins
                while(1) {
                        PT_WAIT_UNTIL(timer.execute()); // yield until true
                        Led::toggle();  // toggle an led every 200ms
                PT_END(); //

In your main loop you will have to call the `MyAmazingThread::run()` 
continously for this to work.
Notice that this equals to an _implicit_ round robin scheduling, ie. you don’t 
register with a dynamic scheduler class, but simply add your update function to 
the main loop.
Other than that the Protothread behave very similarly to other thread 
implementions, with the exception that you cannot have local variables, since 
they are based on a stackless coroutine implementation).

This is a very simple multitasking concept and it works very well for most 
I especially prefer the thread abstraction over using callbacks, as this can 
lead to some very unreadable code.

Regarding power-efficiency:

Since you have to poll the threads even when no state change occurred, the CPU 
is alway 100% utilized.
So this naive polling approach is obviously not very power efficient.

For our use this is not really a concern, since our robots consume around 
10-15W just doing nothing, so the extra 10mA from the CPU doesn’t really matter 

However, theoretically you could implement a sleep function here, by running 
though the main loop only when a state change in hardware occurred.
For example, the timers only need to be polled every 1ms, since that is the 
resolution of the clock.
So if all threads are waiting for a timer to expire, the CPU could to go sleep 
and wake up on the next ms tick.
Since the only thing that you seem to be waiting for which is not an interrupt is a time event you could implement a "time server" with a queue which you can push wakeup events to. Essentially the time server just sets the timer to go off at the nearest time point and then pops it from the queue. Then you can just wait for interrupt at idle and have all the power savings but can also potentially run at a finer granularity. I have had success with this even using multiple soft uarts (which require quite high timing precision).

Similar approaches could be taken for peripherals. You only have to poll the 
thread waiting on I2C/UART/SPI if a state change actually happened, etc.
I would like to investigate the possibilities of this in the distant future, as 
that sounds promising.

Another reason for not being power-efficient is that no DMA support is 
implemented yet.
Even though we have a DMA HAL for the STM32, the Controller and Stream 
selection for every peripheral still needs to be implemented.
This will likely happen before considering a sleep concept.

However, please note, that for true power efficiency, you need a full blown 
resource manager, that not only manages CPU sleep but also powers down unused 
peripherals (clock gating) and even external peripherals (ie. sensors, external 
Such advanced schemes can become very complicated very quickly (there is a ton 
of research done on doing this in clever way) and will probably never be part 
of xpcc.

Regarding hard real-time:

In my experience, you don’t need a hard real-time scheduler, when you can do 
your things directly in hardware (using a timer for a motor controller for 
example) or by enabling a high-priority interrupt handler and executing from 
If you do need actual hard real-time in your program, having a implicit 
cooperatively scheduled main loop is not the way to go, since you cannot make 
any guarantee on latency whatsoever.
So if you synchronize on a flag set during an interrupt, you will first have to 
wait for the main loop to loop around to the thread receiving (“reading”) the 
flag and acting on it.

However, the main loop gets called many thousands of times per second, so you 
will most likely be totally fine.
So the protothreads are definitely soft real-time (very fast though), but you 
can have the hard real-time if you want with interrupts.
I agree, "hard real-time operating systems" are a myth in my mind, If you need hard real-time you need both a high priority interrupt and a sophisticated method of atomics /critical sections in order to guarantee that you never turn off interrupts for too long. Disabling interrupts by escalating the interrupt priority rather than completely disabling them seemed to work on a proof of concept design for me in the past but the product was never developed for other reasons so I don't technically have field experience.


xpcc-dev mailing list

xpcc-dev mailing list

Reply via email to