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

Dependencies:   EthernetInterface mbed-rtos mbed

Fork of TCPSocket_HelloWorldTest by Daniel Peter

main.cpp

Committer:
paulg
Date:
2013-05-27
Revision:
14:5ee75b072c69
Parent:
12:9bef73198a53

File content as of revision 14:5ee75b072c69:

// TCP Socket Test Program
// Based on work by Daniel Peter: https://mbed.org/forum/mbed/topic/4354/
// Modified to add LED tracing, a second task and watchdog timer recovery from lock-up

#include "mbed.h"
#include "rtos.h"
#include "EthernetInterface.h"

#define RETRIES_ALLOWED 5

Serial pc(USBTX, USBRX);
EthernetInterface eth;
DigitalOut led1(LED1);
DigitalOut led2(LED2), led3(LED3), led4(LED4);

// Simon's Watchdog code from http://mbed.org/forum/mbed/topic/508/
class Watchdog {
public:
// Load timeout value in watchdog timer and enable
    void kick(float s) {
        LPC_WDT->WDCLKSEL = 0x1;                // Set CLK src to PCLK
        uint32_t clk = SystemCoreClock / 16;    // WD has a fixed /4 prescaler, PCLK default is /4
        LPC_WDT->WDTC = s * (float)clk;
        LPC_WDT->WDMOD = 0x3;                   // Enabled and Reset
        kick();
    }
// "kick" or "feed" the dog - reset the watchdog timer
// by writing this required bit pattern
    void kick() {
        LPC_WDT->WDFEED = 0xAA;
        LPC_WDT->WDFEED = 0x55;
    }
};
 
Watchdog wdt;   // Set up the watchdog timer

void led2_thread(void const *args) {
    while (true) {
        led2 = !led2;
        Thread::wait(250);
    }
}

int main()
{
    int i = 0;
    Thread thread(led2_thread);

    pc.baud(115200);
    printf("TCP Socket Hello World Test\n");
    printf("Initialising...\n");
    set_time(0);

    // use DHCP
    eth.init();

    // attempt DHCP and if timing out then try again
    while (eth.connect()) {
        printf("DHCP timeout\n");
    };

    // successful DHCP
    printf("IP Address is %s\n", eth.getIPAddress());

    // set up a 10 second timeout on watchdog timer hardware
    // needs to be longer than worst case main loop exection time
    wdt.kick(10.0);  

    // loop forever
    while (true) {

        // new non blocking socket
        TCPSocketConnection sock;
        sock.set_blocking(false);

        // toggle led to indicate activity
        led1 = !led1;

        // attempt socket connection and if failure then loop again
        if (sock.connect("mbed.org", 80)) {
            printf("Socket connect timeout\n");
            continue;
        }

        // send command
        printf("Sending (%d) at %d seconds\n", i++, time(NULL));
        char http_cmd[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\n\n";
        sock.send_all(http_cmd, sizeof(http_cmd) - 1);

        // receive response
        int received = 0;
        int retries = 0;
        while (true) {

            int result;
            char buffer[256];

            led4 = 1;
            result = sock.receive(buffer, sizeof(buffer) - 1);
            led4 = 0;
            printf("Received: %d %d %d\n", result, received, retries);

            // if timeout or no data
            if (result <= 0) {

                // if data previously received then stop receiving
                if (received > 0) {
//                    printf("Data previously received\n");
                    break;
                }

                // if incremented retries exceeded then no response and stop receiving
                if (++retries > RETRIES_ALLOWED) {
                    printf("Retry limit exceeded\n");
                    break;
                }

            } else {

                // zero terminate the buffer
                buffer[result] = '\0';

                // total size of data received
                received += result;
            }

        }

        // close socket at end of send and receive
        sock.close();
        
        // wait before repeating
        Thread::wait(1000);

        // End of main loop so "kick" to reset watchdog timer and avoid a reset
        wdt.kick();
    }
}