![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Watchdog_Step-3_Edwin_Kadavy
Fork of Watchdog_sample_nocoverage by
main.cpp
- Committer:
- edwinkad
- Date:
- 2018-03-09
- Revision:
- 6:d93fa1c57fd2
- Parent:
- 3:32a940251192
File content as of revision 6:d93fa1c57fd2:
#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 // * The watchdog is configured with a 32ms timeout #define ON 1 #define OFF 0 DigitalOut led_red(LED_RED, ON); DigitalOut led_blue(LED_BLUE, ON); DigitalOut led_green(LED_GREEN, ON); DigitalIn button(PTD0, PullUp); DigitalOut led1(PTC12, OFF); DigitalOut led2(PTC13, OFF); AnalogIn ain1(A0) ; // Analog input 1 AnalogIn ain2(A1) ; // Analog input 2 // This ticker is used to feed the watch dog Ticker tick1, tick2; // Threads Thread threadT ; // timer thread Thread threadLED1 ; // thread LED1 Thread threadLED2 ; // thread LED2 //Detection of hardware failure volatile int volts1 = 0 ; volatile int volts2 = 0 ; volatile int state=0 ; Serial pc(USBTX, USBRX); // tx, rx, for debugging // Message type1 typedef struct { uint16_t analog; /* Analog input value */ } message_t; // Mail box Mail<message_t, 2> mailbox; // Function called every 10ms to read ADC // Low pass filter // Every 10th value is sent to mailbox volatile int samples = 0 ; volatile uint16_t smoothed = 0 ; void readA0() { smoothed = (smoothed >> 1) + (ain1.read_u16() >> 1) ; samples++ ; if (samples == 10) { // send to thread message_t *mess = mailbox.alloc() ; // may fail but does not block if (mess) { mess->analog = smoothed ; mailbox.put(mess); // fails but does not block if full } samples = 0; } } // Message type2 typedef struct { uint16_t analog2; /* Analog input value */ } message_t2; // Mail box Mail<message_t2, 2> mailbox2; volatile int samples2 = 0 ; volatile uint16_t smoothed2 = 0 ; void readA1() { smoothed2 = (smoothed2 >> 1) + (ain2.read_u16() >> 1) ; samples2++ ; if (samples2 == 10) { // send to thread message_t2 *mess = mailbox2.alloc() ; // may fail but does not block if (mess) { mess->analog2 = smoothed2 ; mailbox2.put(mess); // fails but does not block if full } samples2 = 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) ; } // ------------Fault Injection Button------------- // Wait while the button is down // Use this to simulate a STUCK fault // ----------------------------------------------- void waitButton() { while (!button) ; } // ---Thread for controlling LED 1---------------- // Turn LED1 on/off in response to signals // ----------------------------------------------- void led1_thread() // method to run in thread { osEvent evt ; while (true) { wdt_kickA(); // first part 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 } } // ---Thread for controlling LED 2---------------- // Turn LED2 on/off in response to signals // ----------------------------------------------- void led2_thread() // method to run in thread { osEvent evt ; while (true) { wdt_kickB(); // second part 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 } } // ---Thread for timing -------------------------- // Send signals to the other threads // ----------------------------------------------- void timer_thread() // method to run in thread { while (true) { Thread::wait(250) ; threadLED1.signal_set(0x1) ; threadLED2.signal_set(0x1) ; Thread::wait(250) ; threadLED1.signal_set(0x2) ; threadLED2.signal_set(0x2) ; // waitButton() ; // POSSIBLE FAULT HERE } } void detection(int volts) { if(volts==0 ||state==1) { led_blue= OFF; state=1; } else if(volts>=300||state==2) { led_green= OFF; state=2; } } // -----------MAIN------------------------------- // 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 // ---------------------------------------------- int main(void) { wdt_256ms() ; // initialise watchdog - 32ms timeout //wdt_kick_all; //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 // show start-up led_red = OFF; Thread::wait(1000) ; led_red = ON; //hardware failure detection int counter = 0 ; char vstring1[] = "X.XX\r\n" ; char vstring2[] = "X.XX\r\n" ; tick1.attach_us(callback(&readA0), 10000); // ticks every 10ms tick2.attach_us(callback(&readA1), 10000); // ticks every 10ms while (true) { osEvent evt = mailbox.get(); // wait for mail if (evt.status == osEventMail) { message_t* mess = (message_t*)evt.value.p ; volts1 = (mess->analog * 330) / 0xffff ; mailbox.free(mess) ; // free the message space } osEvent evt2 = mailbox2.get(); // wait for mail if (evt2.status == osEventMail) { message_t2* mess = (message_t2*)evt2.value.p ; volts2 = (mess->analog2 * 330) / 0xffff ; mailbox2.free(mess) ; // free the message space } counter++ ; if (counter == 5) { // limit bandwidth of serial detection(volts1); // hardware fault detecttion.(It is inside the counter which cause a small delay,... detection(volts2); // putting it out side causes the first 0 value to be read showing an instant failure) vToString(volts1, vstring1) ; pc.printf("LED1 "); pc.printf(vstring1) ; vToString(volts2, vstring2) ; pc.printf("LED2 "); pc.printf(vstring2) ; counter = 0 ; } } }