Program structure for cooperative scheduling - Page 1
Forum section: electronics / general

author: BlogRahul
author_rank: Regular Contributor
timestamp: January 12, 2022, 02:11:46 pm
content: Hi allI am trying to write generic c code for cooperative scheduling just for learning.Here is my basic ideaCode:enum Task_STATE {READY_To_RUN, RUNNING, WAITING};enum Task_STATE STATE_FLAG;int main(void){STATE_FLAG = READY_To_RUN;while(1){if (Timer_Flag == 1){// Timer_Flag set every 1 msTimer_Flag = 0;{switch (STATE_FLAG){case READY_To_RUN :// Pick the taks that is ready to runSTATE_FLAG = RUNNING;break;case RUNNING :// Run the taskSTATE_FLAG = WAITING;break;case WAITING :// waitingSTATE_FLAG = READY_To_RUN;break;default:// Unknown State Encountered, Reset System to READY_To_RUN,STATE_FLAG = READY_To_RUN;}}}}return (0);}// interrupt every 1 msvoid ISR_Timer_Interrupt (){if ( T1IF = SET ){T1IF = 0;Timer_Flag = 1;}}I need to create eight tasks and choose one of the task that is ready to run in state 1 . How to do this in code?

author: brendan0powers
author_rank: Newbie
timestamp: January 12, 2022, 02:38:45 pm
content: I'm certainly no expert here, but I think you need some kind of abstraction for a task. The abstraction needs to include what task to run, and wether the task is ready to execute. You might do something like:Code:typedef struct {bool isReady;void (*taskFunc)();} Task;This struct holds a pointer to a task function, and a boolean flag indicating wether it should be run. You'd need to store a list of these, and iterate over the list every time you're in the running state. Once you have that working, you can start to add features. Time to next ready, priority, some kind of yield mechanism that makes it easier to wait for an interrupt, etc...

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 12, 2022, 05:44:49 pm
content: Yep, you do need to structure your code if you want this to be maintainable, otherwise it will just look like spaghetti.I just happen to have run into this yesterday:https://github.com/cocoOS/cocoOS, from which you could probably find some inspiration.

author: ledtester
author_rank: Super Contributor
timestamp: January 12, 2022, 06:53:12 pm
content: A very simplistic solution is to have your main loop look like this:Code:void loop() {while (1) {task1();task2();...task8();}}and each task subroutine looks like the one you have in your original post -- i.e. each has its own state variable which selects a fragment of code to run. A task gives up the cpu by returning from its subroutine.There is no scheduling or priorities implemented and there's a lot of busy waiting, but it's basically what cooperative multithreading is all about.

author: BlogRahul
author_rank: Regular Contributor
timestamp: January 12, 2022, 07:26:20 pm
content: Quote from: SiliconWizard on January 12, 2022, 05:44:49 pmI got the first inspiration that I should think to build a kernel first. To develop kernel I need many source filesThis is my list of source files to develop kernelmain.cTask.cList.cQueue.cTimer.cevent.cI need to write generic code for all source files

author: errorprone
author_rank: Contributor
timestamp: January 13, 2022, 12:50:07 pm
content: Here is another example of a cooperative scheduler that doesn’t have any extra features but is a nice demonstration of function pointers.https://www.cs.ucr.edu/~vahid/rios/

author: obiwanjacobi
author_rank: Super Contributor
timestamp: January 14, 2022, 11:07:34 am
content: Examplehttps://github.com/obiwanjacobi/atl/blob/master/Source/Code/Arduino%20Libraries/ATL_Process/examples/TimeoutTask/TimeoutTask.inoSource:https://github.com/obiwanjacobi/atl/blob/master/Source/Code/ArduinoTemplateLibrary/Task.hDocs:https://github.com/obiwanjacobi/atl/blob/master/docs/Cooperative%20Multi-tasking.md