Pages: [1]   Go Down
Author Topic: Understanding Scheduler Library? (And many application questions!)  (Read 809 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've got some pretty basic questions regarding my application and implementing the Scheduler Library. I'm very much a novice, so I apologize before hand.

First a note about my application:

Imagine a factory with a number of different stations all controlled by a central "hub". This central hub will be the Due and the stations can be divided into two subgroups: smart and dumb stations. The smart stations have another Due that communicates via RS-435 with the hub. The dumb stations are controlled by the GPIO of the hub.

I've got a large amount of data that consists of "addresses" and "times". Initially, (before the main loop) this data is processed and sent to an external EEPROM chips on I2C bus. (After processing data from SD card, the user should be able to remove the SD card and power down the unit, come back the next day without the SD card and still have it work). This much is more or less complete. I have not decided whether I want to try and read directly from the EEPROM or whether it would be beneficial to load the data out of EEPROM and into SRAM before entering the main loop.

Now, in the main loop I've got something that basically looks like (in pseudocode)
Code:
unsigned long time[800]; //In reality, arrays like these will take up about 23 kB of SRAM
byte address[800];
int i = 0;
int interval = 1;

void loop(){
  if (time[i] >=  millis() && time[i] <= millis() + interval){
    //turn on address[i]
    ++i;
    if (i > 800) reset();
  }
}

I want to do other things while this is running but I need to be sure that I always return to this "stuff" within the 1 mS window. I don't want to accidentally miss a "turn-on event" because I was busy working on a different thread. The trouble is, sometimes these these events are separated by several seconds or even minutes while other times they are only separated by a couple of milliseconds. For instance, I'm interested in using the Audio library to output some analog wave forms from the onboard DACs but I want the main loop to have priority. I'd also like to ping the smart stations regularly over the RS-435 to make sure they are still active.

The problems that I see are the following:
1)memory; I assume that the schedule requires separate "heaps" (right word?) for each "thread" that it runs.
2)timing; how do I know when the scheduler will return to test the if statement in my code? I am under the impression that yield will pass the control to another task, but does that task have to complete before the scheduler returns to the main task?

With 1 mS "accuracy", I have an approximate minimum of 80,000 clock cycles where I'm not doing anything except killing time. I'd like to squeeze some useful instructions in there but always return to check the main loop after 80,000 cycles so I know I don't miss an event.

Does any of this make sense? Is there anyone who has the time to bring a novice up to speed on this topic?
« Last Edit: January 21, 2013, 10:08:17 pm by tms8c8 » Logged

Forum Administrator
Milano, Italy
Offline Offline
Sr. Member
*****
Karma: 23
Posts: 292
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1)memory; I assume that the schedule requires separate "heaps" (right word?) for each "thread" that it runs.

Every "thread" has its own stack, the heap is shared for all threads. The stack contains all "local" variables, while the stack heap contains "global" and "static" variables. This means that every thread has its own set of local variables.

Quote
2)timing; how do I know when the scheduler will return to test the if statement in my code? I am under the impression that yield will pass the control to another task, but does that task have to complete before the scheduler returns to the main task?

A thread keeps the CPU busy between calls to yield(). If you want to manage the 1ms deadline, you should design your program in a way that there are no places where the time between two yield() calls is more than X, where X is 1ms / no. of tasks.
This is easily achievable in your own code, but you should be very careful using libraries.

BTW consider that the Scheduler is at a very early stage of development, and many libraries should be adapted to be scheduler-friendly.

Another approach is to use an RTOS, that hasn't the yield() problem (since the scheduling is done by the kernel using timer-ticks) but has other thread-safety synchronization issues to consider (and sometimes are very hard to handle especially for beginners). The forum user fat16lib has ported some of the most famous RTOS kernels to the Due, if you do a quick search on the forum you can easily find it.
« Last Edit: January 23, 2013, 08:52:07 am by cmaglie » Logged

C.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 58
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you, Cmaglie! You just opened up the door to a subject I didn't know existed! I've sent a message to fat16lib, downloaded a textbook he posted on the forums about embedded solutions and begun playing with ChibiOS. For my application, I think an RTOS is exactly what I need - and I'm excited to learn about them. Thanks again.
Logged

Pages: [1]   Go Up
Jump to: