Pages: [1]   Go Down
Author Topic: Why use a RTOS?  (Read 1818 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Edison Member
*
Karma: 67
Posts: 1656
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I now have ChibiOS/RT and FreeRTOS running on Due.  Should I bother to post them?

It seems like few Arduino users need or want to use a real-time kernel.

Here is the typical response from an "old timer" about using a RTOS.
Quote
When I author code that will run *UNDER* an OS, I by definition do not have access to the resources that will allow me to thread my own code. I am force to use the provided OS threading model and constructs.

I've developed some very complex systems though the years.  I've been programming in ASM before C even existed.

I have never used an "RTOS", I've always teased out and separated my code so timer interrupts always provide me the abilty to implement the required schedules. I'm also careful to author my code so scheduling can be changed around without complete rewrites. A recent design included a design that had Zigbee Radio (proprietary comm), Ethernet, host Serial, and a ton of real-time I/O, including router functions to packet route / bridge radio and Ethernet *AND* host serial traffic (packets route across all 3 "channels"). No RTOS was used, and suspect any RTOS would have cause a lot of packet jitter where the current system is very deterministic ...

So what is the primary motive for which people feel the need to use RTOS's on micro-controllers? Sorry, I don't get it.

Here is an "tutorial" by FreeRTOS that compares solutions without and with a RTOS http://www.freertos.org/tutorial/index.html.

I am an "old timer" and have used real-time kernels since the mid 1970s.  Often using a real-time kernel makes an application really easy.

Here are two tasks for a data logger that trivially logs data to an SD at 1000 points/second without losing data because of the occasional long SD write latency.

I ran this on Due with a buffer queue of 250 points, enough for a 250 millisecond write latency.  The ADC reader put data at the head of the queue and the SD writer takes data from the tail of the queue.

It could easily log data at much faster rates if a timer was used to trigger the data read thread.

Here is the ADC read task.  In my example it runs every 1000 microseconds and reads four ADC channels.
Code:
// ADC read thread
static msg_t Thread1(void *arg) {
  uint8_t over = 0;

  // read data until terminate signal
  while (!chThdShouldTerminate()) {
    // sleep until time for next point
    chThdSleep(SLEEP_TICKS);

    // get pointer to next free data point
    point* h = q.headItem();
    if (h) {
      // save time in micros
      h->usec = micros();

      // read ADC channels
      for (uint8_t i = 0; i < ADC_COUNT; i++) {
        h->data[i] = analogRead(i);
      }
      // count of overruns since last data
      h->over = over;
     
      // advance queue head so writer will see point
      q.headNext();

      // clear overrun count
      over = 0;
    } else {
      // count overrun - queue full
      if (over < MAX_OVER) over++;
    }
  }
  return 0;
}
Data is written to the SD by this thread:
Code:
// format data point and write to SD
void loop() {
  // get count of points in queue
  size_t n = q.count();
  for (size_t i = 0; i < n; i++) {
    // get pointer to next data point
    point* p = q.tailItem();

    // write data point
    file.print(p->usec);
    file.write(',');
   
    // format ADC values
    for (uint8_t i = 0; i < ADC_COUNT; i++) {
      file.print(p->data[i]);
      file.write(',');
    }
    // format overrun count
    file.println(p->over);
   
    // free data point storage in queue
    q.tailNext();
  }
  // check for write error
  if (file.writeError) sd.errorHalt_P(PSTR("write error"));
}

Here is the first part of the data file.  Note that there is no jitter in the time in micros.  Exactly 1000 microseconds between calls to the ADC read task.
Quote
micros,data0,data1,data2,data3,over
3769007,659,728,752,759,0
3770007,602,567,576,585,0
3771007,527,480,480,489,0
3772007,466,426,421,429,0
3773007,420,388,383,390,0
3774007,386,362,358,365,0
3775007,363,344,341,347,0
3776007,347,331,329,335,0
3777007,335,321,320,326,0
3778007,326,314,314,319,0

Logged

Brighton, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@fat16lib

Yes please!  Well done on pushing the boundaries forward.  I'm certainly interested in more reliable, fast methodologies.

Jim
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That would be fantastic. Neil
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8600
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't have a Due but can see the benefits of having an RTOS or two for it.

_____
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The example is great-- because it obviously works and I would like to experiment with it. My problem is that I do not find or can guess how you hooked up your Arduino Due with an Sd card shield (I have a SEEED Studio SD card shield v 3.1). Could you please devote a few words to that?

Kindest Regards,
MJM
Logged

Pages: [1]   Go Up
Jump to: