8 years, 11 months ago.

How to forcefully terminate a function? (Not Solved)

Due to compatibility issues as described in the following thread: http://developer.mbed.org/questions/5358/for-Compatibility-with-EthernetInterface/

Methods(GET, POST etc) in HTTPClient library do not honor non-blocking timeout settings. If mbed tries to get something from a server and no response is received, the whole application will stuck permanently or until watchdog timer is triggered. Believe it nor not, this actually happens a lot. The application I am working on posts some data onto a server about once/minute, it gets stuck sometimes once in a day sometimes once in 3 hours.

Is there any way to terminate a function such as post/get in HTTPClient if it gets stuck?

Mbed official is aware of the issue but not sure the timeline of release of revision. So I am trying to figure out some temporal solution. Watchdog is in place to prevent system stuck forever but rebooting application every couple hours is really not something nice to do:)

Many thanks in advance. ZL

Update 2:

For a while I thought the method posted in Update 1 solved the problem. After more testing in field, the matter of truth is: it doesn't.

Depending on local ethernet stability, HTTP calls caused system hangs vary from once a week(both mbed devices are in north america) to once an hour(when mbed device and server on two sides of pacific ocean). When mbed device is intentionally harassed, like assigned the same IP address to mbed and another computer are the same network, mbed device will keep hangs and reboots by WDT.

So I guess I am back on square 1.

Update 1:

The following is the solution I came up with. put a function inside a thread, and terminate it if timeout.

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

DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
osThreadId mainThreadID;
char threadCycleCount = 0;

void block(void const *args) {
    myled1 = 1;
    threadCycleCount++;
    if(threadCycleCount > 5) {
        threadCycleCount = 0;
        wait(600.0);                        // Simulate a blocking function such as HTTPClient->post()
    } else {
        wait(1.0);
    }
    osSignalSet(mainThreadID, 0x01);
}

int main() {
    myled1 = 0;
    mainThreadID = Thread::gettid();

    while(1) {
        Thread blockingThread(block);
        Thread::signal_wait(0x1, 1100);
        blockingThread.terminate();
        myled1 = 0;
        wait(1.0);
        myled2 = !myled2;
    }
}

Thats a nice solution. Couldn't think myself of any proper way to do it which does not involve changing the function itself.

posted by Erik - 03 May 2015

Well, it doesn't look pretty when parameters and results need to be passed back and forth. But it is the only solution I can think of, so I will live with it for now.

posted by Zhiyong Li 03 May 2015
Be the first to answer this question.