mbed hangs on serial interrupt

11 Sep 2015

Hello

I'm trying to catch data from the serial ports (p9, p10) and (p13, p14). I want it interrupt based, But my mbed hangs afther initialisation.

First I've the initialization functions:

void SerialA_Init(int baud)
{
    serial_A.baud(baud);
    serial_A.attach(&RxA_interrupt);
}
void SerialB_Init(int baud)
{
    serial_B.baud(baud);
    serial_B.attach(&RxB_interrupt);
}

Then in the callback functions I try to catch the data:

void RxA_interrupt(void)
{
    char data = serial_A.getc();
    rcvBufferA = rcvBufferA + data;
}
void RxB_interrupt(void)
{
    char data = serial_B.getc();
    rcvBufferB = rcvBufferB + data;
}

To actually use the data I use another function that uses the rcvBufferA and B.

But the problem is, when booting the MBED, it initializes the serial ports and then the MBED freezes. I've tried several possible solutions like adding "UART_1_RBR = LPC_UART1->RBR;" But nothing works.

How can I solve this?

Thanks Robin

11 Sep 2015

So what is in your program happening after it initializes the serial port? Are you using RTOS?

11 Sep 2015

Yes, I use the EthernetInterface library to handle TCP/IP communication.

When I receive a serial message, it should send it to the server through TCP/IP

14 Sep 2015

It al works fine when I'm not using the "serial_A.attach(&RxA_interrupt);" lines, If I use them "Setting up Ethernet..." is not written to my console. So i suppose it hangs afther the initialisation...

11 Sep 2015

While it only should hang once called, you are not allowed to use Serial interrupts when using RTOS. Use RawSerial instead, then it is allowed.

11 Sep 2015

Is there any example, how to use RawSerial interrupt based?

Thanks for the quick support

11 Sep 2015

Yes. Replace 'Serial' with 'RawSerial' in the declaration of your serial connection, and it should work :).

11 Sep 2015

It does not...

Still hangs after initialization.

Declaration

RawSerial serial_A(p9,p10);
RawSerial serial_B(p13,p14);

init

void SerialA_Init(int baud)
{
    serial_A.baud(baud);
    serial_A.attach(&RxA_interrupt);
}
void SerialB_Init(int baud)
{
   serial_B.baud(baud);
    serial_B.attach(&RxB_interrupt);
}

interrupt routine

void RxA_interrupt(void)
{
    while(serial_A.readable())
    {
       char karakt = serial_A.getc();    
        rcvBufferA = rcvBufferA + karakt;
    }    
}

void RxB_interrupt(void)
{
    while(serial_B.readable())
    {
       char karakt = serial_B.getc();    
        rcvBufferB = rcvBufferB + karakt;
    }    
}

also tried, not using "strings" in the interrupt callback, as suggested here: https://developer.mbed.org/questions/60528/RawSerial-Rx-interrupt-only-triggering-o/ same result..

Regards

Robin

11 Sep 2015

Do you have any reason to assume it hangs due to the interrupts? And try to figure out where it hangs (you can even use LEDs which light up when you enter the interrupt routine, or just print something to serial).

11 Sep 2015

I've created an simple program. Code below. I also included the rtos library but haven't used it.

Now it seems that the interrupt problem is solved. (for now) But, I want to print a message in terminal A when there are more then 5 characters received.

I receive on both ports that "they are alive" but when i send some characters it seems not responding... So i never get the message "A index > 5" or "B index > 5".

#include "mbed.h"
#include <iostream>
#include <string>

RawSerial serial_A(p9,p10);
RawSerial serial_B(p13,p14);

char bufferA[100];
char bufferB[100];
int bufA_index, bufB_index;

void RxA_interrupt(void)
{
    while(serial_A.readable())
    {
       char karakt = serial_A.getc();
       bufA_index++;
    }    
}
void RxB_interrupt(void)
{
    while(serial_B.readable())
    {
       char karakt = serial_B.getc(); 
       bufB_index++;
    }    
}

int main() {
    serial_A.printf("program started \r\n");
        
    serial_A.attach(&RxA_interrupt);
    serial_B.attach(&RxB_interrupt);
    
    serial_A.printf("interrupts attached \r\n");
    
    while(1) {
        
        wait(1);
        
        if (bufA_index > 5)
        {            
            serial_A.printf("A index > 5");
            bufA_index = 0;
        } 
                
        if (bufB_index > 5)
        {            
            serial_A.printf("B index > 5");
            bufB_index = 0;
        }
        
        serial_A.printf("I'm still alive! \r\n");
        serial_B.printf("Also alive! \r\n");
        
    }
}

11 Sep 2015

Any variable modified in an interrupt routine needs to be defines as 'volatile' to make sure the main loop uses always the most recent version. This is especially true for the index integers (so set them as volatile int), but also the buffers themselves should be defined as volatile.

Btw if you include rtos lib in your program, assume it is used :). Not 100% sure about it, but I have seen weird stuff with it.

11 Sep 2015

Dear Erik,

Thanks for the support. I finally found my mistake, and it's an hardware issue :( (I use an custom board based on the LPC1768)

But the info about the interrupts is very useful. On Monday i'll try to fix the hardware issue and then I can continue to program.

I'll keep you posted!

Regards Robin

12 Sep 2015

Robin,

Your simple two interrupt program can show some interesting issues. Although you are not using an rtos you have effectively created a very simple rtos with the interrupt dispatcher acting as scheduler. When viewed in this way you have built a 3 task system with shared variables - bufA_index and bufB_index. The asynchronous nature of interrupt arrival will mean that you cannot predict the actual order of execution.

In your design you are also making an assumption that clearing and incrementing these shared variables are indivisible (also called atomic) operations and cannot be interrupted. This may or may not be true. If they are not indivisible then you can get some very interesting bugs where you will lose counts.

As regards using the 'volatile' keyword, I have always assumed that this only ensured that the variable was left alone be the code optimiser. I don't think it can ensure mutual exclusive access.

Jim

14 Sep 2015

Dear Erik, Jim

I fixed the hardware issue, implemented the serial interrupts as suggested earlier, and it works fine!

Thanks for the support!

15 Sep 2015

Glad to hear it, good luck with your project.