Watchdog_Step-3_Edwin_Kadavy
Fork of Watchdog_sample_nocoverage by
main.cpp@6:d93fa1c57fd2, 2018-03-09 (annotated)
- Committer:
- edwinkad
- Date:
- Fri Mar 09 23:18:31 2018 +0000
- Revision:
- 6:d93fa1c57fd2
- Parent:
- 3:32a940251192
Edwin Kadavy
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Manel_Marin | 0:5ce3cfc57999 | 1 | #include "mbed.h" |
WilliamMarshQMUL | 3:32a940251192 | 2 | #include "rtos.h" |
WilliamMarshQMUL | 1:159a09ac60ba | 3 | #include "wdt.h" |
Manel_Marin | 0:5ce3cfc57999 | 4 | |
WilliamMarshQMUL | 2:c31a1758ac38 | 5 | // Sample program using the Watchdog |
WilliamMarshQMUL | 2:c31a1758ac38 | 6 | // --------------------------------- |
WilliamMarshQMUL | 3:32a940251192 | 7 | // * Three threads co-operate to flash two LEDs |
edwinkad | 6:d93fa1c57fd2 | 8 | // * A simple way to inject a fault, by pressing a button |
WilliamMarshQMUL | 3:32a940251192 | 9 | // * The watchdog is configured with a 32ms timeout |
WilliamMarshQMUL | 3:32a940251192 | 10 | |
WilliamMarshQMUL | 3:32a940251192 | 11 | #define ON 1 |
WilliamMarshQMUL | 3:32a940251192 | 12 | #define OFF 0 |
WilliamMarshQMUL | 3:32a940251192 | 13 | DigitalOut led_red(LED_RED, ON); |
edwinkad | 6:d93fa1c57fd2 | 14 | DigitalOut led_blue(LED_BLUE, ON); |
edwinkad | 6:d93fa1c57fd2 | 15 | DigitalOut led_green(LED_GREEN, ON); |
WilliamMarshQMUL | 3:32a940251192 | 16 | DigitalIn button(PTD0, PullUp); |
WilliamMarshQMUL | 3:32a940251192 | 17 | DigitalOut led1(PTC12, OFF); |
WilliamMarshQMUL | 3:32a940251192 | 18 | DigitalOut led2(PTC13, OFF); |
edwinkad | 6:d93fa1c57fd2 | 19 | AnalogIn ain1(A0) ; // Analog input 1 |
edwinkad | 6:d93fa1c57fd2 | 20 | AnalogIn ain2(A1) ; // Analog input 2 |
WilliamMarshQMUL | 3:32a940251192 | 21 | |
WilliamMarshQMUL | 3:32a940251192 | 22 | // This ticker is used to feed the watch dog |
edwinkad | 6:d93fa1c57fd2 | 23 | Ticker tick1, tick2; |
WilliamMarshQMUL | 3:32a940251192 | 24 | |
WilliamMarshQMUL | 3:32a940251192 | 25 | // Threads |
edwinkad | 6:d93fa1c57fd2 | 26 | Thread threadT ; // timer thread |
WilliamMarshQMUL | 3:32a940251192 | 27 | Thread threadLED1 ; // thread LED1 |
WilliamMarshQMUL | 3:32a940251192 | 28 | Thread threadLED2 ; // thread LED2 |
WilliamMarshQMUL | 3:32a940251192 | 29 | |
edwinkad | 6:d93fa1c57fd2 | 30 | |
edwinkad | 6:d93fa1c57fd2 | 31 | //Detection of hardware failure |
edwinkad | 6:d93fa1c57fd2 | 32 | |
edwinkad | 6:d93fa1c57fd2 | 33 | volatile int volts1 = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 34 | volatile int volts2 = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 35 | volatile int state=0 ; |
edwinkad | 6:d93fa1c57fd2 | 36 | |
edwinkad | 6:d93fa1c57fd2 | 37 | Serial pc(USBTX, USBRX); // tx, rx, for debugging |
edwinkad | 6:d93fa1c57fd2 | 38 | |
edwinkad | 6:d93fa1c57fd2 | 39 | // Message type1 |
edwinkad | 6:d93fa1c57fd2 | 40 | typedef struct { |
edwinkad | 6:d93fa1c57fd2 | 41 | uint16_t analog; /* Analog input value */ |
edwinkad | 6:d93fa1c57fd2 | 42 | } message_t; |
edwinkad | 6:d93fa1c57fd2 | 43 | |
edwinkad | 6:d93fa1c57fd2 | 44 | // Mail box |
edwinkad | 6:d93fa1c57fd2 | 45 | Mail<message_t, 2> mailbox; |
edwinkad | 6:d93fa1c57fd2 | 46 | |
edwinkad | 6:d93fa1c57fd2 | 47 | // Function called every 10ms to read ADC |
edwinkad | 6:d93fa1c57fd2 | 48 | // Low pass filter |
edwinkad | 6:d93fa1c57fd2 | 49 | // Every 10th value is sent to mailbox |
edwinkad | 6:d93fa1c57fd2 | 50 | volatile int samples = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 51 | volatile uint16_t smoothed = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 52 | void readA0() |
edwinkad | 6:d93fa1c57fd2 | 53 | { |
edwinkad | 6:d93fa1c57fd2 | 54 | smoothed = (smoothed >> 1) + (ain1.read_u16() >> 1) ; |
edwinkad | 6:d93fa1c57fd2 | 55 | samples++ ; |
edwinkad | 6:d93fa1c57fd2 | 56 | if (samples == 10) { |
edwinkad | 6:d93fa1c57fd2 | 57 | // send to thread |
edwinkad | 6:d93fa1c57fd2 | 58 | message_t *mess = mailbox.alloc() ; // may fail but does not block |
edwinkad | 6:d93fa1c57fd2 | 59 | if (mess) { |
edwinkad | 6:d93fa1c57fd2 | 60 | mess->analog = smoothed ; |
edwinkad | 6:d93fa1c57fd2 | 61 | mailbox.put(mess); // fails but does not block if full |
edwinkad | 6:d93fa1c57fd2 | 62 | } |
edwinkad | 6:d93fa1c57fd2 | 63 | samples = 0; |
edwinkad | 6:d93fa1c57fd2 | 64 | } |
edwinkad | 6:d93fa1c57fd2 | 65 | } |
edwinkad | 6:d93fa1c57fd2 | 66 | |
edwinkad | 6:d93fa1c57fd2 | 67 | // Message type2 |
edwinkad | 6:d93fa1c57fd2 | 68 | typedef struct { |
edwinkad | 6:d93fa1c57fd2 | 69 | uint16_t analog2; /* Analog input value */ |
edwinkad | 6:d93fa1c57fd2 | 70 | } message_t2; |
edwinkad | 6:d93fa1c57fd2 | 71 | |
edwinkad | 6:d93fa1c57fd2 | 72 | // Mail box |
edwinkad | 6:d93fa1c57fd2 | 73 | Mail<message_t2, 2> mailbox2; |
edwinkad | 6:d93fa1c57fd2 | 74 | |
edwinkad | 6:d93fa1c57fd2 | 75 | volatile int samples2 = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 76 | volatile uint16_t smoothed2 = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 77 | void readA1() |
edwinkad | 6:d93fa1c57fd2 | 78 | { |
edwinkad | 6:d93fa1c57fd2 | 79 | smoothed2 = (smoothed2 >> 1) + (ain2.read_u16() >> 1) ; |
edwinkad | 6:d93fa1c57fd2 | 80 | samples2++ ; |
edwinkad | 6:d93fa1c57fd2 | 81 | if (samples2 == 10) { |
edwinkad | 6:d93fa1c57fd2 | 82 | // send to thread |
edwinkad | 6:d93fa1c57fd2 | 83 | message_t2 *mess = mailbox2.alloc() ; // may fail but does not block |
edwinkad | 6:d93fa1c57fd2 | 84 | if (mess) { |
edwinkad | 6:d93fa1c57fd2 | 85 | mess->analog2 = smoothed2 ; |
edwinkad | 6:d93fa1c57fd2 | 86 | mailbox2.put(mess); // fails but does not block if full |
edwinkad | 6:d93fa1c57fd2 | 87 | } |
edwinkad | 6:d93fa1c57fd2 | 88 | samples2 = 0; |
edwinkad | 6:d93fa1c57fd2 | 89 | } |
edwinkad | 6:d93fa1c57fd2 | 90 | } |
edwinkad | 6:d93fa1c57fd2 | 91 | |
edwinkad | 6:d93fa1c57fd2 | 92 | // Write voltage digits |
edwinkad | 6:d93fa1c57fd2 | 93 | // v Voltage as scale int, e.g. 3.30 is 330 |
edwinkad | 6:d93fa1c57fd2 | 94 | void vToString(int v, char* s) |
edwinkad | 6:d93fa1c57fd2 | 95 | { |
edwinkad | 6:d93fa1c57fd2 | 96 | s[3] = '0' + (v % 10) ; |
edwinkad | 6:d93fa1c57fd2 | 97 | v = v / 10 ; |
edwinkad | 6:d93fa1c57fd2 | 98 | s[2] = '0' + (v % 10) ; |
edwinkad | 6:d93fa1c57fd2 | 99 | v = v / 10 ; |
edwinkad | 6:d93fa1c57fd2 | 100 | s[0] = '0' + (v % 10) ; |
edwinkad | 6:d93fa1c57fd2 | 101 | } |
edwinkad | 6:d93fa1c57fd2 | 102 | |
edwinkad | 6:d93fa1c57fd2 | 103 | |
edwinkad | 6:d93fa1c57fd2 | 104 | |
WilliamMarshQMUL | 3:32a940251192 | 105 | // ------------Fault Injection Button------------- |
WilliamMarshQMUL | 3:32a940251192 | 106 | // Wait while the button is down |
WilliamMarshQMUL | 3:32a940251192 | 107 | // Use this to simulate a STUCK fault |
WilliamMarshQMUL | 3:32a940251192 | 108 | // ----------------------------------------------- |
edwinkad | 6:d93fa1c57fd2 | 109 | void waitButton() |
edwinkad | 6:d93fa1c57fd2 | 110 | { |
edwinkad | 6:d93fa1c57fd2 | 111 | while (!button) ; |
WilliamMarshQMUL | 3:32a940251192 | 112 | } |
WilliamMarshQMUL | 2:c31a1758ac38 | 113 | |
WilliamMarshQMUL | 3:32a940251192 | 114 | // ---Thread for controlling LED 1---------------- |
edwinkad | 6:d93fa1c57fd2 | 115 | // Turn LED1 on/off in response to signals |
WilliamMarshQMUL | 3:32a940251192 | 116 | // ----------------------------------------------- |
edwinkad | 6:d93fa1c57fd2 | 117 | void led1_thread() // method to run in thread |
edwinkad | 6:d93fa1c57fd2 | 118 | { |
WilliamMarshQMUL | 3:32a940251192 | 119 | osEvent evt ; |
WilliamMarshQMUL | 3:32a940251192 | 120 | while (true) { |
edwinkad | 6:d93fa1c57fd2 | 121 | wdt_kickA(); // first part |
WilliamMarshQMUL | 3:32a940251192 | 122 | evt = Thread::signal_wait(0x0); // wait for any signal |
WilliamMarshQMUL | 3:32a940251192 | 123 | if (evt.status == osEventSignal) { |
WilliamMarshQMUL | 3:32a940251192 | 124 | if (evt.value.signals & 0x01) led1 = ON ; |
WilliamMarshQMUL | 3:32a940251192 | 125 | if (evt.value.signals & 0x02) led1 = OFF ; |
edwinkad | 6:d93fa1c57fd2 | 126 | } |
edwinkad | 6:d93fa1c57fd2 | 127 | //waitButton() ; // POSSIBLE FAULT HERE |
WilliamMarshQMUL | 3:32a940251192 | 128 | } |
WilliamMarshQMUL | 3:32a940251192 | 129 | } |
Manel_Marin | 0:5ce3cfc57999 | 130 | |
WilliamMarshQMUL | 3:32a940251192 | 131 | // ---Thread for controlling LED 2---------------- |
edwinkad | 6:d93fa1c57fd2 | 132 | // Turn LED2 on/off in response to signals |
WilliamMarshQMUL | 3:32a940251192 | 133 | // ----------------------------------------------- |
edwinkad | 6:d93fa1c57fd2 | 134 | void led2_thread() // method to run in thread |
edwinkad | 6:d93fa1c57fd2 | 135 | { |
WilliamMarshQMUL | 3:32a940251192 | 136 | osEvent evt ; |
WilliamMarshQMUL | 3:32a940251192 | 137 | while (true) { |
edwinkad | 6:d93fa1c57fd2 | 138 | wdt_kickB(); // second part |
WilliamMarshQMUL | 3:32a940251192 | 139 | evt = Thread::signal_wait(0x0); // wait for any signal |
WilliamMarshQMUL | 3:32a940251192 | 140 | if (evt.status == osEventSignal) { |
WilliamMarshQMUL | 3:32a940251192 | 141 | if (evt.value.signals & 0x01) led2 = ON ; |
WilliamMarshQMUL | 3:32a940251192 | 142 | if (evt.value.signals & 0x02) led2 = OFF ; |
edwinkad | 6:d93fa1c57fd2 | 143 | } |
edwinkad | 6:d93fa1c57fd2 | 144 | waitButton() ; // POSSIBLE FAULT HERE |
WilliamMarshQMUL | 3:32a940251192 | 145 | } |
WilliamMarshQMUL | 3:32a940251192 | 146 | } |
Manel_Marin | 0:5ce3cfc57999 | 147 | |
WilliamMarshQMUL | 3:32a940251192 | 148 | // ---Thread for timing -------------------------- |
WilliamMarshQMUL | 3:32a940251192 | 149 | // Send signals to the other threads |
WilliamMarshQMUL | 3:32a940251192 | 150 | // ----------------------------------------------- |
edwinkad | 6:d93fa1c57fd2 | 151 | void timer_thread() // method to run in thread |
edwinkad | 6:d93fa1c57fd2 | 152 | { |
WilliamMarshQMUL | 3:32a940251192 | 153 | while (true) { |
WilliamMarshQMUL | 3:32a940251192 | 154 | Thread::wait(250) ; |
edwinkad | 6:d93fa1c57fd2 | 155 | |
WilliamMarshQMUL | 3:32a940251192 | 156 | threadLED1.signal_set(0x1) ; |
WilliamMarshQMUL | 3:32a940251192 | 157 | threadLED2.signal_set(0x1) ; |
WilliamMarshQMUL | 3:32a940251192 | 158 | Thread::wait(250) ; |
WilliamMarshQMUL | 3:32a940251192 | 159 | threadLED1.signal_set(0x2) ; |
WilliamMarshQMUL | 3:32a940251192 | 160 | threadLED2.signal_set(0x2) ; |
WilliamMarshQMUL | 3:32a940251192 | 161 | // waitButton() ; // POSSIBLE FAULT HERE |
WilliamMarshQMUL | 3:32a940251192 | 162 | } |
WilliamMarshQMUL | 3:32a940251192 | 163 | } |
WilliamMarshQMUL | 3:32a940251192 | 164 | |
edwinkad | 6:d93fa1c57fd2 | 165 | void detection(int volts) |
edwinkad | 6:d93fa1c57fd2 | 166 | { |
edwinkad | 6:d93fa1c57fd2 | 167 | if(volts==0 ||state==1) { |
edwinkad | 6:d93fa1c57fd2 | 168 | led_blue= OFF; |
edwinkad | 6:d93fa1c57fd2 | 169 | state=1; |
edwinkad | 6:d93fa1c57fd2 | 170 | } else if(volts>=300||state==2) { |
edwinkad | 6:d93fa1c57fd2 | 171 | led_green= OFF; |
edwinkad | 6:d93fa1c57fd2 | 172 | state=2; |
edwinkad | 6:d93fa1c57fd2 | 173 | } |
edwinkad | 6:d93fa1c57fd2 | 174 | } |
edwinkad | 6:d93fa1c57fd2 | 175 | |
WilliamMarshQMUL | 3:32a940251192 | 176 | // -----------MAIN------------------------------- |
edwinkad | 6:d93fa1c57fd2 | 177 | // Configure watchdog. Start threads. |
WilliamMarshQMUL | 3:32a940251192 | 178 | // Show start up with RED for 1sec |
WilliamMarshQMUL | 3:32a940251192 | 179 | // Remember the watchdog is running |
WilliamMarshQMUL | 3:32a940251192 | 180 | // - 1024ms to set it once |
edwinkad | 6:d93fa1c57fd2 | 181 | // - then must feed it every 32ms |
WilliamMarshQMUL | 3:32a940251192 | 182 | // ---------------------------------------------- |
Manel_Marin | 0:5ce3cfc57999 | 183 | |
edwinkad | 6:d93fa1c57fd2 | 184 | |
edwinkad | 6:d93fa1c57fd2 | 185 | |
edwinkad | 6:d93fa1c57fd2 | 186 | int main(void) |
edwinkad | 6:d93fa1c57fd2 | 187 | { |
edwinkad | 6:d93fa1c57fd2 | 188 | wdt_256ms() ; // initialise watchdog - 32ms timeout |
edwinkad | 6:d93fa1c57fd2 | 189 | //wdt_kick_all; |
edwinkad | 6:d93fa1c57fd2 | 190 | //tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms |
edwinkad | 6:d93fa1c57fd2 | 191 | |
WilliamMarshQMUL | 3:32a940251192 | 192 | // start threads |
edwinkad | 6:d93fa1c57fd2 | 193 | threadT.start(&timer_thread) ; // start the timer thread |
edwinkad | 6:d93fa1c57fd2 | 194 | threadLED1.start(&led1_thread) ; // start the LED1 control thread |
edwinkad | 6:d93fa1c57fd2 | 195 | threadLED2.start(&led2_thread) ; // start the LED2 control thread |
edwinkad | 6:d93fa1c57fd2 | 196 | |
edwinkad | 6:d93fa1c57fd2 | 197 | |
WilliamMarshQMUL | 1:159a09ac60ba | 198 | // show start-up |
WilliamMarshQMUL | 3:32a940251192 | 199 | led_red = OFF; |
WilliamMarshQMUL | 3:32a940251192 | 200 | Thread::wait(1000) ; |
WilliamMarshQMUL | 3:32a940251192 | 201 | led_red = ON; |
edwinkad | 6:d93fa1c57fd2 | 202 | |
edwinkad | 6:d93fa1c57fd2 | 203 | //hardware failure detection |
edwinkad | 6:d93fa1c57fd2 | 204 | int counter = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 205 | char vstring1[] = "X.XX\r\n" ; |
edwinkad | 6:d93fa1c57fd2 | 206 | char vstring2[] = "X.XX\r\n" ; |
edwinkad | 6:d93fa1c57fd2 | 207 | |
edwinkad | 6:d93fa1c57fd2 | 208 | tick1.attach_us(callback(&readA0), 10000); // ticks every 10ms |
edwinkad | 6:d93fa1c57fd2 | 209 | tick2.attach_us(callback(&readA1), 10000); // ticks every 10ms |
edwinkad | 6:d93fa1c57fd2 | 210 | while (true) { |
edwinkad | 6:d93fa1c57fd2 | 211 | osEvent evt = mailbox.get(); // wait for mail |
edwinkad | 6:d93fa1c57fd2 | 212 | if (evt.status == osEventMail) { |
edwinkad | 6:d93fa1c57fd2 | 213 | message_t* mess = (message_t*)evt.value.p ; |
edwinkad | 6:d93fa1c57fd2 | 214 | volts1 = (mess->analog * 330) / 0xffff ; |
edwinkad | 6:d93fa1c57fd2 | 215 | |
edwinkad | 6:d93fa1c57fd2 | 216 | mailbox.free(mess) ; // free the message space |
edwinkad | 6:d93fa1c57fd2 | 217 | } |
edwinkad | 6:d93fa1c57fd2 | 218 | |
edwinkad | 6:d93fa1c57fd2 | 219 | osEvent evt2 = mailbox2.get(); // wait for mail |
edwinkad | 6:d93fa1c57fd2 | 220 | if (evt2.status == osEventMail) { |
edwinkad | 6:d93fa1c57fd2 | 221 | message_t2* mess = (message_t2*)evt2.value.p ; |
edwinkad | 6:d93fa1c57fd2 | 222 | volts2 = (mess->analog2 * 330) / 0xffff ; |
edwinkad | 6:d93fa1c57fd2 | 223 | mailbox2.free(mess) ; // free the message space |
edwinkad | 6:d93fa1c57fd2 | 224 | } |
edwinkad | 6:d93fa1c57fd2 | 225 | |
edwinkad | 6:d93fa1c57fd2 | 226 | counter++ ; |
edwinkad | 6:d93fa1c57fd2 | 227 | if (counter == 5) { // limit bandwidth of serial |
edwinkad | 6:d93fa1c57fd2 | 228 | detection(volts1); // hardware fault detecttion.(It is inside the counter which cause a small delay,... |
edwinkad | 6:d93fa1c57fd2 | 229 | detection(volts2); // putting it out side causes the first 0 value to be read showing an instant failure) |
edwinkad | 6:d93fa1c57fd2 | 230 | vToString(volts1, vstring1) ; |
edwinkad | 6:d93fa1c57fd2 | 231 | pc.printf("LED1 "); |
edwinkad | 6:d93fa1c57fd2 | 232 | pc.printf(vstring1) ; |
edwinkad | 6:d93fa1c57fd2 | 233 | vToString(volts2, vstring2) ; |
edwinkad | 6:d93fa1c57fd2 | 234 | pc.printf("LED2 "); |
edwinkad | 6:d93fa1c57fd2 | 235 | pc.printf(vstring2) ; |
edwinkad | 6:d93fa1c57fd2 | 236 | counter = 0 ; |
edwinkad | 6:d93fa1c57fd2 | 237 | } |
edwinkad | 6:d93fa1c57fd2 | 238 | } |
edwinkad | 6:d93fa1c57fd2 | 239 | |
Manel_Marin | 0:5ce3cfc57999 | 240 | } |