Added hardware failure detection to watchdog example.

Fork of Watchdog_sample_nocoverage by William Marsh

Committer:
natgovor
Date:
Fri Mar 09 15:45:02 2018 +0000
Revision:
6:6f93bce60d98
Parent:
3:32a940251192
Added hardware failure detection to watchdog example.

Who changed what in which revision?

UserRevisionLine numberNew 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
WilliamMarshQMUL 3:32a940251192 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);
WilliamMarshQMUL 3:32a940251192 14 DigitalIn button(PTD0, PullUp);
WilliamMarshQMUL 3:32a940251192 15 DigitalOut led1(PTC12, OFF);
WilliamMarshQMUL 3:32a940251192 16 DigitalOut led2(PTC13, OFF);
WilliamMarshQMUL 3:32a940251192 17
natgovor 6:6f93bce60d98 18 DigitalOut redLed(LED1);
natgovor 6:6f93bce60d98 19 DigitalOut greenLed(LED2);
natgovor 6:6f93bce60d98 20
natgovor 6:6f93bce60d98 21 // Analog inputs
natgovor 6:6f93bce60d98 22 AnalogIn ain1(A0);
natgovor 6:6f93bce60d98 23 AnalogIn ain2(A1);
natgovor 6:6f93bce60d98 24
natgovor 6:6f93bce60d98 25 Serial pc(USBTX, USBRX); // tx, rx, for debugging
natgovor 6:6f93bce60d98 26
WilliamMarshQMUL 3:32a940251192 27 // This ticker is used to feed the watch dog
natgovor 6:6f93bce60d98 28 Ticker tick1;
natgovor 6:6f93bce60d98 29 Ticker tick2;
WilliamMarshQMUL 3:32a940251192 30
WilliamMarshQMUL 3:32a940251192 31 // Threads
natgovor 6:6f93bce60d98 32 Thread threadT(osPriorityNormal, 1000); // timer thread
natgovor 6:6f93bce60d98 33 Thread threadLED1(osPriorityNormal, 1000); // thread LED1
natgovor 6:6f93bce60d98 34 Thread threadLED2(osPriorityNormal, 1000); // thread LED2
natgovor 6:6f93bce60d98 35 Thread threadCheckLED1(osPriorityNormal, 1000);
natgovor 6:6f93bce60d98 36 Thread threadCheckLED2(osPriorityNormal, 1000);
natgovor 6:6f93bce60d98 37
natgovor 6:6f93bce60d98 38 // Message type
natgovor 6:6f93bce60d98 39 typedef struct {
natgovor 6:6f93bce60d98 40 uint16_t analog; /* Analog input value */
natgovor 6:6f93bce60d98 41 bool buttonPressed;
natgovor 6:6f93bce60d98 42 } message_t;
natgovor 6:6f93bce60d98 43
natgovor 6:6f93bce60d98 44 // Mail box
natgovor 6:6f93bce60d98 45 Mail<message_t, 2> mailbox1;
natgovor 6:6f93bce60d98 46 Mail<message_t, 2> mailbox2;
natgovor 6:6f93bce60d98 47
natgovor 6:6f93bce60d98 48 volatile int samples1 = 0;
natgovor 6:6f93bce60d98 49 volatile uint16_t smoothed1 = 0;
natgovor 6:6f93bce60d98 50 void readA0() {
natgovor 6:6f93bce60d98 51 smoothed1 = (smoothed1 >> 1) + (ain1.read_u16() >> 1);
natgovor 6:6f93bce60d98 52 samples1++;
natgovor 6:6f93bce60d98 53 if (samples1 == 10) {
natgovor 6:6f93bce60d98 54 // send to thread
natgovor 6:6f93bce60d98 55 message_t *mess = mailbox1.alloc(); // may fail but does not block
natgovor 6:6f93bce60d98 56 if (mess) {
natgovor 6:6f93bce60d98 57 mess->analog = smoothed1;
natgovor 6:6f93bce60d98 58 mailbox1.put(mess); // fails but does not block if full
natgovor 6:6f93bce60d98 59 }
natgovor 6:6f93bce60d98 60 samples1 = 0;
natgovor 6:6f93bce60d98 61 }
natgovor 6:6f93bce60d98 62 }
natgovor 6:6f93bce60d98 63
natgovor 6:6f93bce60d98 64 volatile int samples2 = 0;
natgovor 6:6f93bce60d98 65 volatile uint16_t smoothed2 = 0;
natgovor 6:6f93bce60d98 66 void readA1() {
natgovor 6:6f93bce60d98 67 smoothed2 = (smoothed2 >> 1) + (ain2.read_u16() >> 1);
natgovor 6:6f93bce60d98 68 samples2++;
natgovor 6:6f93bce60d98 69 if (samples2 == 10) {
natgovor 6:6f93bce60d98 70 // send to thread
natgovor 6:6f93bce60d98 71 message_t *mess = mailbox2.alloc(); // may fail but does not block
natgovor 6:6f93bce60d98 72 if (mess) {
natgovor 6:6f93bce60d98 73 mess->analog = smoothed2;
natgovor 6:6f93bce60d98 74 mailbox2.put(mess); // fails but does not block if full
natgovor 6:6f93bce60d98 75 }
natgovor 6:6f93bce60d98 76 samples2 = 0;
natgovor 6:6f93bce60d98 77 }
natgovor 6:6f93bce60d98 78 }
natgovor 6:6f93bce60d98 79
natgovor 6:6f93bce60d98 80 // Write voltage digits
natgovor 6:6f93bce60d98 81 // v Voltage as scale int, e.g. 3.30 is 330
natgovor 6:6f93bce60d98 82 void vToString(int v, char* s) {
natgovor 6:6f93bce60d98 83 s[3] = '0' + (v % 10) ;
natgovor 6:6f93bce60d98 84 v = v / 10 ;
natgovor 6:6f93bce60d98 85 s[2] = '0' + (v % 10) ;
natgovor 6:6f93bce60d98 86 v = v / 10 ;
natgovor 6:6f93bce60d98 87 s[0] = '0' + (v % 10) ;
natgovor 6:6f93bce60d98 88 }
WilliamMarshQMUL 3:32a940251192 89
WilliamMarshQMUL 3:32a940251192 90 // ------------Fault Injection Button-------------
WilliamMarshQMUL 3:32a940251192 91 // Wait while the button is down
WilliamMarshQMUL 3:32a940251192 92 // Use this to simulate a STUCK fault
WilliamMarshQMUL 3:32a940251192 93 // -----------------------------------------------
WilliamMarshQMUL 3:32a940251192 94 void waitButton() {
WilliamMarshQMUL 3:32a940251192 95 while (!button) ;
WilliamMarshQMUL 3:32a940251192 96 }
WilliamMarshQMUL 2:c31a1758ac38 97
WilliamMarshQMUL 3:32a940251192 98 // ---Thread for controlling LED 1----------------
WilliamMarshQMUL 3:32a940251192 99 // Turn LED1 on/off in response to signals
WilliamMarshQMUL 3:32a940251192 100 // -----------------------------------------------
WilliamMarshQMUL 3:32a940251192 101 void led1_thread() { // method to run in thread
WilliamMarshQMUL 3:32a940251192 102 osEvent evt ;
WilliamMarshQMUL 3:32a940251192 103 while (true) {
WilliamMarshQMUL 3:32a940251192 104 evt = Thread::signal_wait(0x0); // wait for any signal
WilliamMarshQMUL 3:32a940251192 105 if (evt.status == osEventSignal) {
WilliamMarshQMUL 3:32a940251192 106 if (evt.value.signals & 0x01) led1 = ON ;
WilliamMarshQMUL 3:32a940251192 107 if (evt.value.signals & 0x02) led1 = OFF ;
natgovor 6:6f93bce60d98 108 wdt_kickA();
WilliamMarshQMUL 3:32a940251192 109 }
natgovor 6:6f93bce60d98 110 //waitButton() ; // POSSIBLE FAULT HERE
WilliamMarshQMUL 3:32a940251192 111 }
WilliamMarshQMUL 3:32a940251192 112 }
Manel_Marin 0:5ce3cfc57999 113
WilliamMarshQMUL 3:32a940251192 114 // ---Thread for controlling LED 2----------------
WilliamMarshQMUL 3:32a940251192 115 // Turn LED2 on/off in response to signals
WilliamMarshQMUL 3:32a940251192 116 // -----------------------------------------------
WilliamMarshQMUL 3:32a940251192 117 void led2_thread() { // method to run in thread
WilliamMarshQMUL 3:32a940251192 118 osEvent evt ;
WilliamMarshQMUL 3:32a940251192 119 while (true) {
WilliamMarshQMUL 3:32a940251192 120 evt = Thread::signal_wait(0x0); // wait for any signal
WilliamMarshQMUL 3:32a940251192 121 if (evt.status == osEventSignal) {
WilliamMarshQMUL 3:32a940251192 122 if (evt.value.signals & 0x01) led2 = ON ;
WilliamMarshQMUL 3:32a940251192 123 if (evt.value.signals & 0x02) led2 = OFF ;
natgovor 6:6f93bce60d98 124 wdt_kickB();
WilliamMarshQMUL 3:32a940251192 125 }
natgovor 6:6f93bce60d98 126 //waitButton() ; // POSSIBLE FAULT HERE
WilliamMarshQMUL 3:32a940251192 127 }
WilliamMarshQMUL 3:32a940251192 128 }
Manel_Marin 0:5ce3cfc57999 129
WilliamMarshQMUL 3:32a940251192 130 // ---Thread for timing --------------------------
WilliamMarshQMUL 3:32a940251192 131 // Send signals to the other threads
WilliamMarshQMUL 3:32a940251192 132 // -----------------------------------------------
WilliamMarshQMUL 3:32a940251192 133 void timer_thread() { // method to run in thread
WilliamMarshQMUL 3:32a940251192 134 while (true) {
WilliamMarshQMUL 3:32a940251192 135 Thread::wait(250) ;
WilliamMarshQMUL 3:32a940251192 136 threadLED1.signal_set(0x1) ;
WilliamMarshQMUL 3:32a940251192 137 threadLED2.signal_set(0x1) ;
WilliamMarshQMUL 3:32a940251192 138 Thread::wait(250) ;
WilliamMarshQMUL 3:32a940251192 139 threadLED1.signal_set(0x2) ;
WilliamMarshQMUL 3:32a940251192 140 threadLED2.signal_set(0x2) ;
natgovor 6:6f93bce60d98 141
natgovor 6:6f93bce60d98 142 waitButton() ; // POSSIBLE FAULT HERE
natgovor 6:6f93bce60d98 143 }
natgovor 6:6f93bce60d98 144 }
natgovor 6:6f93bce60d98 145
natgovor 6:6f93bce60d98 146 void check_led1() {
natgovor 6:6f93bce60d98 147 int volts = 0;
natgovor 6:6f93bce60d98 148 int counter = 0;
natgovor 6:6f93bce60d98 149 char vstring[] = "X.XX\r\n";
natgovor 6:6f93bce60d98 150
natgovor 6:6f93bce60d98 151 while (true) {
natgovor 6:6f93bce60d98 152 osEvent evt = mailbox1.get(); // wait for mail
natgovor 6:6f93bce60d98 153 if (evt.status == osEventMail) {
natgovor 6:6f93bce60d98 154 message_t* mess = (message_t*)evt.value.p;
natgovor 6:6f93bce60d98 155 volts = (mess->analog * 330) / 0xffff;
natgovor 6:6f93bce60d98 156 mailbox1.free(mess); // free the message space
natgovor 6:6f93bce60d98 157
natgovor 6:6f93bce60d98 158 if (led1 == 1) {
natgovor 6:6f93bce60d98 159 if (volts < 160 && volts > 140) {
natgovor 6:6f93bce60d98 160 // normal
natgovor 6:6f93bce60d98 161 } else if (volts == 0) {
natgovor 6:6f93bce60d98 162 // failed open circuit
natgovor 6:6f93bce60d98 163 pc.printf("Failed open circuit 1\n\r");
natgovor 6:6f93bce60d98 164 redLed = 0;
natgovor 6:6f93bce60d98 165 } else if (volts > 300) {
natgovor 6:6f93bce60d98 166 // failed short circuit
natgovor 6:6f93bce60d98 167 pc.printf("Failed short circuit 1\n\r");
natgovor 6:6f93bce60d98 168 greenLed = 0;
natgovor 6:6f93bce60d98 169 }
natgovor 6:6f93bce60d98 170 }
natgovor 6:6f93bce60d98 171
natgovor 6:6f93bce60d98 172 vToString(volts, vstring);
natgovor 6:6f93bce60d98 173 counter++;
natgovor 6:6f93bce60d98 174 if (counter == 10) { // limit bandwidth of serial
natgovor 6:6f93bce60d98 175 pc.printf(vstring);
natgovor 6:6f93bce60d98 176 counter = 0;
natgovor 6:6f93bce60d98 177 }
natgovor 6:6f93bce60d98 178 }
natgovor 6:6f93bce60d98 179 }
natgovor 6:6f93bce60d98 180 }
natgovor 6:6f93bce60d98 181
natgovor 6:6f93bce60d98 182 void check_led2() {
natgovor 6:6f93bce60d98 183 int volts = 0;
natgovor 6:6f93bce60d98 184 int counter = 0;
natgovor 6:6f93bce60d98 185 char vstring[] = "X.XX\r\n";
natgovor 6:6f93bce60d98 186
natgovor 6:6f93bce60d98 187 while (true) {
natgovor 6:6f93bce60d98 188 osEvent evt = mailbox2.get(); // wait for mail
natgovor 6:6f93bce60d98 189 if (evt.status == osEventMail) {
natgovor 6:6f93bce60d98 190 message_t* mess = (message_t*)evt.value.p;
natgovor 6:6f93bce60d98 191 volts = (mess->analog * 330) / 0xffff;
natgovor 6:6f93bce60d98 192 mailbox2.free(mess); // free the message space
natgovor 6:6f93bce60d98 193
natgovor 6:6f93bce60d98 194 if (led2 == 1) {
natgovor 6:6f93bce60d98 195 if (volts < 160 && volts > 140) {
natgovor 6:6f93bce60d98 196 // normal
natgovor 6:6f93bce60d98 197 } else if (volts == 0) {
natgovor 6:6f93bce60d98 198 // failed open circuit
natgovor 6:6f93bce60d98 199 pc.printf("Failed open circuit 2\n\r");
natgovor 6:6f93bce60d98 200 redLed = 0;
natgovor 6:6f93bce60d98 201 } else if (volts > 300) {
natgovor 6:6f93bce60d98 202 // failed short circuit
natgovor 6:6f93bce60d98 203 pc.printf("Failed open circuit 2\n\r");
natgovor 6:6f93bce60d98 204 greenLed = 0;
natgovor 6:6f93bce60d98 205 }
natgovor 6:6f93bce60d98 206 }
natgovor 6:6f93bce60d98 207
natgovor 6:6f93bce60d98 208 vToString(volts, vstring);
natgovor 6:6f93bce60d98 209 counter++;
natgovor 6:6f93bce60d98 210 if (counter == 10) { // limit bandwidth of serial
natgovor 6:6f93bce60d98 211 pc.printf(vstring);
natgovor 6:6f93bce60d98 212 counter = 0;
natgovor 6:6f93bce60d98 213 }
natgovor 6:6f93bce60d98 214 }
WilliamMarshQMUL 3:32a940251192 215 }
WilliamMarshQMUL 3:32a940251192 216 }
WilliamMarshQMUL 3:32a940251192 217
WilliamMarshQMUL 3:32a940251192 218 // -----------MAIN-------------------------------
WilliamMarshQMUL 3:32a940251192 219 // Configure watchdog. Start threads.
WilliamMarshQMUL 3:32a940251192 220 // Show start up with RED for 1sec
WilliamMarshQMUL 3:32a940251192 221 // Remember the watchdog is running
WilliamMarshQMUL 3:32a940251192 222 // - 1024ms to set it once
WilliamMarshQMUL 3:32a940251192 223 // - then must feed it every 32ms
WilliamMarshQMUL 3:32a940251192 224 // ----------------------------------------------
Manel_Marin 0:5ce3cfc57999 225
Manel_Marin 0:5ce3cfc57999 226 int main(void) {
natgovor 6:6f93bce60d98 227 redLed = 1;
natgovor 6:6f93bce60d98 228 greenLed = 1;
natgovor 6:6f93bce60d98 229
natgovor 6:6f93bce60d98 230 wdt_1sec(); // initialise watchdog - 1sec timeout
natgovor 6:6f93bce60d98 231
natgovor 6:6f93bce60d98 232 tick1.attach_us(callback(&readA0), 10000); // ticks every 10ms
natgovor 6:6f93bce60d98 233 tick2.attach_us(callback(&readA1), 10000); // ticks every 10ms
WilliamMarshQMUL 1:159a09ac60ba 234
WilliamMarshQMUL 3:32a940251192 235 // start threads
natgovor 6:6f93bce60d98 236 threadT.start(&timer_thread); // start the timer thread
natgovor 6:6f93bce60d98 237 threadLED1.start(&led1_thread); // start the LED1 control thread
natgovor 6:6f93bce60d98 238 threadLED2.start(&led2_thread); // start the LED2 control thread
natgovor 6:6f93bce60d98 239 threadCheckLED1.start(&check_led1); // start the LED2 control thread
natgovor 6:6f93bce60d98 240 threadCheckLED2.start(&check_led2); // start the LED2 control thread
WilliamMarshQMUL 1:159a09ac60ba 241
WilliamMarshQMUL 1:159a09ac60ba 242 // show start-up
WilliamMarshQMUL 3:32a940251192 243 led_red = OFF;
natgovor 6:6f93bce60d98 244 Thread::wait(1000);
WilliamMarshQMUL 3:32a940251192 245 led_red = ON;
Manel_Marin 0:5ce3cfc57999 246 }