DuinOS: small and simple rtos

There is a bug reported when printing numbers with the overloaded Serial.Print (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1256745982/160#160) and I'm not sure it's caused by a stack problem. Sadly we could not work on it yet.

May I suggest that you try with the v0.1 and the 0018 core? These bugs were not reported for that version, and there was a FreeRTOS kernel change between v0.1 and v0.2. If it works, we may roll-back something for the v0.3.

Thanks!

Regards,
Julián

I actually seem to have fixed the problem when I went back and simplified some of the code. Things seem to be working fine now.. I will roll back to 0.1 if I run into more problems.

Julian,

I'm getting back into some Arduino/DuinOS coding after some time off and was wondering if the latest DuinOS rev is compatible with the latest Arduino build (21).

Thanks.

Hi, we did not test it yet but I think it's not.
The latest v0.2 is 0018-compatible.

Regards,
Julián

Thanks.

Saw you were working on v0.3. Any ETA on that? Need help testing?

mmm, sorry, not ETA yet, but working.
With kind regards,
Julián

Hello,

Where can I find more examples of DuinOS? All that I could find is MoreComplexBlinking and MoreComplexBlinkingAndSound.

Thanks!

Hello!

I am trying to develop a Clock for Arduino using DuinOS. The idea is to use a task in order to manage the system time while others task are running.

To set the clock, it is used an UNIX format, for example: T1291036511. Where "T" is a special char to identify the UNIX time. We give the unix time to the system using the serial connection.

When I put the unix time in the serial port, the system goes very slow... and it freezes.

Here is my code (based on MoreComplexBlinking):

#include <Time.h>  

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

#define INITIAL_GREEN_DELAY  200
#define NEW_GREEN_DELAY  20

int ledPinRed =  8;
int ledPinGreen =  9;

unsigned int greenDelay = INITIAL_GREEN_DELAY;
boolean redLED_isOn = false;
boolean greenLED_isOn = false;

//Forward declaration, to let redLED call to resumeTask(greenLED). It's not necessary if we put the greenLED 
//itself here, but declareLoopTask may be usefull in more complex situations:
declareTaskLoop(greenLED);
declareTaskLoop(clock);

taskLoop(redLED)
{
  static unsigned char counter = 0;
  
  if (!greenLED_isOn)
  {
     if (counter >2)
       resumeTask(greenLED);
     counter++;
  }
  
  redLED_isOn = false;
  delay(1000);
  redLED_isOn = true; 
  delay(1000);
}


taskLoop(greenLED)
{
  static unsigned char counter = 1;

  digitalWrite(ledPinGreen, HIGH);  // set the LED on
  delay(greenDelay);
  digitalWrite(ledPinGreen, LOW);  // set the LED off
  delay(greenDelay);

  if ( (counter >= 9) && (greenDelay != NEW_GREEN_DELAY) )
    greenDelay = NEW_GREEN_DELAY; //now, after 10 blinks, accelerates
  if (counter >= 99)
  {
    //Reset vars, so next time, if the task is resumed, it executes all again:
    counter = 0;
    greenDelay = INITIAL_GREEN_DELAY;
    greenLED_isOn = false;
    suspend();      //After a while, the tasks suspends itself (forever)
  }
  counter++;
}

taskLoop(clock)
{    
  if(Serial.available() ) 
  {
    processSyncMessage();
  }
  if(timeStatus()!= timeNotSet)   
  {
    digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh  
    digitalClockDisplay();  
  }
  delay(1000);
}

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

void setup()   
{                
  // Initialize the digital pins as outputs:
  pinMode(ledPinRed, OUTPUT);
  pinMode(ledPinGreen, OUTPUT);
  
  Serial.begin(9600);
  setSyncProvider( requestSync);  //set function to call when sync required
  Serial.println("Waiting for sync message...");
  
  createTaskLoop(clock, HIGH_PRIORITY);
  createTaskLoop(redLED, NORMAL_PRIORITY);
  createTaskLoop(greenLED, LOW_PRIORITY);

  //This initializes the main loop's with a different priority (default is LOW_PRIORITY):
  //initMainLoopPriority(NORMAL_PRIORITY);

  //Try this and see what happends:
  //suspendTask(redLED);
}


// This is the main loop() method, wich runs over and over again,
// as long as the Arduino has power. Is a LOW_PRIORITY taskLoop:

void loop()                     
{
  if (redLED_isOn)
  {
    digitalWrite(ledPinRed, LOW);  // set the LED off
    delay(25);                      // The OS can be tested reducing these delays, and seeing how both LEDs work together...
    digitalWrite(ledPinRed, HIGH);   // set the LED on
    delay(25);    
  }
  else
  {
    digitalWrite(ledPinRed, LOW);  //  LED is off
    //If nextTask is not called, the application will not hang, because the OS is preemptive. BUT, the current task
    //will consume a lot of computational resources (due to it's lack of a delay() in this branch), the application will 
    //turn slower, and the other tasks may be affected by this, loossing precision in their timing:
    nextTask();
  }
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void processSyncMessage() {
   // if time sync available from serial port, update time and return true

  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
      Serial.println("Serial.available");
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      Serial.println(pctime);
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

time_t requestSync()
{
  Serial.print(TIME_REQUEST,BYTE);  
  return 0; // the time will be sent later in response to serial mesg
}

I know it seems counter intuitive, but did you try putting delay() functions by the serial commands.

I been working on a DuinOS project all weekend. The serial.print functions gave me allot of trouble, but for some reason if I put delays right after or before the serial commands the trouble went away.

I wondering if it caused by the Content switching and interrupting the serial functions.

Hi,

This seems very interesting! Did anyone get it to work with the Mega2560?

Thanks!

Nice initiative!

Hello,

I have translated the DuinOS 's wiki in french at http://robotgroup.com.ar/duinos/wiki/index.php?title=Main_Page-FR

and I have updaded several english wiki page and added several useful links in the DuinOS wiki.

I hope this will useful for the Arduino community.

Regards.

Yannick

Many thanks!
Great Idea!

I think we will have to translate to Spanish then :slight_smile:

Regards,
Julián

I'm working on DuinOS 0.3 Alpha.
I have checked all the changes in DuinOS 0.2 and I have reported them on DuinOS 0.3.

Now in this Alpha DuinOS 0.3 release, I have made :

  • update to FreeRTOS 6.1.0
  • update to Arduino IDE 0021

With DuinOS 0.3, I have compiled the following exemples without problems :
MoreComplexBlinking and MoreComplexBlinkingAndSound.

Does somebody have any idea where I can upload the 0.3 release for downloading by users for testing ?

I'm happy to provide with some webspace for the download on a personal hosting, I'll contact you via PM.

Thanks
Stijn

@Stijn

I think that I will contact Julian DA SILVA to allow me to commit my changes at Google Code Archive - Long-term storage for Google Code Project Hosting..

It will be more useful for all community (get source code and show diff changes, download the latest release for the users).

Sorry, I did not see the replies before.

Of course, please feel free to commit to the Google Code repository. We have created that this year but did not announced it yet.

Regarding the mprintf, please check my previous question to Paula and her kindly answer in entries 5, 6 and 7 of this blog:

http://www.out--there.com/blog/the-devil-is-in-the-details-atmega-startup-to-freertos/

We are cooking new software (don't say nothing yet, it's a graphical programming environment, but shhh) to be released as soon as possible, so DuinOS were not receiving our full attention. I'm really happy that you have ported it to the 0021 and the new FreeRTOS core.

By other hand, we were working along the 2010 on a lot of things, and one of them is testing core that we called the 0Warning Experimental Arduino Core, or just the 0W. It's here:

http://code.google.com/p/0w-experimental-arduino-core/

We just implemented it with the 0019 version, but it's quiet easy to do the same job for the 0021 version. We have no time now, but were planing to integrate the DuinOS Core with this. It's NOT TESTED AT ALL, but when compiled with Code::Blocks, it has 0 warnings, against the 42 warnings from the original 0019 version (we don't know if the 0021 has some of them, because did not check it).

But for DuinOS v0.4 it will be nice to have it 0W too! Don't you think?

Oh, something I was forgetting. If someone is interested, please find with the 0W core, the following files:

CPPLib.h
CPPLib.cpp

Those add the new() and delete() operators, (with very common and well known iplementations) and the function that allows to have virtual pure destructors.

I'm happy to of having feedback again!

Kind regards, and thanks for all your work!
Julián

To DuinOS users,

I have updated DuinOS source code for DuinOS 0.3 release in the next weeks (maybe before christmas 2010, I don't know) .
You can get it by svn here
http://code.google.com/p/duinos/source/checkout

We need someone who has an Arduino Mega2560 for testing.

That's great news!

Are the incompatibilities here still an issue?

http://www.multiplo.org/duinos/wiki/index.php?title=Tracker#Incompatibility_issues_with_Arduino_libraries

Some yes, and some no:

Thanks Yannick! Very great work!

Cheers!
Julián