
Added hardware failure detection to watchdog example.
Fork of Watchdog_sample_nocoverage by
Revision 6:2180a272ba06, committed 2018-03-09
- Comitter:
- diviavad
- Date:
- Fri Mar 09 22:10:35 2018 +0000
- Parent:
- 5:9817756efc34
- Commit message:
- lab 2.2.3
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 9817756efc34 -r 2180a272ba06 main.cpp --- a/main.cpp Tue Feb 27 10:29:30 2018 +0000 +++ b/main.cpp Fri Mar 09 22:10:35 2018 +0000 @@ -1,70 +1,145 @@ #include "mbed.h" #include "rtos.h" #include "wdt.h" - + // Sample program using the Watchdog // --------------------------------- // * Three threads co-operate to flash two LEDs -// * A simple way to inject a fault, by pressing a button +// * A simple way to inject a fault, by pressing a button // * The watchdog is configured with a 32ms timeout - + #define ON 1 #define OFF 0 DigitalOut led_red(LED_RED, ON); DigitalIn button(PTD0, PullUp); DigitalOut led1(PTC12, OFF); DigitalOut led2(PTC13, OFF); - + +AnalogIn ain1(A0) ; // Analog input +AnalogIn ain2(A1) ; // Analog input +Serial pc(USBTX, USBRX); // tx, rx, for debugging + + // This ticker is used to feed the watch dog Ticker tick; - + // Threads -Thread threadT ; // timer thread -Thread threadLED1 ; // thread LED1 -Thread threadLED2 ; // thread LED2 - +Thread threadT(osPriorityNormal, 2000) ; // timer thread +Thread threadLED1(osPriorityNormal, 2000) ; // thread LED1 +Thread threadLED2(osPriorityNormal, 2000) ; // thread LED2 + // ------------Fault Injection Button------------- // Wait while the button is down // Use this to simulate a STUCK fault // ----------------------------------------------- -void waitButton() { - while (!button) ; +void waitButton() +{ + while (!button) ; +} + +// Message type +typedef struct { + uint16_t analog; /* Analog input value */ +} message_t; + +// Mail box +Mail<message_t, 2> mailbox_led1; + +// Function called every 10ms to read ADC +// Low pass filter +// Every 10th value is sent to mailbox +volatile int samples_led1 = 0 ; +volatile uint16_t smoothed_led1 = 0 ; +void readA0() +{ + smoothed_led1 = (smoothed_led1 >> 1) + (ain1.read_u16() >> 1) ; // divided by 2 - reduce the signal noise + samples_led1++ ; + if (samples_led1 == 10) { + // send to thread + message_t *mess = mailbox_led1.alloc() ; // may fail but does not block + if (mess) { + mess->analog = smoothed_led1; + mailbox_led1.put(mess); // fails but does not block if full + } + samples_led1 = 0; + } } - + +// Mail box +Mail<message_t, 2> mailbox_led2; + +// Function called every 10ms to read ADC +// Low pass filter +// Every 10th value is sent to mailbox +volatile int samples_led2 = 0 ; +volatile uint16_t smoothed_led2 = 0 ; +void readA1() +{ + smoothed_led2 = (smoothed_led2 >> 1) + (ain2.read_u16() >> 1) ; // divided by 2 - reduce the signal noise + samples_led1++ ; + if (samples_led2 == 10) { + // send to thread + message_t *mess = mailbox_led2.alloc() ; // may fail but does not block + if (mess) { + mess->analog = smoothed_led2; + mailbox_led2.put(mess); // fails but does not block if full + } + samples_led2 = 0; + } +} + + + +// Write voltage digits +// v Voltage as scale int, e.g. 3.30 is 330 +void vToString(int v, char* s) +{ + s[3] = '0' + (v % 10) ; + v = v / 10 ; + s[2] = '0' + (v % 10) ; + v = v / 10 ; + s[0] = '0' + (v % 10) ; +} + // ---Thread for controlling LED 1---------------- -// Turn LED1 on/off in response to signals +// Turn LED1 on/off in response to signals // ----------------------------------------------- -void led1_thread() { // method to run in thread +void led1_thread() // method to run in thread +{ osEvent evt ; while (true) { evt = Thread::signal_wait(0x0); // wait for any signal if (evt.status == osEventSignal) { if (evt.value.signals & 0x01) led1 = ON ; if (evt.value.signals & 0x02) led1 = OFF ; - } + } waitButton() ; // POSSIBLE FAULT HERE + wdt_kickA(); } } - + // ---Thread for controlling LED 2---------------- -// Turn LED2 on/off in response to signals +// Turn LED2 on/off in response to signals // ----------------------------------------------- -void led2_thread() { // method to run in thread +void led2_thread() // method to run in thread +{ osEvent evt ; while (true) { evt = Thread::signal_wait(0x0); // wait for any signal if (evt.status == osEventSignal) { if (evt.value.signals & 0x01) led2 = ON ; if (evt.value.signals & 0x02) led2 = OFF ; - } - // waitButton() ; // POSSIBLE FAULT HERE + } + //waitButton() ; // POSSIBLE FAULT HERE + wdt_kickB(); } } - + // ---Thread for timing -------------------------- // Send signals to the other threads // ----------------------------------------------- -void timer_thread() { // method to run in thread +void timer_thread() // method to run in thread +{ while (true) { Thread::wait(250) ; threadLED1.signal_set(0x1) ; @@ -72,29 +147,94 @@ Thread::wait(250) ; threadLED1.signal_set(0x2) ; threadLED2.signal_set(0x2) ; - // waitButton() ; // POSSIBLE FAULT HERE + //waitButton() ; // POSSIBLE FAULT HERE } } - + // -----------MAIN------------------------------- -// Configure watchdog. Start threads. +// Configure watchdog. Start threads. // Show start up with RED for 1sec // Remember the watchdog is running // - 1024ms to set it once -// - then must feed it every 32ms +// - then must feed it every 32ms // ---------------------------------------------- - -int main(void) { - wdt_32ms() ; // initialise watchdog - 32ms timeout - tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms - + +int main(void) +{ + wdt_1sec() ; // initialise watchdog - 32ms timeout + //tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms + // start threads - threadT.start(&timer_thread) ; // start the timer thread - threadLED1.start(&led1_thread) ; // start the LED1 control thread - threadLED2.start(&led2_thread) ; // start the LED2 control thread - + threadT.start(&timer_thread) ; // start the timer thread + threadLED1.start(&led1_thread) ; // start the LED1 control thread + threadLED2.start(&led2_thread) ; // start the LED2 control thread + + int volts = 0 ; + const int threshold = 100 ; // 1 vol + int counter1 = 0 ; + int counter2 = 0 ; + char vstring[] = "X.XX\r\n" ; + + tick.attach_us(callback(&readA0), 10000); // ticks every 10ms -> 10000 micro second +// tick.attach_us(callback(&readA1), 10000); // ticks every 10ms -> 10000 micro second + // show start-up led_red = OFF; Thread::wait(1000) ; led_red = ON; + + while (true) { + + // LED1 process + osEvent evt1 = mailbox_led1.get(); // wait for mail + // every 100 ms this loop operates + if (evt1.status == osEventMail) { + message_t* mess = (message_t*)evt1.value.p ; + volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16 + mailbox_led1.free(mess) ; // free the message space + counter1++; + + + + vToString(volts, vstring) ; + // every 1 s this loop will operate + if (counter1 == 10) { // limit bandwidth of serial + pc.printf(vstring) ; + if(volts >= 150-threshold && volts <= 150+threshold) { + pc.printf("LED1 - Nomral \r\n\r\n") ; + } else if (volts == 0) { + pc.printf("LED1 - open circuit \r\n\r\n") ; + } else if(volts > 300) { + pc.printf("LED1 - short circuit \r\n\r\n") ; + } + counter1 = 0 ; + } + } + + // LED2 process + if(false) { + osEvent evt2 = mailbox_led2.get(); // wait for mail + // every 100 ms this loop operates + if (evt2.status == osEventMail) { + message_t* mess = (message_t*)evt2.value.p ; + volts = (mess->analog * 330) / 0xffff ; // 2 ^ 16 + mailbox_led1.free(mess) ; // free the message space + vToString(volts, vstring) ; + counter2++; + + // every 1 s this loop will operate + if (counter2 == 10) { // limit bandwidth of serial + pc.printf(vstring) ; + if(volts >= 150-threshold && volts <= 150+threshold) { + pc.printf("LED2 - Nomral \r\n\r\n") ; + } else if (volts == 0) { + pc.printf("LED2 - open circuit \r\n\r\n" ) ; + } else if(volts > 300) { + pc.printf("LED2 - short circuit \r\n\r\n") ; + } + counter2 = 0 ; + } + } + } + } } \ No newline at end of file