Serial IRQ and event queue

01 Nov 2017

Hello there,

When i'm trying to attach an EventQueue event to the Serial RX ISR it produces an assert:

mbed assertation failed: id, file: /src/mbed-os/events/Event.h, line 149

With other ISRs it is working. I don't understand what the assert means. Any suggestions?

EXAMPLE CODE

#include <events/mbed_events.h>
#include <mbed.h>

mbed::Serial *pc;
EventQueue eventQueue(32 * EVENTS_EVENT_SIZE);
Thread t(osPriorityNormal);

void printtext(){
  pc->printf("text received\n\r");    
}

int main(){
  t.start(callback(&eventQueue, &EventQueue::dispatch_forever));

  pc = new Serial(USBTX, USBRX);
  pc->attach(eventQueue.event(printtext), Serial::RxIrq);
}
01 Nov 2017

It is possible that you are filling up the EventQueue. Do you have any idea about how many events are being generated?

01 Nov 2017

Thanks Sarah, good hint

The Problem is that Serial IRQ Flag isn't cleared in ISR. It gets cleared by reading the RX buffer i guess. Is it a bug or a feature?!

So endless queue events get fired and the queue gets filled up.

Is there a way to clear the IRQ flags manually in mbed?

01 Nov 2017

A Solution could be to use this library:

https://os.mbed.com/users/AjK/code/MODSERIAL/

But not for my Device nRF52-DK until now.

01 Nov 2017

Hello,

I've just gotten a chance to try this out myself.

Quote:

The Problem is that Serial IRQ Flag isn't cleared in ISR. It gets cleared by reading the RX buffer i guess. Is it a bug or a feature?!

Yes, most hardware will keep the interrupt pending until it is cleared. Some boards do not have a way to clear the IRQ unless you read from the register, so it must be consumed.

Another problem with your program... printf will generate serial events, and for each of those events, you'll print more, so you're stuck in an infinite loop even if you consumed the data in your callback.

So, here is a program that will do what I think you want:

#include "events/mbed_events.h"
#include "mbed.h"
 
mbed::Serial *pc;
EventQueue eventQueue(32 * EVENTS_EVENT_SIZE);
Thread t(osPriorityNormal);

void post_to_queue();
 
void printtext(){
    pc->printf("text received %c\n\r", pc->getc()); 
    pc->attach(post_to_queue, Serial::RxIrq);
}

void post_to_queue(){
    pc->attach(NULL, Serial::RxIrq);
    eventQueue.call(printtext);
}
 
int main(){
  t.start(callback(&eventQueue, &EventQueue::dispatch_forever));
 
  pc = new Serial(USBTX, USBRX);
  pc->attach(post_to_queue, Serial::RxIrq);
}
01 Nov 2017

Wow this is a really cool solution.

Works fine!

Thank you :)

16 Aug 2019

This does not work.

Using an LPC 1768, Mbed OS 5.13, the system halts with:

output from serial

++ MbedOS Error Info ++
Error Status: 0x80010133 Code: 307 Module: 1
Error Message: Mutex: 0x100037FC, Not allowed in ISR context
Location: 0x877B
File: mbed_rtx_handlers.c+118
Error Value: 0x100037FC
Current Thread: rtx_idle  Id: 0x10001974 Entry: 0x5D6B StackSize: 0x200 StackMem: 0x10001A00 SP: 0x10007EE4 
For more info, visit: https://mbed.com/s/error?error=0x80010133&osver=51302&core=0x412FC230&comp=1&ver=6100100&tgt=LPC1768
-- MbedOS Error Info --

Is there an alternative to this, as using an ISR and reading data off the serial interface is essentially non-functional at this point.

16 Aug 2019

If you, like me, found this same error, the 'fix' is to use `RawSerial` instead of `Serial`.

To say it's not immediately obvious that this is the case, would be an oversimplification.