Enhanced test program using watchdog timer to recover from lock-up
Dependencies: EthernetInterface mbed-rtos mbed
Fork of TCPSocket_HelloWorldTest by
main.cpp@14:5ee75b072c69, 2013-05-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |