8 years, 1 month ago.

Serial, Interrups and the RTOS Library

I tried to get the serial port working by using the attach-function. I had some problems with that so I set up a little testprogram.

I use a serial bluetooth device connected to the mbed. This program resets the device and then shows the startupinformation which come from the device:

#include "mbed.h"
 
DigitalOut led1(LED1);
DigitalOut led2(LED2);
 
Serial pc(USBTX, USBRX);
DigitalOut rst(p28);

class btc {
public:
    btc(PinName rx, PinName tx){
        bt = new Serial(rx, tx);
        bt->baud(38400);
        bt->attach(this, &btc::callback);
    }
    void callback() {
        led2 = !led2;
        pc.printf("%c", bt->getc());
    }
private:
    Serial* bt;
};

 
int main() {
    btc* mybt = new btc(p9, p10);
    
    rst = 1;
    wait(1);
    rst = 0;
    
    while (1) {
        led1 = !led1;
        wait(0.5);
    }
}

That works fine. But at the moment I add the mbed RTOS Library to the projekt, the program freeze after first call of the interrupt-function. LED2 turns on, and then it freezes. I don't even have to include the rtos-header file. If I delete the RTOS Library, everything goes back to normal.

Anybody any ideas and/or solutions?

3 Answers

6 years, 2 months ago.

Hi Max and Emilio,

Not sure what the progress is, but I think at this point, we can get around by accessing UART TX and RX register directly instead of using putc() and getc().

The following link has a nice write up regarding how to directly access mbed hardware io.

http://developer.mbed.org/users/4180_1/notebook/cc-io-register-names/

I was able to get my code to work this way.

ZL

RawSerial has been introduced in the meantime which does work with RTOS.

posted by Erik - 24 Jan 2015

Thanks for the heads up Erik. I was able to find RawSerial in mbed-src. We are finally able to put getc() in ISR. Cheers!

posted by Zhiyong Li 24 Jan 2015
8 years, 1 month ago.

Hi Max, there are few implementation details that could not be obvious:

  • when using the RTOS you cannot use mutexes in ISR.
  • printf uses mutexes for protecting the access to stdout
  • the Serial attach callback get executed in an ISR

We tried to document that in this paragraph of the RTOS documentation: RTOS::Mutex.

You should solve your problem removing the printf from your ISR: btc::callback.

HTH, Emilio

Max Knodel
poster
8 years, 1 month ago.

Hey Emilio,

thanks for your quick answer. I thougt about that too, so I just deleted line 18 and the same happens... Offcourse this way the interrups is never deleted but it should at least blink LED1...

To avoid the problem with blocking commands in ISR I usally start a new Thread, waiting for a signal and then doing the work I can't do in ISR. And the actual ISR only sends the signal to it. It works on InterruptIn for example. But doing that by using the attach function from Serial, I get siren lights, the moment it calls the set_signal-function of that Thread.

Edit: I actually only try to get an Interrup-driven serial ring buffer getting to work but running out of ideas...

Try to keep just the bt->getc() to clear the interrupt.

posted by Emilio Monti 08 Mar 2013

nope, not working... It should anyway always come to the while-loop at the end of main, or not? Even I don't clear the interrupt?

posted by Max Knodel 08 Mar 2013

I meant: substitute "pc.printf("%c", bt->getc());" with "bt->getc();"

posted by Emilio Monti 08 Mar 2013

Yes, i did that... It looks like this now

void callback() {
        led2 = !led2;
        bt->getc();
    }
posted by Max Knodel 08 Mar 2013

I changed the program now, so you can try out without any additional hardware...

#include "mbed.h"
 
DigitalOut led1(LED1);
DigitalOut led2(LED2);
 
Serial pc(USBTX, USBRX);
 
class pcc {
public:
    pcc(){
        pc.attach(this, &pcc::callback);
    }
    void callback() {
        led2 = !led2;
        pc.getc();
    }
};
 
 
int main() {
    pcc* mypcc = new pcc();
    
    while (1) {
        led1 = !led1;
        wait(0.5);
    }
}

At the beginning, LED1 is flashing, when I enter a character, it freezes...

posted by Max Knodel 08 Mar 2013

OK, I tried with the simple and quick suggestions reading the code. I will open a ticket to run and debug the example, but it goes at the end of a long queue, do not expect a follow up soon.

posted by Emilio Monti 08 Mar 2013

Yes, all the serial stdio-like functions (printf, putc, getc, etc) end up calling actual stdio functions, that, like I said, are actually mutex protected: therefore they cannot be called from an ISR.

In a future revision of the mbed library integration with the RTOS we will try to improve this use case.

posted by Emilio Monti 18 Jul 2013