Andrew Mkpanam
/
Watchdog2
final
Diff: main.cpp
- Revision:
- 3:32a940251192
- Parent:
- 2:c31a1758ac38
- Child:
- 6:8b0ca28c88a4
--- 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