Page 1 of 1

Scheduling different tasks based on the mode

PostPosted: Tue Mar 18, 2014 9:43 pm
by z8379303
I am new to Salvo so I am still trying things out.
I was wondering how the following scenario can be achieved with salvo.
Let's say my system has 2 modes and 5 tasks in total. In Mode 1, I want the scheduler to pick a task from Task 1,2,3; in Mode 2, it should pick one from Task 3,4,5.

If I use semaphores to represent modes, I need to signal it each time I do context-switching; and for Task 3 which is shared by two modes, it has to wait for semaphore 1 OR 2. I am not sure if it is right way to do.

So I was wandering if anyone can suggest a way of doing it? Thanks in advance! :P

Re: Scheduling different tasks based on the mode

PostPosted: Wed Mar 19, 2014 7:40 am
by Andrew
The event-driven nature of Salvo requires that a task wait on an event ... if you were to signal a bunch of tasks to do something, you'd have to have them all wait the event. and that will affect how your tasks are structured.

I think the most straightforward way would be to re-initialize the OS when you switch modes, via an OSInit() and then the creation of the tasks you want in a group (1-3 or 4-6). The only thing you would lose is the ticks counter (it's reset to zero upon OSInit()), but you could read it (OSGetTicks()) and then (re-)set it (OSSetTicks()) thereafter, in order to have it increase monotonically over the lifetime of your application.

Note that you can destroy tasks, and start and stop them via the API. But, it will take some thought to synchronize them as groups.

Another option is to use event flags, maybe one bit per group.

Re: Scheduling different tasks based on the mode

PostPosted: Fri Mar 21, 2014 11:13 am
by Andrew
The problem / challenge with switching modes (by enabling certain tasks and disabling others) is synchronization ... if all you do is run periodic tasks (via a single OS_Delay() per task), then by definition, assuming you are in a task or in your main() that calls OSSched(), all the tasks will be delayed when you want to do a mode switch, and you can OSStopTask() those tasks to be stopped, and OSStartTask() those tasks you want started.

But, if you have a more complex context-switching scheme in some of those tasks (e.g., you're waiting on something via OS_WaitXyz()), then the start/stop approach doesn't work.

Calling OSInit() re-initializes all the tasks (and some other OS issues), and so you have a more clearly defined starting point to then use to enable those tasks active in your mode.

Note that all C constructs are valid in a alvo task ... you could, for example, have a
Code: Select all
switch(mode) {
at the top of your
Code: Select all
while(1) {
loop in each task, and then you could either do stuff
Code: Select all
or stop the task via OS_Stop() for the
Code: Select all
This would auto-stop (at the point of the OS_Stop() API call) the task when it's not in th active mode, but it would not restart such a task -- you'd need to call OSStartTask() on it. But that's OK, OSStartTask() doesn't mind operating on tasks that are already running, so you could c all OSStartTask() on all of the tasks whenever you change modes.

Another way to do it might be to use event flags, as they behave a bit differently from simple events.