Watchdog_Step-3_Edwin_Kadavy

Fork of Watchdog_sample_nocoverage by William Marsh

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?

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
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 }