See graph
Dependencies: MCP23017 SDFileSystem WattBob_TextLCD mbed
Fork of Embedded_Software_Assignment_2 by
main.cpp@17:d12bdce11d40, 2017-03-14 (annotated)
- Committer:
- xouf2114
- Date:
- Tue Mar 14 15:47:24 2017 +0000
- Revision:
- 17:d12bdce11d40
- Parent:
- 15:c1cf53d91a85
Added library documentation and updated FATFileSystem sub-library to the latest revision
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sk398 | 4:b85bc0d810e1 | 1 | /* ##################################################################### |
sk398 | 4:b85bc0d810e1 | 2 | main.cpp |
sk398 | 4:b85bc0d810e1 | 3 | --------- |
sk398 | 4:b85bc0d810e1 | 4 | |
sk398 | 4:b85bc0d810e1 | 5 | Embedded Software - Assignment 2 |
sk398 | 4:b85bc0d810e1 | 6 | -------------------------------- |
sk398 | 4:b85bc0d810e1 | 7 | |
xouf2114 | 11:1069d300847b | 8 | Written by: Xavier Gouesnard |
sk398 | 4:b85bc0d810e1 | 9 | |
xouf2114 | 11:1069d300847b | 10 | Date: March 2017 |
sk398 | 4:b85bc0d810e1 | 11 | |
sk398 | 10:c0531edf4850 | 12 | Function: This is the main runner containing the Cyclic executive |
xouf2114 | 11:1069d300847b | 13 | There are 8 defined tasks and several Auxillary components |
sk398 | 10:c0531edf4850 | 14 | which are logically ran periodically at their required time |
sk398 | 10:c0531edf4850 | 15 | by a Cyclic Executive sequencer. |
sk398 | 10:c0531edf4850 | 16 | Ticks, or slots, to this Cyclic Executive are provided by |
sk398 | 10:c0531edf4850 | 17 | a ticker ever 25ms, and then using logical expressions, the |
sk398 | 10:c0531edf4850 | 18 | correct task is initiated and allocated the required time. |
xouf2114 | 15:c1cf53d91a85 | 19 | |
sk398 | 4:b85bc0d810e1 | 20 | |
sk398 | 4:b85bc0d810e1 | 21 | ##################################################################### */ |
sk398 | 2:22ebabd78084 | 22 | |
sk398 | 0:5989ac10c4d3 | 23 | #include "mbed.h" |
sk398 | 1:221d677fe0d3 | 24 | #include "Tasks.h" |
sk398 | 0:5989ac10c4d3 | 25 | |
sk398 | 7:2973bf297f3d | 26 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 27 | // Task Declerations |
sk398 | 7:2973bf297f3d | 28 | // ============================================================================ |
sk398 | 6:ceda53939eb8 | 29 | Task1 task1(p11); // Square wave Measurement |
sk398 | 7:2973bf297f3d | 30 | Task2 task2_switch1(p12); // Read digital Input |
sk398 | 6:ceda53939eb8 | 31 | Task3 task3(p13); // Watchdog Pulse |
sk398 | 6:ceda53939eb8 | 32 | Task4 task4(p15,p16); // Read analog Inputs |
sk398 | 6:ceda53939eb8 | 33 | Task5 task5(p9,p10,0x40); // Output to LCD Display |
sk398 | 6:ceda53939eb8 | 34 | Task6 task6; // Logical checks |
sk398 | 6:ceda53939eb8 | 35 | Task7 task7(p5,p6,p7,p8,"SD","/SD/A2"); // SD Card Write |
xouf2114 | 11:1069d300847b | 36 | //Task8 task8; // Shutdown Switch |
sk398 | 0:5989ac10c4d3 | 37 | |
sk398 | 7:2973bf297f3d | 38 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 39 | // Cyclic Executive Objects and Declerations |
sk398 | 7:2973bf297f3d | 40 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 41 | DigitalOut ErrorLED(LED1); // Error Indicating LED |
sk398 | 10:c0531edf4850 | 42 | DigitalOut LenPin(p25); // Pulse Pin |
sk398 | 10:c0531edf4850 | 43 | DigitalIn SDRemoval(p18); // Switch state to indicate remove SD |
sk398 | 7:2973bf297f3d | 44 | Ticker CyclicTicker; // Ticker object to cycle tasks |
sk398 | 10:c0531edf4850 | 45 | Timer stampTime; // Timer to stamp the time between logs |
sk398 | 10:c0531edf4850 | 46 | |
sk398 | 10:c0531edf4850 | 47 | // NOTE THE FOLLOWING ARE NOT ESSENTIAL TO THE OPERATION OF THIS CYCLIC EXECUTIVE |
sk398 | 10:c0531edf4850 | 48 | Timer task1t; // Timer to calculate task1 timing |
sk398 | 10:c0531edf4850 | 49 | Timer task2t; // Timer to calculate task2 timing |
sk398 | 10:c0531edf4850 | 50 | Timer task3t; // Timer to calculate task3 timing |
sk398 | 10:c0531edf4850 | 51 | Timer task4t; // Timer to calculate task4 timing |
sk398 | 10:c0531edf4850 | 52 | Timer task5t; // Timer to calculate task5 timing |
sk398 | 10:c0531edf4850 | 53 | Timer task6t; // Timer to calculate task6 timing |
sk398 | 7:2973bf297f3d | 54 | |
sk398 | 7:2973bf297f3d | 55 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 56 | // Global Data Parameters used in Cyclic Executive |
sk398 | 7:2973bf297f3d | 57 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 58 | // Counter to record the number of ticks went through by the Cyclic Executive |
sk398 | 7:2973bf297f3d | 59 | int cyclicTicks = 1; |
sk398 | 7:2973bf297f3d | 60 | |
sk398 | 10:c0531edf4850 | 61 | // Flag variable to switch priority between Tasks 2 and 3 |
sk398 | 10:c0531edf4850 | 62 | int taskNum = 2; |
sk398 | 10:c0531edf4850 | 63 | |
sk398 | 7:2973bf297f3d | 64 | // Global parameter storing the most up to date value of the return from Task 1 |
sk398 | 7:2973bf297f3d | 65 | volatile int task1Frequency; |
sk398 | 7:2973bf297f3d | 66 | |
sk398 | 7:2973bf297f3d | 67 | // Global parameter storing the most up to date value of the return from Task 2 |
sk398 | 7:2973bf297f3d | 68 | volatile int task2SwitchState; |
sk398 | 7:2973bf297f3d | 69 | |
sk398 | 7:2973bf297f3d | 70 | // Global parameter storing the most up to date value of the return from Task 4 |
sk398 | 7:2973bf297f3d | 71 | volatile float task4AnalogChannels[2]; |
sk398 | 7:2973bf297f3d | 72 | |
sk398 | 7:2973bf297f3d | 73 | // Global parameter storing the most up to date value of the return from Task 6 |
sk398 | 7:2973bf297f3d | 74 | volatile int task6ErrorState; |
sk398 | 7:2973bf297f3d | 75 | |
sk398 | 7:2973bf297f3d | 76 | // Char array to store the concatenated string for output onto the SD Card |
sk398 | 7:2973bf297f3d | 77 | char logData[50]; |
sk398 | 7:2973bf297f3d | 78 | |
sk398 | 7:2973bf297f3d | 79 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 80 | // Cyclic Executive Function Prototypes |
sk398 | 7:2973bf297f3d | 81 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 82 | void CyclicExec(); |
sk398 | 7:2973bf297f3d | 83 | |
sk398 | 7:2973bf297f3d | 84 | // ============================================================================ |
sk398 | 7:2973bf297f3d | 85 | // Main Execution Program |
sk398 | 7:2973bf297f3d | 86 | // ============================================================================ |
sk398 | 0:5989ac10c4d3 | 87 | int main() { |
sk398 | 10:c0531edf4850 | 88 | |
sk398 | 7:2973bf297f3d | 89 | // Attempt to open SD file |
sk398 | 7:2973bf297f3d | 90 | // If open failed, do not run Cyclic Exec |
sk398 | 7:2973bf297f3d | 91 | if(!task7.openFile("/SD/A2/test.csv","a")) |
sk398 | 7:2973bf297f3d | 92 | { |
sk398 | 7:2973bf297f3d | 93 | // Start Cyclic Executive |
sk398 | 7:2973bf297f3d | 94 | CyclicTicker.attach(&CyclicExec,0.025); // 25ms pulses |
sk398 | 7:2973bf297f3d | 95 | |
sk398 | 7:2973bf297f3d | 96 | // Keep program running until RESET |
sk398 | 7:2973bf297f3d | 97 | while(1) |
sk398 | 7:2973bf297f3d | 98 | { |
sk398 | 7:2973bf297f3d | 99 | } |
sk398 | 7:2973bf297f3d | 100 | } |
sk398 | 4:b85bc0d810e1 | 101 | |
sk398 | 7:2973bf297f3d | 102 | // If FIle is not opened, prompt user and show Error on LED |
sk398 | 6:ceda53939eb8 | 103 | else |
sk398 | 6:ceda53939eb8 | 104 | { |
sk398 | 7:2973bf297f3d | 105 | // Prompt user about error |
sk398 | 7:2973bf297f3d | 106 | printf("File not opened\r\nNot executing Cyclic Executive"); |
sk398 | 7:2973bf297f3d | 107 | |
sk398 | 7:2973bf297f3d | 108 | // Execute error code on LED |
sk398 | 7:2973bf297f3d | 109 | while(1) |
sk398 | 7:2973bf297f3d | 110 | { |
sk398 | 7:2973bf297f3d | 111 | ErrorLED = 1; |
sk398 | 7:2973bf297f3d | 112 | wait(1); |
sk398 | 7:2973bf297f3d | 113 | ErrorLED = 0; |
sk398 | 7:2973bf297f3d | 114 | wait(1); |
sk398 | 7:2973bf297f3d | 115 | } |
sk398 | 7:2973bf297f3d | 116 | } |
sk398 | 7:2973bf297f3d | 117 | } |
sk398 | 7:2973bf297f3d | 118 | |
sk398 | 7:2973bf297f3d | 119 | #define TASK1_TICKS 40 |
sk398 | 7:2973bf297f3d | 120 | #define TASK2_TICKS 12 |
sk398 | 7:2973bf297f3d | 121 | #define TASK3_TICKS 12 |
sk398 | 7:2973bf297f3d | 122 | #define TASK4_TICKS 16 |
sk398 | 7:2973bf297f3d | 123 | #define TASK5_TICKS 80 |
sk398 | 7:2973bf297f3d | 124 | #define TASK6_TICKS 32 |
sk398 | 7:2973bf297f3d | 125 | #define TASK7_TICKS 200 |
xouf2114 | 14:f11c30a93736 | 126 | #define TASK8_TICKS 100 |
sk398 | 7:2973bf297f3d | 127 | |
sk398 | 7:2973bf297f3d | 128 | void CyclicExec() |
sk398 | 7:2973bf297f3d | 129 | { |
sk398 | 10:c0531edf4850 | 130 | // When called, increment cyclicTicks |
sk398 | 7:2973bf297f3d | 131 | cyclicTicks++; |
sk398 | 10:c0531edf4850 | 132 | |
sk398 | 10:c0531edf4850 | 133 | // Run every 1 second (should be 40 ticks, but tuned to 38 through testing) |
sk398 | 10:c0531edf4850 | 134 | if(cyclicTicks % 38 == 0) |
xouf2114 | 13:4b595e5d443f | 135 | { |
sk398 | 10:c0531edf4850 | 136 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 137 | task1t.stop(); |
sk398 | 10:c0531edf4850 | 138 | printf("T1 %d\r\n",task1t.read_ms()); |
sk398 | 10:c0531edf4850 | 139 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 140 | |
sk398 | 10:c0531edf4850 | 141 | // Run Task1 |
sk398 | 10:c0531edf4850 | 142 | LenPin = 1; |
sk398 | 10:c0531edf4850 | 143 | task1Frequency = task1.ReadFrequency(); |
sk398 | 10:c0531edf4850 | 144 | LenPin = 0; |
sk398 | 10:c0531edf4850 | 145 | |
sk398 | 10:c0531edf4850 | 146 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 147 | task1t.reset(); |
sk398 | 10:c0531edf4850 | 148 | task1t.start(); |
sk398 | 10:c0531edf4850 | 149 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 150 | } |
sk398 | 10:c0531edf4850 | 151 | |
sk398 | 10:c0531edf4850 | 152 | // Run every 300ms (should be 12 ticks, but logic dictates double the frequency) |
sk398 | 10:c0531edf4850 | 153 | if(cyclicTicks % 6 == 0) |
sk398 | 10:c0531edf4850 | 154 | { |
sk398 | 10:c0531edf4850 | 155 | // If flag taskNum is assigned to run Task2 |
sk398 | 10:c0531edf4850 | 156 | if(taskNum == 2) |
sk398 | 10:c0531edf4850 | 157 | { |
sk398 | 10:c0531edf4850 | 158 | |
sk398 | 10:c0531edf4850 | 159 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 160 | task2t.stop(); |
sk398 | 10:c0531edf4850 | 161 | printf("T2 %d\r\n",task2t.read_ms()); |
sk398 | 10:c0531edf4850 | 162 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 163 | |
sk398 | 10:c0531edf4850 | 164 | // Run Task 2 |
sk398 | 10:c0531edf4850 | 165 | task2SwitchState = task2_switch1.digitalInState(); |
sk398 | 10:c0531edf4850 | 166 | |
sk398 | 10:c0531edf4850 | 167 | // Set flag to run Task 3 on next iteration |
sk398 | 10:c0531edf4850 | 168 | taskNum = 3; |
sk398 | 10:c0531edf4850 | 169 | |
sk398 | 10:c0531edf4850 | 170 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 171 | task2t.reset(); |
sk398 | 10:c0531edf4850 | 172 | task2t.start(); |
sk398 | 10:c0531edf4850 | 173 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 174 | } |
sk398 | 10:c0531edf4850 | 175 | |
sk398 | 10:c0531edf4850 | 176 | // If flag taskNum is assigned to run Task3 |
sk398 | 10:c0531edf4850 | 177 | else if(taskNum == 3) |
sk398 | 10:c0531edf4850 | 178 | { |
sk398 | 10:c0531edf4850 | 179 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 180 | task3t.stop(); |
sk398 | 10:c0531edf4850 | 181 | printf("T3 %d\r\n",task3t.read_ms()); |
sk398 | 10:c0531edf4850 | 182 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 183 | |
sk398 | 10:c0531edf4850 | 184 | |
sk398 | 10:c0531edf4850 | 185 | // Run Task3 |
sk398 | 10:c0531edf4850 | 186 | task3.OutputWatchdogPulse(); |
sk398 | 10:c0531edf4850 | 187 | |
sk398 | 10:c0531edf4850 | 188 | // Set flag to run Task2 on next iteration |
sk398 | 10:c0531edf4850 | 189 | taskNum = 2; |
sk398 | 10:c0531edf4850 | 190 | |
sk398 | 10:c0531edf4850 | 191 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 192 | task3t.reset(); |
sk398 | 10:c0531edf4850 | 193 | task3t.start(); |
sk398 | 10:c0531edf4850 | 194 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 195 | } |
sk398 | 10:c0531edf4850 | 196 | } |
sk398 | 10:c0531edf4850 | 197 | |
sk398 | 10:c0531edf4850 | 198 | // Run every 400ms (16 ticks) |
sk398 | 10:c0531edf4850 | 199 | if(cyclicTicks % 16 == 0) |
sk398 | 10:c0531edf4850 | 200 | { |
sk398 | 10:c0531edf4850 | 201 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 202 | task4t.stop(); |
sk398 | 10:c0531edf4850 | 203 | printf("T4 %d\r\n",task4t.read_ms()); |
sk398 | 10:c0531edf4850 | 204 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 205 | |
sk398 | 10:c0531edf4850 | 206 | // Run Task4 |
sk398 | 10:c0531edf4850 | 207 | float *analogReading = task4.returnAnalogReadings(); |
sk398 | 10:c0531edf4850 | 208 | task4AnalogChannels[0] = *(analogReading); |
sk398 | 10:c0531edf4850 | 209 | task4AnalogChannels[1]= *(analogReading+1); |
sk398 | 10:c0531edf4850 | 210 | |
sk398 | 10:c0531edf4850 | 211 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 212 | task4t.reset(); |
sk398 | 10:c0531edf4850 | 213 | task4t.start(); |
sk398 | 10:c0531edf4850 | 214 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 215 | } |
sk398 | 10:c0531edf4850 | 216 | |
sk398 | 10:c0531edf4850 | 217 | // Run every 2 seconds (should be 80 ticks, but tuned to 84 through testing) |
sk398 | 10:c0531edf4850 | 218 | if(cyclicTicks % 84 == 0) |
sk398 | 10:c0531edf4850 | 219 | { |
sk398 | 10:c0531edf4850 | 220 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 221 | task5t.stop(); |
sk398 | 10:c0531edf4850 | 222 | printf("T5 %1.2f\r\n",task5t.read()); |
sk398 | 10:c0531edf4850 | 223 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 224 | |
sk398 | 10:c0531edf4850 | 225 | // Run Task5 |
sk398 | 10:c0531edf4850 | 226 | task5.updateDisplay( task1Frequency, |
sk398 | 10:c0531edf4850 | 227 | task2SwitchState, |
sk398 | 10:c0531edf4850 | 228 | task6ErrorState, |
sk398 | 10:c0531edf4850 | 229 | task4AnalogChannels[0], |
sk398 | 10:c0531edf4850 | 230 | task4AnalogChannels[1] ); |
sk398 | 10:c0531edf4850 | 231 | |
sk398 | 10:c0531edf4850 | 232 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 233 | task5t.reset(); |
sk398 | 10:c0531edf4850 | 234 | task5t.start(); |
sk398 | 10:c0531edf4850 | 235 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 236 | } |
sk398 | 10:c0531edf4850 | 237 | |
sk398 | 10:c0531edf4850 | 238 | // Run every 800ms (32 ticks) |
sk398 | 10:c0531edf4850 | 239 | if(cyclicTicks % 32 == 0) |
sk398 | 10:c0531edf4850 | 240 | { |
sk398 | 10:c0531edf4850 | 241 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 242 | task6t.stop(); |
sk398 | 10:c0531edf4850 | 243 | printf("T6 %d\r\n",task6t.read_ms()); |
sk398 | 10:c0531edf4850 | 244 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 245 | |
sk398 | 10:c0531edf4850 | 246 | // Run Task6 |
sk398 | 10:c0531edf4850 | 247 | task6ErrorState = task6.updateErrorCode( task2SwitchState, |
sk398 | 10:c0531edf4850 | 248 | task4AnalogChannels[0], |
sk398 | 10:c0531edf4850 | 249 | task4AnalogChannels[1] ); |
sk398 | 10:c0531edf4850 | 250 | |
sk398 | 10:c0531edf4850 | 251 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 252 | task6t.reset(); |
sk398 | 10:c0531edf4850 | 253 | task6t.start(); |
sk398 | 10:c0531edf4850 | 254 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 255 | } |
sk398 | 10:c0531edf4850 | 256 | |
sk398 | 10:c0531edf4850 | 257 | // Run every 5 seconds (200 ticks) |
sk398 | 7:2973bf297f3d | 258 | if(cyclicTicks % 200 == 0) |
sk398 | 7:2973bf297f3d | 259 | { |
sk398 | 10:c0531edf4850 | 260 | // ---------- Can be removed --------- |
sk398 | 10:c0531edf4850 | 261 | printf("T7\r\n"); |
sk398 | 10:c0531edf4850 | 262 | // ----------------------------------- |
sk398 | 10:c0531edf4850 | 263 | |
sk398 | 10:c0531edf4850 | 264 | // Run Task7 |
sk398 | 7:2973bf297f3d | 265 | stampTime.stop(); |
sk398 | 7:2973bf297f3d | 266 | int a = sprintf( logData,"Time=%1.2f,Freq=%d,SW1=%d,A1=%1.3f,A2=%1.3f\n", |
sk398 | 7:2973bf297f3d | 267 | stampTime.read(), |
sk398 | 7:2973bf297f3d | 268 | task1Frequency, |
sk398 | 7:2973bf297f3d | 269 | task2SwitchState, |
sk398 | 7:2973bf297f3d | 270 | task4AnalogChannels[0], |
sk398 | 7:2973bf297f3d | 271 | task4AnalogChannels[1] ); |
sk398 | 7:2973bf297f3d | 272 | task7.writeData(logData); |
sk398 | 10:c0531edf4850 | 273 | |
sk398 | 10:c0531edf4850 | 274 | // ---------- Can be removed --------- |
sk398 | 7:2973bf297f3d | 275 | stampTime.reset(); |
sk398 | 7:2973bf297f3d | 276 | stampTime.start(); |
sk398 | 10:c0531edf4850 | 277 | // ----------------------------------- |
sk398 | 7:2973bf297f3d | 278 | } |
sk398 | 7:2973bf297f3d | 279 | |
sk398 | 10:c0531edf4850 | 280 | // If SDRemoval Input is high, close FILE and detach the Ticker |
sk398 | 7:2973bf297f3d | 281 | if(SDRemoval == HIGH) |
sk398 | 7:2973bf297f3d | 282 | { |
sk398 | 7:2973bf297f3d | 283 | printf("SD Removed"); |
sk398 | 7:2973bf297f3d | 284 | task7.closeFile(); |
sk398 | 10:c0531edf4850 | 285 | CyclicTicker.detach(); |
sk398 | 7:2973bf297f3d | 286 | } |
sk398 | 7:2973bf297f3d | 287 | } |
sk398 | 7:2973bf297f3d | 288 |