Mysterious System Freeze after some Runtime

Running a fairly simple blinking program yields in a reproducible system hang situation. The program just plays with the four LEDs in a fairly stupid way and is my first excercise to get known with the mbed. After approximate 35 minutes the blinking stops, leaving 2 of the LEDs switched on.

This is strange, have no further idea, need to check this out.

Have added some logging via the serial line to be able to compare the loop counts and RTC time until freeze.

2 tests with the loop counter and RTC show that after 15749 inner cycles and 35:48 the system stops.

Will introduce the outer counter also...

(Problem solved; stupid me, see below)

(faulty) Code of Blink program:

#include "mbed.h"

DigitalOut myled1(LED1);
DigitalOut myled2(LED2); 
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);

long loopcounter;

Serial pc(USBTX, USBRX); // tx, rx

Timer timer;

int main() {
    loopcounter = 0;
    myled1 = 1;
    myled2 = 0;
    myled3 = 0;
    myled4 = 1;
    timer.start();
    pc.printf("starting.\n");

    int start = timer.read_ms();
    int start1 = timer.read_ms();
    int outerlim = 100;
    int maxlim = 200;
    int minlim = 10;
    int delta = 10;
    int deltalim = delta;
    set_time(0);  // Set RTC time

    while (1) {
        if ((timer.read_ms() - start) >= outerlim) {
            time_t seconds = time(NULL);
            loopcounter++;
            pc.printf("%d - %s",loopcounter, ctime(&seconds));
            myled1 = !myled1;
            myled4 = !myled4;
            start = timer.read_ms();
            outerlim += deltalim;
            if (outerlim <= minlim) {
                deltalim = delta;
            }
            if (outerlim >= maxlim) {
                deltalim = -delta;
            }
        }
        if (myled1 > 0) {
            myled2 = 0;
            myled3 = 0;
        } else {
            if ((timer.read_ms() - start1) >= outerlim/3) {
                myled2 = !myled2;
                myled3 = !myled3;
                start1 = timer.read_ms();
            }
        }
    }
}


2 comments

16 Oct 2010

Hi Peter,

You've done the main bit of the detective work :) Here is the next bit that'll help you:

All the timers use a 32-bit int to take a timestamp of a 1us running tick, so that limits how long they can time for (before they wrap). So you can work out how long this is:

int is stored as a 32-bit 2's complement number. That means it can store any number between -2^31 and +2^31-1 (i.e. approximately +/- 2 billion). So we can convert that to minutes/seconds:

2^31-1 micoroseconds / 10^6 = 2147 seconds = 35 minutes 47 seconds (approximately).

Snap!

Basically it comes down to the fact Timers are for microsecond to second timing, and time() is for second to year timing. I've updated the handbook to make this even clearer.

Hope that helps!

Simon

16 Oct 2010

Ta-Taaaa!

Simon, you're absolutely right: I was using the same 32bit timer values without resetting them after cycle completion. Shame on me, I should have seen that, being in the sw business for such a long time... (but then there were also a couple of glasses of red wine I had during my mbed playtime ;-)

Thanks for updating the handbook, it will surely help others to avoid this mistake.

Thanks again for putting me into the right direction,

-pl

You need to log in to post a comment