Go Down

Topic: DuinOS: small and simple rtos (Read 92946 times) previous topic - next topic


I just saw that as things are, pins 9 and 10 will not be available for PWM? I know of at least one shield, the Adafruit Motor/Stepper/Servo shield that uses PWM on 9 and 10 for the servos. I have this shield, but I can get around it.

I'm coming to hate shields. They should at least offer breakout pins so that you can use them and have some control of what pins the thing grabs. The WiFi shield from AsyncLabs does this.


I appreciate this project grately!
Where can I read the sourc-code of DuinOS?

(and how come you named it DuinOS rather than ArduinOS?)


Hi, the project is deployed in source form, so you can find the sources in the hardware\cores\arduino.DuinOS.

You can donwnload it from http://www.multiplo.org/duinos/wiki



I understand that because DuinOS uses Timer1 that PWM on pins 9 and 10 are not available.  On the Duemilanove 328 Timer1 uses OutputCompare1A (OC1A) and (OC1B) which are on AVR pins 15 and 16 which map to Arduino pins 9 and 10.

On the Arduino Mega (1280) Timer 1 uses OC1A, OC1B, and OC1C on AVR pins 24,25, and 26, which map to Arduino pins 11, 12, and 13.  I'm new to the Arduino, but am I correct that for the Mega PWM is available on pins 9 and 10, but not on 11,12, 13?


Jan 14, 2010, 03:34 am Last Edit: Jan 14, 2010, 03:36 am by Dennis_Meade Reason: 1
Not that I figured this out from ATMega1280 reference , but on the  Arduino Mega "PWM is on 0 to 13 and provides 8-bit PWM output with the analogWrite() function." ( paraphrased from the Hardware page )


Jan 14, 2010, 07:35 pm Last Edit: Jan 14, 2010, 07:57 pm by seven Reason: 1
Hello DuinOS users.  Warning, Lurker approaching :)


Jan 14, 2010, 07:36 pm Last Edit: Jan 14, 2010, 08:01 pm by seven Reason: 1
Stepping out of the lurkers corner.  
I've been working with DuinOS since Julian first put it out here.  I've had successes :) and I've come across some real aggravations >:(  First, some comments:

  • My research has shown that freeRTOS is a good choice for the Arduino hardware..  There are other OS that I'll likely review (TinyOS for one, possibly femtoOS if he relaxes the licensing), however freeRTOS is the best supported.
  • I commend Julian for his efforts.  This is a great start for a freeRTOS branch on Arduino
  • I'm very skeptical about preserving the Arduino IDE.  Most people who get to the point they are considering an RTOS are fairly deep into programming.  The Arduino IDE is very fragile when it comes to serious programming.  My areas of concern are, and not limited to: a) Arduino IDE libraries mixes C++ code with C code without notifying the compiler (more on this later) b) Arduino IDE libraries as well as libcavr are not thread safe. c) Not exposing the task loop.  This limits the programmers abiltiy to add trace macro instrumentation.
  • How deep does the Arduino/freeRTOS fragility go?  I applaud our current efforts but feel we may be just seeing the tip of the iceberg.  Perhaps a methodical approach that implements freeRTOS and migrates/test the Arduino libraries?

As a programmer, I spend quite a bit of time understanding and implementing programming tools that I refer to as instrumentation.  For the seasoned programmer, the printf() function is perhaps the number one function used for situations that are not time sensitive [most implementations of printf require a series of nested calls eating cpu cycles and stack space]. For real time programming we need more.   FreeRTOS provides a trace macro instrumentation facility which has no impact if not used and very low impact if implemented with some thought.
printf comments
It is possible to get a printf() function working in Arduino (example here) and it is even possible to make it thread safe (example here. However it does requires a reasonably deep understanding to implement and is very susceptible to poor behavior if used improperly (in DuinOS, we can eat up stack space and cause a fault, or eat up cpu cycles and cause a fault, both of which are very hard to debug).
trace macro comments
freeRTOS offers a facility to make use of predefined macro names where the developer can define the macro (usually in FreeRTOSConfig.h) and the compiler will compile in the defined code at strategic places in the FreeRTOS scheduler.  This is extremely useful when trying to identify why something has died.  The freeRTOS.org site provides a great example here.  That's the good news.  The bad news is that C++ and C do not mix well in the context of this feature.  This is where it is very important to notify the compiler when it should be compiling C++ and when it should be compiling C.  (Arduino and DuinOS do not do this well) freeRTOS makes use of something called a TaskTag.  In the task.h and task.c files, this type is cast as a function pointer and can be overloaded as just about any kind of value the implementor would like to use by making use of the C cast (void *).  This, however, is not acceptable to the C++ compiler and generates a cast error that cannot be violated in C++ even with a complex cast prefix.
Did I mention that there is fragility here  ;)  I've been moving ahead with DuinOS and fixing what seems to be broke however, it does not seem to be the most efficient way to getting a viable RTOS running on the Arduino board using Arduino libraries.
Sorry if this was 'long on the tooth' .  I thought the group might benefit from my experiences.



Hi Paula

Very informative set of comments. You might want to look at an article I came across Integrating Microchip Libraries with a Real-Time Operating System
. Among other things, the article suggests creating a task to buffer printf().

The WinAVR libc User Manual part of the WinAVR distribution (http://download.savannah.gnu.org/releases-noredirect/avr-libc/) talks about re-entrant code and documents the functions (printf()) that are definitely not re-entrant.

As far as the task loop is concerned, I don't see why it's necessary in DuinOS. Basically you create tasks and start the scheduler. The tasks get the for (;;) if they need it.


I've written what I think is a very simple program that runs two tasks. When I compile it, I get the following error message:

error: expected constructor, destructor, or type conversion before '(' token

taskLoop(loopOne) is high-lighted.

Code: [Select]

#define TASK_DELAY 1000

 Serial.println( "taskLoop(loopOne)" );
 vTaskDelay( TASK_DELAY );

 for (;;) {
   Serial.println( "In Task One" );
   vTaskDelay( TASK_DELAY );


 Serial.println( "taskLoop(loopTwo)" );
 vTaskDelay( TASK_DELAY );

 for (;;) {
   Serial.println( "In Task Two" );
   vTaskDelay( TASK_DELAY );


// The setup() method runs once, when the sketch starts

void setup()  

 Serial.begin( 9600 );
 Serial.println( "setup()" );
 createTaskLoop(loopOne, LOW_PRIORITY);
 createTaskLoop(loopTwo, NORMAL_PRIORITY);


I tried to setting preproc.save_build_files=true thinking I would be able to see what the compiler was dealing with. No luck.

Any ideas? I realize the Serial.println() may not work as one might expect.


Julian,  take a look at the trace macro facility in freeRTOS.  Very powerful for those trying to debug real time code.  It requires that you reinitialize a freeRTOS task tag prior to entering the task loop but within the task function.  If the task loop is not exposed, well, you can 't do it!..  There may be other 'pre' task loop initialization features in freeRTOS as well.  I'll update when I have the trace macro facility running.  Seems to be an extern 'C' problem somewhere, maybe in FreeRTOS.h..

The problem with using a task for printf is you get into deeper reliance on the OS working.  Granted, not  everyone uses printf for debugging, but in these environments I suspect that is where it will get the most use.  If one depends on the OS to cue up printf  values and pipe them out to the serial port and something hangs the OS, well your debugging info has just got caught in the OS death spiral.  Better to go the other way and let printf run autonomous, maybe rewrite libcavr to allow for critical code segment protection, that way, the last bits of info that made it into printf may show up on your screen.




Jan 15, 2010, 02:26 am Last Edit: Jan 15, 2010, 04:03 am by juliandasilva Reason: 1
Hi, I have some comments:

1. Thanks Paula! I think the community is growing, and all these contributions are very welcome!

2. Stonechild: I compiled your code. The error "error: expected constructor, destructor, or type conversion before '(' token..." is because you did not selected a DuinOS target in the Tools->Boards. For example, if I select "Arduino Duemilanove or Nano w/ ATmega328" I obtain the same error. That's because there are no DuinOS kernel libraries compiled, so, the macros simply do not exists for the compiler.

But, If you select, for example "Arduino Duemilanove or Nano w/ ATmega328 + DuinOS", you get another error: "
o: In function `main_Task(void*)':
C:\Projects\XDF\Components\SNAPI\_Dev\_Experiments\arduino-0017\.\_build/sketch_jan14a.cpp:51: undefined reference to `loop'".  

So, it will necessary to add the loop() function, and the code starts to compile (I did not test it in run time, just compiled it).

3. About the code itself: You are using taskLoops, so the for(;; )s are not necessary inside the tasks. If you want to use infinite loops inside a task, you must use xTaskCreate().

4. It has been decided: Due to the confusion about the taskLoops, we will deprecate them for the next version. They will be simply "tasks", so the user will need to add it's own infinite loop inside them. This will have, I hope. 2 advantages:

- Will be more similar to the original FreeRTOS syntax, so, less confusing.
- Will add more control over the task initialization (and possible a little more eficiency).

5. Regarding the "void loop()" function, and the main task, I think it will continue. We decided to implement DuinOS that way due to:

- First, with that structure (the loop as a task), any Arduino example compiles. I may not work if using something like delayMicroseconds, or pwm on pin 9, but the simpler examples, and a lot of the standard examples does work, just selecting the "DuinOS targets in your boards menues.

- Second, it does not take away too much control over the application, and it simplifies the initialization process for the Arduino user (no calls to vTaskStartScheduler, and no confusions with the fact that THERE IS NO MAIN LOOP, EXCEPT FOR THE MAIN TASK, because the for(;; ) in the main task is never reached, except if someone calls the vTaskEndScheduler() function, which is not so common).

- Third: The advanced user, will probably simply use the FreeRTOS kernel, even without the Wiring/Arduino API. So, there is space for everyone, with any level of knowlege. The DuinOS utility for these users is that it has the FreeRTOS kernel working on the some very used megas (168, 328, 644, 1280 and 1284).

Last, I agree with Paula that there are many things that can cause problems with an RTOS on such minimalist hardware (specially taking in account the small RAM), so well, there is one of the biggests challenges.

I hope that it will envolve in something more robust and easy, we are working, but yes, a bit slow. Sorry for this.

Well, regards, and thanks to all contributing and interested in DuinOS!


Hi Paula, I was wrinting my previous post before see your last one about the trace macro. I will take a look, many thanks again!


Hi Julian,

If you play with the trace macros you may find a cast that doesn't seem to work correctly when compiling vTaskSetApplicationTaskTag( NULL, ( void * ) 2 ); statement.  The (void *) generates a compiler error.  I had to use the following cast:
(void(*)(void*)) to make it compile and it properly loads the integer value into the TaskTag.




Jan 24, 2010, 12:58 am Last Edit: Jan 24, 2010, 12:58 am by juliandasilva Reason: 1
The DuinOS wiki has been hacked by a damn spammer. Specifically, the Tracker section. I deleted the spam, but do not have backup of the last modifications we made. Does some one has a local copy of the wiki or just the tracker section?


I can't understand which is the gain of adding links that nobody will click in an open source project page.


Go Up