Simple example of a very basic cooperative round robin task switching.
A very basic demo of how to run a set of tasks in sequence.
main.cpp@0:301a83d3eeb4, 2015-03-19 (annotated)
- Committer:
- AndyA
- Date:
- Thu Mar 19 17:08:55 2015 +0000
- Revision:
- 0:301a83d3eeb4
First commit.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AndyA | 0:301a83d3eeb4 | 1 | #include "mbed.h" |
AndyA | 0:301a83d3eeb4 | 2 | |
AndyA | 0:301a83d3eeb4 | 3 | Serial pc(USBTX,USBRX); |
AndyA | 0:301a83d3eeb4 | 4 | |
AndyA | 0:301a83d3eeb4 | 5 | int taskCount = 0; |
AndyA | 0:301a83d3eeb4 | 6 | const int maxTasks = 16; |
AndyA | 0:301a83d3eeb4 | 7 | void *taskList[maxTasks]; |
AndyA | 0:301a83d3eeb4 | 8 | |
AndyA | 0:301a83d3eeb4 | 9 | typedef void function_t(void); |
AndyA | 0:301a83d3eeb4 | 10 | |
AndyA | 0:301a83d3eeb4 | 11 | //runs the next task. Avoid calling from a ticker since that would block all interrupts while running. |
AndyA | 0:301a83d3eeb4 | 12 | void nextTask(void) |
AndyA | 0:301a83d3eeb4 | 13 | { |
AndyA | 0:301a83d3eeb4 | 14 | static int taskID = 0; |
AndyA | 0:301a83d3eeb4 | 15 | if (taskCount) { |
AndyA | 0:301a83d3eeb4 | 16 | if (taskID >= taskCount) // a task could have been removed. |
AndyA | 0:301a83d3eeb4 | 17 | taskID = 0; |
AndyA | 0:301a83d3eeb4 | 18 | |
AndyA | 0:301a83d3eeb4 | 19 | ((function_t*)taskList[taskID])(); |
AndyA | 0:301a83d3eeb4 | 20 | taskID++; |
AndyA | 0:301a83d3eeb4 | 21 | if (taskID == taskCount) |
AndyA | 0:301a83d3eeb4 | 22 | taskID = 0; |
AndyA | 0:301a83d3eeb4 | 23 | } |
AndyA | 0:301a83d3eeb4 | 24 | } |
AndyA | 0:301a83d3eeb4 | 25 | |
AndyA | 0:301a83d3eeb4 | 26 | // add a task to the list |
AndyA | 0:301a83d3eeb4 | 27 | bool addTask(void (*function)(void)) |
AndyA | 0:301a83d3eeb4 | 28 | { |
AndyA | 0:301a83d3eeb4 | 29 | if ((taskCount < maxTasks) && function) { |
AndyA | 0:301a83d3eeb4 | 30 | taskList[taskCount] = (void *)function; |
AndyA | 0:301a83d3eeb4 | 31 | taskCount++; |
AndyA | 0:301a83d3eeb4 | 32 | return true; |
AndyA | 0:301a83d3eeb4 | 33 | } else |
AndyA | 0:301a83d3eeb4 | 34 | return false; |
AndyA | 0:301a83d3eeb4 | 35 | } |
AndyA | 0:301a83d3eeb4 | 36 | |
AndyA | 0:301a83d3eeb4 | 37 | // finds a task in the list or -1 if not in the list. Mainly used for removing tasks. |
AndyA | 0:301a83d3eeb4 | 38 | int findTask(void (*function)(void)) |
AndyA | 0:301a83d3eeb4 | 39 | { |
AndyA | 0:301a83d3eeb4 | 40 | if (!function) |
AndyA | 0:301a83d3eeb4 | 41 | return -1; |
AndyA | 0:301a83d3eeb4 | 42 | int number = 0; |
AndyA | 0:301a83d3eeb4 | 43 | while (number < taskCount) { |
AndyA | 0:301a83d3eeb4 | 44 | if (taskList[number] == (void *)function) |
AndyA | 0:301a83d3eeb4 | 45 | return number; |
AndyA | 0:301a83d3eeb4 | 46 | number++; |
AndyA | 0:301a83d3eeb4 | 47 | } |
AndyA | 0:301a83d3eeb4 | 48 | return -1; |
AndyA | 0:301a83d3eeb4 | 49 | } |
AndyA | 0:301a83d3eeb4 | 50 | |
AndyA | 0:301a83d3eeb4 | 51 | // remove a task. returns false if the task wasn't in the list. |
AndyA | 0:301a83d3eeb4 | 52 | bool removeTask(void (*function)(void)) |
AndyA | 0:301a83d3eeb4 | 53 | { |
AndyA | 0:301a83d3eeb4 | 54 | int taskToRemove = findTask(function); |
AndyA | 0:301a83d3eeb4 | 55 | if (taskToRemove == -1) |
AndyA | 0:301a83d3eeb4 | 56 | return false; |
AndyA | 0:301a83d3eeb4 | 57 | |
AndyA | 0:301a83d3eeb4 | 58 | for (int i = taskToRemove; i<(taskCount-1); i++) { |
AndyA | 0:301a83d3eeb4 | 59 | taskList[i] = taskList[i+1]; |
AndyA | 0:301a83d3eeb4 | 60 | } |
AndyA | 0:301a83d3eeb4 | 61 | taskCount--; |
AndyA | 0:301a83d3eeb4 | 62 | return true; |
AndyA | 0:301a83d3eeb4 | 63 | } |
AndyA | 0:301a83d3eeb4 | 64 | |
AndyA | 0:301a83d3eeb4 | 65 | // simple example task. |
AndyA | 0:301a83d3eeb4 | 66 | void task1(void) |
AndyA | 0:301a83d3eeb4 | 67 | { |
AndyA | 0:301a83d3eeb4 | 68 | const int NumberOfStates = 5; |
AndyA | 0:301a83d3eeb4 | 69 | static int state = 0; |
AndyA | 0:301a83d3eeb4 | 70 | switch (state) { |
AndyA | 0:301a83d3eeb4 | 71 | case 0: |
AndyA | 0:301a83d3eeb4 | 72 | pc.putc('A'); |
AndyA | 0:301a83d3eeb4 | 73 | break; |
AndyA | 0:301a83d3eeb4 | 74 | case 1: |
AndyA | 0:301a83d3eeb4 | 75 | pc.putc('B'); |
AndyA | 0:301a83d3eeb4 | 76 | break; |
AndyA | 0:301a83d3eeb4 | 77 | case 2: |
AndyA | 0:301a83d3eeb4 | 78 | pc.putc('C'); |
AndyA | 0:301a83d3eeb4 | 79 | break; |
AndyA | 0:301a83d3eeb4 | 80 | case 3: |
AndyA | 0:301a83d3eeb4 | 81 | pc.putc('D'); |
AndyA | 0:301a83d3eeb4 | 82 | break; |
AndyA | 0:301a83d3eeb4 | 83 | case 4: |
AndyA | 0:301a83d3eeb4 | 84 | pc.putc('E'); |
AndyA | 0:301a83d3eeb4 | 85 | break; |
AndyA | 0:301a83d3eeb4 | 86 | default: |
AndyA | 0:301a83d3eeb4 | 87 | state = 0; |
AndyA | 0:301a83d3eeb4 | 88 | break; |
AndyA | 0:301a83d3eeb4 | 89 | } |
AndyA | 0:301a83d3eeb4 | 90 | state++; |
AndyA | 0:301a83d3eeb4 | 91 | if (state == NumberOfStates) |
AndyA | 0:301a83d3eeb4 | 92 | state = 0; |
AndyA | 0:301a83d3eeb4 | 93 | } |
AndyA | 0:301a83d3eeb4 | 94 | |
AndyA | 0:301a83d3eeb4 | 95 | // simple example task. |
AndyA | 0:301a83d3eeb4 | 96 | void task2(void) |
AndyA | 0:301a83d3eeb4 | 97 | { |
AndyA | 0:301a83d3eeb4 | 98 | const int NumberOfStates = 2; |
AndyA | 0:301a83d3eeb4 | 99 | static int state = 0; |
AndyA | 0:301a83d3eeb4 | 100 | switch (state) { |
AndyA | 0:301a83d3eeb4 | 101 | case 0: |
AndyA | 0:301a83d3eeb4 | 102 | pc.putc('1'); |
AndyA | 0:301a83d3eeb4 | 103 | break; |
AndyA | 0:301a83d3eeb4 | 104 | case 1: |
AndyA | 0:301a83d3eeb4 | 105 | pc.putc('2'); |
AndyA | 0:301a83d3eeb4 | 106 | break; |
AndyA | 0:301a83d3eeb4 | 107 | default: |
AndyA | 0:301a83d3eeb4 | 108 | state = 0; |
AndyA | 0:301a83d3eeb4 | 109 | break; |
AndyA | 0:301a83d3eeb4 | 110 | } |
AndyA | 0:301a83d3eeb4 | 111 | state++; |
AndyA | 0:301a83d3eeb4 | 112 | if (state == NumberOfStates) |
AndyA | 0:301a83d3eeb4 | 113 | state = 0; |
AndyA | 0:301a83d3eeb4 | 114 | } |
AndyA | 0:301a83d3eeb4 | 115 | |
AndyA | 0:301a83d3eeb4 | 116 | // simple example task using enum for current state. |
AndyA | 0:301a83d3eeb4 | 117 | void task3(void) |
AndyA | 0:301a83d3eeb4 | 118 | { |
AndyA | 0:301a83d3eeb4 | 119 | static enum {firstState,secondState} state = firstState; |
AndyA | 0:301a83d3eeb4 | 120 | switch (state) { |
AndyA | 0:301a83d3eeb4 | 121 | case firstState: |
AndyA | 0:301a83d3eeb4 | 122 | pc.putc('X'); |
AndyA | 0:301a83d3eeb4 | 123 | state = secondState; |
AndyA | 0:301a83d3eeb4 | 124 | break; |
AndyA | 0:301a83d3eeb4 | 125 | case secondState: |
AndyA | 0:301a83d3eeb4 | 126 | pc.putc('Y'); |
AndyA | 0:301a83d3eeb4 | 127 | state = firstState; |
AndyA | 0:301a83d3eeb4 | 128 | break; |
AndyA | 0:301a83d3eeb4 | 129 | default: |
AndyA | 0:301a83d3eeb4 | 130 | state = firstState; |
AndyA | 0:301a83d3eeb4 | 131 | break; |
AndyA | 0:301a83d3eeb4 | 132 | } |
AndyA | 0:301a83d3eeb4 | 133 | } |
AndyA | 0:301a83d3eeb4 | 134 | |
AndyA | 0:301a83d3eeb4 | 135 | main () |
AndyA | 0:301a83d3eeb4 | 136 | { |
AndyA | 0:301a83d3eeb4 | 137 | |
AndyA | 0:301a83d3eeb4 | 138 | addTask(&task1); |
AndyA | 0:301a83d3eeb4 | 139 | addTask(&task2); |
AndyA | 0:301a83d3eeb4 | 140 | pc.printf("\r\nTasks 1 & 2\r\n"); |
AndyA | 0:301a83d3eeb4 | 141 | for (int i = 0; i < 20; i++) |
AndyA | 0:301a83d3eeb4 | 142 | nextTask(); |
AndyA | 0:301a83d3eeb4 | 143 | |
AndyA | 0:301a83d3eeb4 | 144 | |
AndyA | 0:301a83d3eeb4 | 145 | addTask(&task1); |
AndyA | 0:301a83d3eeb4 | 146 | addTask(&task3); |
AndyA | 0:301a83d3eeb4 | 147 | pc.printf("\r\nTasks 1,2,1,3\r\n"); |
AndyA | 0:301a83d3eeb4 | 148 | for (int i = 0; i < 20; i++) |
AndyA | 0:301a83d3eeb4 | 149 | nextTask(); |
AndyA | 0:301a83d3eeb4 | 150 | |
AndyA | 0:301a83d3eeb4 | 151 | removeTask(&task1); // removes the first instance of task 1 in the list. |
AndyA | 0:301a83d3eeb4 | 152 | pc.printf("\r\nTasks 2,1,3\r\n"); |
AndyA | 0:301a83d3eeb4 | 153 | for (int i = 0; i < 20; i++) |
AndyA | 0:301a83d3eeb4 | 154 | nextTask(); |
AndyA | 0:301a83d3eeb4 | 155 | |
AndyA | 0:301a83d3eeb4 | 156 | pc.printf("\r\nDone\r\n"); |
AndyA | 0:301a83d3eeb4 | 157 | |
AndyA | 0:301a83d3eeb4 | 158 | } |