Enhanced test program using watchdog timer to recover from lock-up

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of TCPSocket_HelloWorldTest by Daniel Peter

Committer:
paulg
Date:
Mon May 27 09:58:51 2013 +0000
Revision:
14:5ee75b072c69
Parent:
12:9bef73198a53
Enhanced test program using watchdog timer to recover from lock-up

Who changed what in which revision?

UserRevisionLine numberNew contents of line
paulg 14:5ee75b072c69 1 // TCP Socket Test Program
paulg 14:5ee75b072c69 2 // Based on work by Daniel Peter: https://mbed.org/forum/mbed/topic/4354/
paulg 14:5ee75b072c69 3 // Modified to add LED tracing, a second task and watchdog timer recovery from lock-up
paulg 14:5ee75b072c69 4
donatien 0:bb128f0e952f 5 #include "mbed.h"
paulg 14:5ee75b072c69 6 #include "rtos.h"
donatien 0:bb128f0e952f 7 #include "EthernetInterface.h"
donatien 0:bb128f0e952f 8
mbed714 12:9bef73198a53 9 #define RETRIES_ALLOWED 5
mbed714 12:9bef73198a53 10
mbed714 12:9bef73198a53 11 Serial pc(USBTX, USBRX);
mbed714 12:9bef73198a53 12 EthernetInterface eth;
mbed714 12:9bef73198a53 13 DigitalOut led1(LED1);
paulg 14:5ee75b072c69 14 DigitalOut led2(LED2), led3(LED3), led4(LED4);
paulg 14:5ee75b072c69 15
paulg 14:5ee75b072c69 16 // Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/
paulg 14:5ee75b072c69 17 class Watchdog {
paulg 14:5ee75b072c69 18 public:
paulg 14:5ee75b072c69 19 // Load timeout value in watchdog timer and enable
paulg 14:5ee75b072c69 20 void kick(float s) {
paulg 14:5ee75b072c69 21 LPC_WDT->WDCLKSEL = 0x1; // Set CLK src to PCLK
paulg 14:5ee75b072c69 22 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
paulg 14:5ee75b072c69 23 LPC_WDT->WDTC = s * (float)clk;
paulg 14:5ee75b072c69 24 LPC_WDT->WDMOD = 0x3; // Enabled and Reset
paulg 14:5ee75b072c69 25 kick();
paulg 14:5ee75b072c69 26 }
paulg 14:5ee75b072c69 27 // "kick" or "feed" the dog - reset the watchdog timer
paulg 14:5ee75b072c69 28 // by writing this required bit pattern
paulg 14:5ee75b072c69 29 void kick() {
paulg 14:5ee75b072c69 30 LPC_WDT->WDFEED = 0xAA;
paulg 14:5ee75b072c69 31 LPC_WDT->WDFEED = 0x55;
paulg 14:5ee75b072c69 32 }
paulg 14:5ee75b072c69 33 };
paulg 14:5ee75b072c69 34
paulg 14:5ee75b072c69 35 Watchdog wdt; // Set up the watchdog timer
paulg 14:5ee75b072c69 36
paulg 14:5ee75b072c69 37 void led2_thread(void const *args) {
paulg 14:5ee75b072c69 38 while (true) {
paulg 14:5ee75b072c69 39 led2 = !led2;
paulg 14:5ee75b072c69 40 Thread::wait(250);
paulg 14:5ee75b072c69 41 }
paulg 14:5ee75b072c69 42 }
mbed714 12:9bef73198a53 43
mbed714 12:9bef73198a53 44 int main()
mbed714 12:9bef73198a53 45 {
paulg 14:5ee75b072c69 46 int i = 0;
paulg 14:5ee75b072c69 47 Thread thread(led2_thread);
mbed714 12:9bef73198a53 48
mbed714 12:9bef73198a53 49 pc.baud(115200);
paulg 14:5ee75b072c69 50 printf("TCP Socket Hello World Test\n");
mbed714 12:9bef73198a53 51 printf("Initialising...\n");
mbed714 12:9bef73198a53 52 set_time(0);
mbed714 12:9bef73198a53 53
mbed714 12:9bef73198a53 54 // use DHCP
mbed714 12:9bef73198a53 55 eth.init();
mbed714 12:9bef73198a53 56
mbed714 12:9bef73198a53 57 // attempt DHCP and if timing out then try again
mbed714 12:9bef73198a53 58 while (eth.connect()) {
mbed714 12:9bef73198a53 59 printf("DHCP timeout\n");
mbed714 12:9bef73198a53 60 };
mbed714 12:9bef73198a53 61
mbed714 12:9bef73198a53 62 // successful DHCP
emilmont 2:e087e9b789e9 63 printf("IP Address is %s\n", eth.getIPAddress());
mbed714 12:9bef73198a53 64
paulg 14:5ee75b072c69 65 // set up a 10 second timeout on watchdog timer hardware
paulg 14:5ee75b072c69 66 // needs to be longer than worst case main loop exection time
paulg 14:5ee75b072c69 67 wdt.kick(10.0);
paulg 14:5ee75b072c69 68
mbed714 12:9bef73198a53 69 // loop forever
emilmont 7:65188f4a8c25 70 while (true) {
mbed714 12:9bef73198a53 71
mbed714 12:9bef73198a53 72 // new non blocking socket
mbed714 12:9bef73198a53 73 TCPSocketConnection sock;
mbed714 12:9bef73198a53 74 sock.set_blocking(false);
mbed714 12:9bef73198a53 75
mbed714 12:9bef73198a53 76 // toggle led to indicate activity
mbed714 12:9bef73198a53 77 led1 = !led1;
mbed714 12:9bef73198a53 78
mbed714 12:9bef73198a53 79 // attempt socket connection and if failure then loop again
mbed714 12:9bef73198a53 80 if (sock.connect("mbed.org", 80)) {
mbed714 12:9bef73198a53 81 printf("Socket connect timeout\n");
mbed714 12:9bef73198a53 82 continue;
mbed714 12:9bef73198a53 83 }
mbed714 12:9bef73198a53 84
mbed714 12:9bef73198a53 85 // send command
paulg 14:5ee75b072c69 86 printf("Sending (%d) at %d seconds\n", i++, time(NULL));
mbed714 12:9bef73198a53 87 char http_cmd[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\n\n";
mbed714 12:9bef73198a53 88 sock.send_all(http_cmd, sizeof(http_cmd) - 1);
mbed714 12:9bef73198a53 89
mbed714 12:9bef73198a53 90 // receive response
mbed714 12:9bef73198a53 91 int received = 0;
mbed714 12:9bef73198a53 92 int retries = 0;
mbed714 12:9bef73198a53 93 while (true) {
mbed714 12:9bef73198a53 94
mbed714 12:9bef73198a53 95 int result;
mbed714 12:9bef73198a53 96 char buffer[256];
mbed714 12:9bef73198a53 97
paulg 14:5ee75b072c69 98 led4 = 1;
mbed714 12:9bef73198a53 99 result = sock.receive(buffer, sizeof(buffer) - 1);
paulg 14:5ee75b072c69 100 led4 = 0;
mbed714 12:9bef73198a53 101 printf("Received: %d %d %d\n", result, received, retries);
mbed714 12:9bef73198a53 102
mbed714 12:9bef73198a53 103 // if timeout or no data
mbed714 12:9bef73198a53 104 if (result <= 0) {
mbed714 12:9bef73198a53 105
mbed714 12:9bef73198a53 106 // if data previously received then stop receiving
paulg 14:5ee75b072c69 107 if (received > 0) {
paulg 14:5ee75b072c69 108 // printf("Data previously received\n");
mbed714 12:9bef73198a53 109 break;
paulg 14:5ee75b072c69 110 }
mbed714 12:9bef73198a53 111
mbed714 12:9bef73198a53 112 // if incremented retries exceeded then no response and stop receiving
mbed714 12:9bef73198a53 113 if (++retries > RETRIES_ALLOWED) {
paulg 14:5ee75b072c69 114 printf("Retry limit exceeded\n");
mbed714 12:9bef73198a53 115 break;
mbed714 12:9bef73198a53 116 }
mbed714 12:9bef73198a53 117
mbed714 12:9bef73198a53 118 } else {
mbed714 12:9bef73198a53 119
mbed714 12:9bef73198a53 120 // zero terminate the buffer
mbed714 12:9bef73198a53 121 buffer[result] = '\0';
mbed714 12:9bef73198a53 122
mbed714 12:9bef73198a53 123 // total size of data received
mbed714 12:9bef73198a53 124 received += result;
mbed714 12:9bef73198a53 125 }
mbed714 12:9bef73198a53 126
mbed714 12:9bef73198a53 127 }
mbed714 12:9bef73198a53 128
mbed714 12:9bef73198a53 129 // close socket at end of send and receive
mbed714 12:9bef73198a53 130 sock.close();
mbed714 12:9bef73198a53 131
mbed714 12:9bef73198a53 132 // wait before repeating
mbed714 12:9bef73198a53 133 Thread::wait(1000);
mbed714 12:9bef73198a53 134
paulg 14:5ee75b072c69 135 // End of main loop so "kick" to reset watchdog timer and avoid a reset
paulg 14:5ee75b072c69 136 wdt.kick();
emilmont 7:65188f4a8c25 137 }
mbed714 12:9bef73198a53 138 }