Mutex and Semaphore API examples goes to ++ MbedOS Fault Handler ++

Hi all,

I’m using release mbed-os (#c73413893fb9, tags: mbed-os-6.9.0, mbed-os-6.9.0-rc1)

And I went trough examples of all ROTS APIs to learn use it.

If I hard copy Mutex or Semaphore example and compile it with Mbed Cli “mbed compile -m NUCLEO_L432KC -t GCC_ARM -f” it goers to ++ MbedOS Fault Handler ++

I tried to avoid printf

    printf("%s: %d\n\r", name, state);

with

static BufferedSerial serial(USBTX, USBRX, 9600);
char buff[64];
sprintf("%s\n\r", (const char *)name);
        serial.write(buff, strlen(buff));
		memset(buff, '/0', sizeof(buff));

but it did not worked out. I still got error.

Is it problem of example code for mbed-os 6 or I am doing something wrong?

all other examples are working (they can be more verbose too).

Thanks.

Hello,

Both examples, the Mutex and the Semaphore, work fine when compiled with Mbed OS 6.15.0 for LPC1768. Maybe there was some issue with revision 6.9.0. So I’d recommend to try 6.15.0.

Hi Zoltan,

I updated mbed-os to 6.15.00

#include "mbed.h"

Mutex stdio_mutex;
Thread t2;
Thread t3;

void notify(const char *name, int state)
{
    stdio_mutex.lock();
    printf("%s: %d\n\r", name, state);
    stdio_mutex.unlock();
}

void test_thread(void const *args)
{
    while (true) {
        notify((const char *)args, 0);
        ThisThread::sleep_for(1000);
        notify((const char *)args, 1);
        ThisThread::sleep_for(1000);
    }
}

int main()
{
    t2.start(callback(test_thread, (void *)"Th 2"));
    t3.start(callback(test_thread, (void *)"Th 3"));

    test_thread((void *)"Th 1");
}

Run to ++ MbedOS Fault Handler ++.

If I commented out :

    //t2.start(callback(test_thread, (void *)"Th 2"));
    t3.start(callback(test_thread, (void *)"Th 3"));

or

    t2.start(callback(test_thread, (void *)"Th 2"));
    //t3.start(callback(test_thread, (void *)"Th 3"));

it runs.
Total Static RAM memory (data + bss): 8440(+0) bytes
Total Flash memory (text + data): 31332(+28) bytes

But When I keep both thread active, ++ MbedOS Fault Handler ++ appear.
Total Static RAM memory (data + bss): 8440(+0) bytes
Total Flash memory (text + data): 31336(+4) bytes

This was in console, it it helps:

Th 1:

++ MbedOS Fault Handler ++



FaultType: HardFault



Context:

R   0: 08007861

R   1: 00000000

R   2: 00000000

R   3: 200003B8

R   4: 20000420

R   5: 00000000

R   6: 00000000

R   7: 00000000

R   8: 00000000

R   9: 00000000

R  10: 00000000

R  11: 00000000

R  12: 00000000

SP   : 200032B0

LR   : 0800426D

PC   : 200003B8

xPSR : 00000000

PSP  : 20003290

MSP  : 2000FFC0

CPUID: 410FC241

HFSR : 40000000

MMFSR: 00000001

BFSR : 00000000

UFSR : 00000000

DFSR : 00000008

AFSR : 00000000

Mode : Thread

Priv : Privileged

Stack: PSP



-- MbedOS Fault Handler --







++ MbedOS Error Info ++

Error Status: 0x80FF013D Code: 317 Module: 255

Error Message: Fault exception

Location: 0x200003B8

Error Value: 0x20001FE8

Current Thread: application_unnamed_thread Id: 0x20000498 Entry: 0x8004255 StackSize: 0x1000 StackMem: 0x200022B8 SP: 0x200032B0

For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=NUCLEO_L432KC

-- MbedOS Error Info --


Also to same with Semaphore.

#include "mbed.h"

Semaphore one_slot(1);
Thread t2;
Thread t3;

void test_thread(void const *name)
{
    while (true) {
        one_slot.acquire();
        printf("%s\n\r", (const char *)name);
        ThisThread::sleep_for(1000);
        one_slot.release();
    }
}

int main(void)
{
    t2.start(callback(test_thread, (void *)"Th 2"));
    t3.start(callback(test_thread, (void *)"Th 3"));

    test_thread((void *)"Th 1");
}

runs to :

Th 1


++ MbedOS Fault Handler ++



FaultType: HardFault



Context:

R   0: 08007905

R   1: 00000000

R   2: 00000000

R   3: 200003B8

R   4: 20000410

R   5: 00000000

R   6: 00000000

R   7: 00000000

R   8: 00000000

R   9: 00000000

R  10: 00000000

R  11: 00000000

R  12: 00000000

SP   : 200032A0

LR   : 08004315

PC   : 200003B8

xPSR : 00000000

PSP  : 20003280

MSP  : 2000FFC0

CPUID: 410FC241

HFSR : 40000000

MMFSR: 00000001

BFSR : 00000000

UFSR : 00000000

DFSR : 00000008

AFSR : 00000000

Mode : Thread

Priv : Privileged

Stack: PSP



-- MbedOS Fault Handler --







++ MbedOS Error Info ++

Error Status: 0x80FF013D Code: 317 Module: 255

Error Message: Fault exception

Location: 0x200003B8

Error Value: 0x20001FD8

Current Thread: application_unnamed_thread Id: 0x20000488 Entry: 0x80042FD StackSize: 0x1000 StackMem: 0x200022A8 SP: 0x200032A0

For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=NUCLEO_L432KC

-- MbedOS Error Info --

Works only with commented out t2.start() or t3.start().

The RTOS is memory-hungry but the RAM is limited. So try to reduce the size of the thread stack from 4k to for example 2k:

mbed-app.json

{
    "target_overrides": {
        "*": {
            "platform.stdio-baud-rate": 115200,
            "rtos.thread-stack-size": 2048
        }
    }
}

Thanks a Lot Zoltan,

I just put here that I needed to change:

mbed-os/cmsis/device/rtos/ mbed_lib.json

{
    "name": "rtos",
    "config": {
        "present": 1,
         "main-thread-stack-size": {
            "help": "The size of the main thread's stack",
            "value": 4096
         },
         "timer-thread-stack-size": {
            "help": "The size of the timer thread's stack",
            "value": 768
         },
         "idle-thread-stack-size": {
            "help": "The size of the idle thread's stack",
            "value": 512
         },
         "thread-stack-size": {
            "help": "The default stack size of new threads",
            "value": 2048

I don’t know why we have it on different files, but it works.

Michal

I’m glad that is works :slight_smile:

I don’t know why we have it on different files

The mbed-os/cmsis/device/rtos/mbed_lib.json is a global configuration file of the rtos library. It is applied to all programs and targets using that library. That’s why it is not recommended to modify it (unless you need a permanent change to be applied to all programs and targets).

As opposed to that, the mbed_app.json is a configuration file used only for a specific application program. It should be created in the root directory of you program. Here you can adapt (override) the global (default) settings according to your needs. Moreover, if you would like to apply it only for a specific target then indicate its name rather than putting an asterisk (*). For example as below:

{
    "target_overrides": {
        "NUCLEO_L432KC": {
            "platform.stdio-baud-rate": 115200,
            "rtos.thread-stack-size": 2048,
            "rtos.main-thread-stack-size": 3072
        },
        "LPC1768": {
            "platform.stdio-baud-rate": 115200,
            "rtos.thread-stack-size": 4096,
            "rtos.main-thread-stack-size": 1024
        }

    }
}

This enables to have different settings in different programs for different targets.

I don’t know, but text search on all files gave me this:

image

No mbed_app.json with this

platform.stdio-baud-rate

Which file shall be that correct mbed_app.json ?

image

Thanks

Which file shall be that correct mbed_app.json ?

Maybe it’s not clear yet but it should be created by you in the root directory of your program:

Now you have a program for testing the Mutex which contains a main.cpp file. Right?

  • Open your favorite text editor and copy & paste the following text to the editor’s edit window:
{
    "target_overrides": {
        "*": {
            "platform.stdio-baud-rate": 115200,
            "rtos.thread-stack-size": 2048
        }
    }
}
  • Click on the Save button. When you are asked for the file name type in mbed_app.json and save it in the folder containing the main.cpp file.

  • Repeat the same for the Semaphore program.