Lab 6 Code 2 Hardware Failure Detection

Fork of Watchdog_sample_nocoverage by William Marsh

Revision:
3:32a940251192
Parent:
2:c31a1758ac38
Child:
6:f375c710bd0e
--- a/main.cpp	Tue Feb 28 18:05:25 2017 +0000
+++ b/main.cpp	Wed Mar 01 23:01:51 2017 +0000
@@ -1,66 +1,100 @@
 #include "mbed.h"
+#include "rtos.h"
 #include "wdt.h"
 
 // Sample program using the Watchdog
 // ---------------------------------
-//    * Watchdog is fed for 5 sec, after that
-//    *   ... the system resets 
+//    * 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);
+DigitalIn button(PTD0, PullUp);
+DigitalOut led1(PTC12, OFF);
+DigitalOut led2(PTC13, OFF);
+
+// This ticker is used to feed the watch dog
+Ticker tick;
+
+// Threads
+Thread threadT ; // timer thread 
+Thread threadLED1 ; // thread LED1
+Thread threadLED2 ; // thread LED2
+
+// ------------Fault Injection Button-------------
+//  Wait while the button is down
+//     Use this to simulate a STUCK fault
+// -----------------------------------------------
+void waitButton() {
+    while (!button) ;  
+}
 
-// Note on how the WATCHDOG is enabled, overloading library function SystemInit
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// The KL25Z watchdog is enabled after reset with timeout=1024ms (2^10*LPO=1KHz)
-// To make the dvice easy to use on mbed, th watchdog is disabled at startup 
-// (in file SystemInit.c) **BUT** SIM_COPC register can only be written once 
-// after reset and so it can not be enabled later. To resolve this, 
-// SystemInit() is overloaded using:   void $Sub$$SystemInit (void) {
-//
-// The original SystemInit() can be dowloaded from:
-//   https://developer.mbed.org/users/mbed_official/code/mbed-src/
-//   navigating to ... targets/cmsis/TARGET_Freescale/TARGET_KLXX/
-//                       TARGET_KL25Z/system_MKL25Z4.c
-//
-// MORE on how this overides the original initialisation: 
-//   https://developer.mbed.org/users/chris/notebook/Patching-functions-and-libraries/
-//   and searching "ARM Compiler toolchain Using the Linker" 
-//      "Using $Super$$ and $Sub$$ to patch symbol definitions"
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// ---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) {
+        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
+    }
+}
 
-
-#define LIGHT 0
-#define DARK 1
-DigitalOut led_red(LED_RED, LIGHT);
-DigitalOut led_blue(LED_BLUE, DARK);
+// ---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) {
+        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
+    }
+}
 
-// Demonstate the watchdog
-//   The red LED is on after reset
-//   Th blue LED flashes and the watch dog is fed
-//   Aft 5sec, stop feeding the watchdog
-enum wState {Working, Stopped} ;
+// ---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
+    }
+}
+
+// -----------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) {
-    // initialise watchdog
-    wdt_1sec() ;
+    wdt_32ms() ; // initialise watchdog - 32ms timeout
+    tick.attach_us(callback(&wdt_kick_all), 20000); // ticks every 20ms    
     
-    // state of the watch dog
-    wState watchDog = Working ;
-    int counter = 10 ;
+    // 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_blue = DARK;
-    led_red = LIGHT;
-    wait(0.5) ;
-    led_red = DARK;
-    
-    // Note: the red LED now stays OFF until processor reset
-    while(1)
-    {
-        led_blue = LIGHT;
-        wait(0.25);
-        if (watchDog == Working) wdt_kick_all() ;
-        led_blue = DARK;
-        wait(0.25);
-        
-        // When the counter rachs zero, chang state to stop watchdog 
-        if (counter > 0) counter-- ; else watchDog = Stopped ;
-    }
+    led_red = OFF;
+    Thread::wait(1000) ;
+    led_red = ON;
 }
\ No newline at end of file