Is it cooperative scheduling

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
What would you call these pseudocode cooperative multitasking or cooperative scheduling
LED1
LED2
LED3

enum LED_STATE ( STATE1 = 1, STATE2 = 2, STATE3 = 3)STATE;

void main ()
{
    unit8_t Timer1 = 0 ;
    unit8_t Timer2 = 0 ;
    unit8_t Timer3 = 0 ;

    LED1 = ON ;
    LED2 = ON ;
    LED3 = ON ;

    STATE = STATE1;

    while (1)
    {
        if (Timer_Flag == 1)
        {                        // Timer_Flag set every 10ms
            Timer_Flag = 0; 

            //increment each timer every 10ms
            Timer1++ ;
            Timer2++ ;
            Timer3++ ;

            switch (STATE)
            {
                case STATE1 :
                            if ( Timer1 == 10 )   // check if time is 100ms
                               {
                                 LED1 =~ LED1 ;   // change state of LED1
                                 Timer1 = 0;      // clear Timer1 for next time
                                 STATE = STATE2 ; // Move to next STATE
                               }
                               break;
                case STATE2 :
                            if ( Timer2 == 20 )   // check if time is 200ms
                               {
                                 LED2 =~ LED2 ;   // change state of LED2
                                 Timer2 = 0;      // clear Timer2 for next time
                                 STATE = STATE3 ; // Move to next STATE
                               }
                              break
                case STATE3 :
                              if ( Timer3 == 30 )  // check if time is 300ms
                              {
                                LED3 =~ LED3 ;     // change state of LED3
                                Timer3 = 0;        // clear Timer3 for next time
                                STATE = STATE1 ;   // return to STATE1
                              }
                              break;
            }

}

// interrupt every 10ms
void ISR_Timer_Interrupt ()
{
    if ( T1IF = SET )
    {
      T1IF = 0;
      Timer_Flag = 1;
    }
}

 

Last Edited: Fri. Jan 7, 2022 - 10:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Cooperative" just means that the tasks themselves decide when they will relinquish control; there is nothing to force a task to relinquish control, so the tasks have to cooperate and not "hog" the system.

 

The converse would be "pre-emptive".

 

 

 

muke12 wrote:
would you call these pseudocode cooperative multitasking

I think it would be a stretch to call it multitasking at all.

 

But, for the sake of a trivial example, you could call them "tasks" ...

 

ADDENDUM

 

https://www.rapitasystems.com/blog/what-are-co-operative-and-pre-emptive-scheduling-algorithms

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Jan 7, 2022 - 11:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

muke12 wrote:

What would you call these pseudocode cooperative multitasking or cooperative scheduling

 

Well it's certainly not multitasking because it's only doing one thing, there is only one task (well actually there are no tasks at all as it all runs in main() ).

 

And it's not cooperative because of the same reason. With only one, or zero, task(s) there is nothing else to cooperate with.

 

Is it any form of scheduling? Maybe. Just about. But it's certainly not either of your descriptions.

 

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't think you even need the 3 timers:

    while (1)
    {
        if (Timer_Flag == 1)
        {                        
            Timer_Flag = 0; 

            //increment timer every 10ms
            Timer1++ ;

            if ( Timer1 == 10 ) // check if time is 100ms
            {
                Timer1 = 0; 
                switch (STATE)
                {
                case STATE1 :    // 1st 100ms - update LED1
                                 LED1 =~ LED1 ;   // change state of LED1
                                 STATE = STATE2 ; // Move to next STATE
                               break;
                case STATE2 :    // 2nd 100ms (ie, 200ms) - update LED2
                                 LED2 =~ LED2 ;   // change state of LED2
                                 STATE = STATE3 ; // Move to next STATE
                              break
                case STATE3 :   // 3rd 100ms (ie, 300ms) - update LED3, then restart the cycle
                                LED3 =~ LED3 ;     // change state of LED3
                                STATE = STATE1 ;   // return to STATE1
                              break;
                }
            }

}
 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

muke12 wrote:

What would you call these pseudocode cooperative multitasking or cooperative scheduling

Is it any form of scheduling? Maybe. Just about. But it's certainly not either of your descriptions.

 

What do you think, Is there any difference between multitasking and scheduling?

 

I don't think I think both cooperative multitasking and cooperative scheduling are same things 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

I don't think you even need the 3 timer

I thought each LED should have its own timer. Actually idea was to flash eight LED's

 

What's your approach?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It depends.

 

The simple sequence you posted just requires one timer, as shown.

 

Just extending that sequence to more LEDs would also just need 1 timer (also other optimisations are possible).

 

For a general, arbitrary sequence, separate timers might be easier.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should declare a global volatile unsigned long variable (for example: milliCount) and initialize it to 0x0000.  Then set the timer to interrupt every millisecond and increment milliCount.  Have a function  millis() that returns the milliCount value.

 

Each task will have a milliCount variable that indicates to the main() when it is time to do the task again.   The loop section of main() will test if the milliCount variable for the task is equal to the current milliCount returned by millis().

 

unsigned long  toggleLEDNow = 500;

unsigned long popNow = 50000;

 

int main() {

   setup();

   while(1) {

         if (millis() == toggleLEDNow) {

             toggleLEDnow += 500;

             toggleLED();

         } 

       

         if (millis() ==popNow) {

             popNow += 50000;

            explode();

         } 

    } /* while */ 

}  /* main */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
  Have a function  millis() that returns the milliCount value.

and if that sounds familiar, it is: https://www.arduino.cc/reference/en/language/functions/time/millis/

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

muke12 wrote:

I don't think I think both cooperative multitasking and cooperative scheduling are same things 

 

I think they are two terms to describe the same thing.

 

Cooperative Multitasking means that individual tasks routinely give up control of the CPU when they don't need it. Usually while they are waiting for some external, to them, event. So they might be waiting on a semaphore; they might be waiting a period of time before they need to run again, or they might simply yield() to give other tasks the chance to run.

 

Cooperative Scheduling means that the piece of software which decides when each task should run, and which handles semaphores, mailboxes and the like, assumes that all the tasks are coopertive.

 

The two things go hand in hand. There's nothing to stop you writing a task which doesn't cooperate; one which waits on an external event with a 'while(FALSE==event)', but if you do then there's nothing the scheduler can do about it.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is a tutorial on multi-tasking scheduler on this forum, have you read it?

https://www.avrfreaks.net/forum/...

 

You may find it helpful to answer your questions!

 

Jim

 

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

muke12 wrote:
Is there any difference between multitasking and scheduling?

Yes.

 

Multitasking just means having multiple tasks.

 

If you have multiple tasks, you have to decide when to run each one - that's scheduling.

 

Again: https://www.rapitasystems.com/blog/what-are-co-operative-and-pre-emptive-scheduling-algorithms 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
There's nothing to stop you writing a task which doesn't cooperate; one which waits on an external event with a 'while(FALSE==event)', but if you do then there's nothing the scheduler can do about it.

As people who used Windows 3.x  will remember ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lets begin with some basic terms, in order to have multi-tasking, one must first have a task!

A task is a sequence of instructions, sometimes done repetitively,
to perform an action (e.g. read a keypad, display a message on an
LCD, flash an LED or generate a waveform). In other words, it’s
usually a small program inside a bigger one.

 

The simplest form of multi-tasking is foreground/background tasking, this usually means one has a main loop where most of the processing is done (background), and an ISR(forground) that is triggered by some event, such as a timer interrupt, a character received via SPI or USART, or an external event like a pin change interrupt.

 

Two or more foreground tasks above would be an example of multi-tasking....

Here scheduling is handled by the interrupt priority mechanism built into the micro, and in this example that would be pre-emptive, not cooperative scheduling! 

 

Jim

edit: added scheduling, and pre-emption...

 

FF = PI > S.E.T

 

Last Edited: Fri. Jan 7, 2022 - 02:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
in order to have multi-tasking, one must first have a (sic) task!

In order to have multi-tasking, one must first have multiple tasks!

 

The clue is in the name!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Andy for clarifying that, and just to add, tasks do not have to be ISR(), that was just one example, tasks can be "scheduled" to run as multiple background tasks as well.

 

 

FF = PI > S.E.T

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

Just to point out the obvious (there's a clue in the name of the variables!) the code in #1 is simply a "state machine". It's not multi-tasking, it's one task running multiple states. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

There is a tutorial on multi-tasking scheduler on this forum, have you read it?

https://www.avrfreaks.net/forum/...

 

There is a problem with that tutorial and it is this statement...

 

Quote:

... Downside is that your code must be written in a way that you do the job and finish within a given time...

 

...what is described there is Run To Completion (RTC) scheduling which isn't really Cooperative Scheduling. A cooperative task is one that hands control (yields) back to the scheduler when it no longer needs full access to the CPU, irrespective of whether it has finished it's task.

 

A true cooperative task will, once it's running, live inside a 'while(1)' loop.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Brian Fairchild wrote:
A cooperative task is one that hands control (yields) back to the scheduler when it no longer needs full access to the CPU, irrespective of whether it has finished it's task.

Hmmm ... that could be implemented as a task that returns (exits) to the scheduler whenever it no longer needs CPU - which wouldn't necessarily mean that it's "finished".

 

So the choice to exit to the scheduler is the "cooperation".

 

That would mean that the task would have to remember some internal state so that, when it gets called again, it knows where it left off...

 

It's quite a simple way to build a multi-tasking system.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Hmmm ... that could be implemented as a task that returns (exits) to the scheduler whenever it no longer needs CPU - which wouldn't necessarily mean that it's "finished".

 

That's RTC (run to completion). 

 

awneil wrote:

That would mean that the task would have to remember some internal state so that, when it gets called again, it knows where it left off...It's quite a simple way to build a multi-tasking system.

 

State machines all the way. Their use in embedded systems ought to be made compulsory. Driving character LCDs is sooooo much easier when you use a state machine and a timer tick.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
That's RTC (run to completion)

but it's still "cooperative" in the sense that it's not pre-emptive, and so the tasks have to be specifically designed to "cooperate" - ie, not "hog" the system.

 

State machines all the way.

Absolutely! 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

but it's still "cooperative" in the sense that it's not pre-emptive, and so the tasks have to be specifically designed to "cooperate" - ie, not "hog" the system.

 

Ah, but the tasks have no say in whether they cooperate; they just do. In a true cooperative system a task will make a decision to yield to the scheduler.

 

Take waiting for a character to come in from a USART. In an RTC system the task will look at a flag variable set by an ISR and if it is not set all it can do is exit. The next time it run it uses a state machine to go back to the 'waiting for a character' state and retest the flag. Rinse and Repeat.

 

In a cooperative system the task can test a semaphore set by the ISR (and here's the important bit) and execution of that task will, to the outside world, appear to pause at that point. The task does not exit; it's all taking place in a while(1) loop. Meanwhile the scheduler has got back control and can schedule other tasks, handing control back to the paused task as and when those other tasks cooperate by given back the CPU. Rinse and Repeat.

 

The difference is conceptual. What makes more sense in a multitasking system when you are waiting for an external event? Abandoning what you are doing and coming back to it later, or waiting at that point until the event becomes true?

 

 

@OP - you really need to do some reading of proper resources about scheduling/mutitasking etc on small devices. Start with...

 

Intel Application Note AP-61

Adam Dunkels Protothreads

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Fri. Jan 7, 2022 - 04:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Start off with a state machine and one timer---you can usually accomplish a lot with just that.  You can even have a hierarchy of state machines to perform more complex tasks.

Draw your LEDs as a state diagram & you will be able to come up with many variations to flash in different patterns.

Keep it simple, until it can no longer be simple! You can also jump into using an RTOS, but too many think of it as a save-all, when a little extra planning with a good state machine is more than sufficient.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The way I see it, "Scheduling" is mostly about figuring out which task to run next.  Whereas the type of multi-tasking determines when a task pauses.

In cooperative mutitasking, a task gets to run a long as it wants, and then lets the scheduler figure out what to run next.

In preemptive multitasking, a task can also be interrupted (preempted) by a timer or other interrupt, and the scheduler decides whether some other task should run at that point.