Mbed os version and GCC compiler version combination

Which version of mbed os 6 and gcc arm compiler work best? I am working with the following combination

  • MBed os 6.17.0 (latest)
  • GCC Arm compiler version 6.3.1 (gcc-arm-none-eabi-6-2017q2). Have tried newer ones too like 10.3.1
  • mbed cli 1

I have issues with things like

  • CAN Interrupt not working (polling works)
  • InterruptIn ISR not being triggered (when defined inside a class; while it works if defined in main)

All these used to work fine in my previous code with mbed os 5. I have even tried the eventqueue but that also seems to not trigger my interrupt action.

I even tried switching back to mbed os 6.13.0. Still, no luck.

Some help would be very much appreciated. Thanks in advance.

Hello,

for example the Mbed Studio has GCC 9 as recommended one so your one is definitely very old. However basic information seems to be here - Overview - Build tools | Mbed OS 6 Documentation

  • what a minor version of MbedOs 5 were you use before?
  • what is your target?
  • do you have a simple code for reproducing?

BR, Jan

1 Like

Hi,

Thnx for the response.

I was using GCC 9.2.1 along with Mbed os 5.9.5 in an older project. It used to work fine.
My target is LPC1768
When I switched to Mbed Os 6.17.0, GCC 9.2.1 (gcc-arm-none-eabi-9-2019-q4-major) would not work. So, I switched to 6.3.1 (gcc-arm-none-eabi-6-2017q2) which was known to work from another internal project.

This example is only on CAN interrupt. I will post a separate one for InterruptIn issues. I have the other items in place only to have a realistic minimal code. Also, Ideally, I keep most codes separated in different files (can_handler, io_handler etc) but made a simple example in one file using those now.

/* 
 * Simple program to test few APIs of mebed os 6
 */

#include "mbed.h"


// Macros
#define FIRMWARE_VERSION "0.21-mbed6"

#define TICKER_1_PERIOD 1s

#define PC_SERIAL_BAUDRATE 115200

#define CAN1_FREQUENCY 125000 //in kbps
#define ID_REQUEST_FRAME 0x01
#define ID_RESPONSE_FRAME 0x20
#define INTER_CAN_FRAME_DELAY 5000 // in us


// Instantiate mbed Objects
DigitalOut mainLED(LED1);
DigitalOut canLED(LED2);
Ticker _ticker1;
CAN _can(CAN1_RD,CAN1_TD);
BufferedSerial _pc(USBTX, USBRX);


// Global variables
bool canMessageReceived = false;
bool canRequestReceived = false;
char printStringBuffer[200];
int printStringSize = 0;
bool ticker1Ready = 0;

// Function prototypes
void ticker1();
void RxIrqHandlerCAN();
void attachISR(void function());
bool sendCANMessage(CANMessage Msg);
CANMessage readCANMessage();
CANMessage getNewCANMessage(uint32_t frame_id, uint8_t frame_data);
void readAndParseCANMessage();

// Main function

int main()
{
    mainLED = 1;
    canLED = 1;

    _pc.set_baud(PC_SERIAL_BAUDRATE);
    _pc.set_format(8, BufferedSerial::None, 1);

    _ticker1.attach(&ticker1, TICKER_1_PERIOD);

    _can.frequency(CAN1_FREQUENCY);
    attachISR(RxIrqHandlerCAN);

    while(1)
    {
        if (ticker1Ready)
        {
            if (canRequestReceived)
            {
                sendCANMessage(getNewCANMessage(ID_RESPONSE_FRAME, 0x01));
                canRequestReceived = false;
            }
            printStringSize = sprintf(printStringBuffer, "Triggered by Ticker1: Mbed6 tests v%s\n", FIRMWARE_VERSION);
            _pc.write(printStringBuffer, printStringSize);
            ticker1Ready = false;
        }

        if (canMessageReceived)
        {
            readAndParseCANMessage();
            canMessageReceived = false;
        }
    }
}


// Function definitions

void ticker1()
{
    mainLED = !mainLED;
    ticker1Ready = true;
}

void RxIrqHandlerCAN()
{
    canLED = !canLED;
    canMessageReceived = true;
}

void attachISR(void function())
{
    _can.attach(function, CAN::RxIrq);
}

bool sendCANMessage(CANMessage TxMsg)
{
    wait_us(INTER_CAN_FRAME_DELAY);
    if(_can.write(TxMsg))
    {
        printStringSize = sprintf(printStringBuffer,"CAN Message sent: 0x%X\n", TxMsg.id);
        _pc.write(printStringBuffer, printStringSize);
        return 1;
    }
    else
    {
        return 0;
    }
}

CANMessage readCANMessage()
{
    CANMessage RxMsg;
    RxMsg.format = CANExtended;

    _can.read(RxMsg);
    return RxMsg;
}

CANMessage getNewCANMessage(uint32_t frame_id, uint8_t frame_data)
{
    CANMessage CanMsg;
    CanMsg.format = CANExtended;
    CanMsg.id = frame_id;
    CanMsg.len = 8;
    CanMsg.data[0] = frame_data;
    return CanMsg;
}

void readAndParseCANMessage()
{
    CANMessage receivedCANMessage = readCANMessage();

    if (receivedCANMessage.id == 0) // no can message received
    {
        return;
    }

    printStringSize = sprintf(printStringBuffer,"CAN Message received: 0x%X\n", receivedCANMessage.id);
    _pc.write(printStringBuffer, printStringSize);

    if (receivedCANMessage.id == ID_REQUEST_FRAME)
    {
        canRequestReceived = true;
    }
}

Ok, thank you.

Can you try to declared your bool flags as volatile?

volatile bool canMessageReceived = false;
volatile bool canRequestReceived = false;
volatile bool ticker1Ready = 0;

BR, Jan

Thanks. Tried volatile too. No change.

I used gcc arm compiler 10.3.1 as recommended in the documentation.

Net effect, I am unable to isolate the cause

  • Is my code wrong? (not very likely since it’s a simplified version of what used to work with mbed os 5.9.5)
  • Are there some bugs in the latest version of Mbed OS?
  • Is there a mismatch between Mbed OS version and GCC Arm compiler version?

The effort to determine this is becoming too high. Any suggestions to crunch this debugging time would be much appreciated.

I do not have LPC1768 so I do not know, but is popular target so I believe potential issues would be already reported here or on github.

I see just this

Mbed CLI 1 - Mbed OS 6.4 and older
Mbed CLI 2 - Mbed OS 6.5 and newer

About interrupt in general the Mbed OS 5.12 was game changer because all methods what have potential with manipulation through threads are covered by Mutex and mutex can not be used in ISR - read / write / printf / send / received and os on

Did you firmware updare of your LPC1768? That could be the magic.

BR, Jan

Hi,

Yes. I noted that Mbed CLI 2 is recommended for Mbed OS 6.5 or higher. But Mbed CLI 1 is also allowed. I did try Mbed CLI 2. I am able to build a simple file but then I need to add more CMakeLists.txt files etc for that. Hence, I have set aside that activity for later. May be, I will try MBed Os 6.4 with this.

Good to know that Mbed OS 5.12 was the game changer. In any case, I don’t have printf / read etc (which create mutex) in ISRs.

I don’t understand the concept of interface firmware. Looks like that was old. Those documentation pages do not look updated. Also, is that still required? Coz I never used it even with Mbed OS 5.9.5. And this certainly does not look like it was introduced with Mbed OS 6. Do you know if this is actually required?

I will test Mbed OS 6.4 and let you know. Thnx again.

Yes, I think it is necessary for newer versions of Mbed OS. I remember this was usually solution for strange behavior reported here on forum.
It was not introduced with MbedOS 6 because this page and info about firmware update there were long time before.

BR, Jan

Hmm. Ok. I will read through that and check. It does make life more complicated.