Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutex lock failed on Mbed OS5.10.x #8518

Closed
toyowata opened this issue Oct 24, 2018 · 9 comments
Closed

Mutex lock failed on Mbed OS5.10.x #8518

toyowata opened this issue Oct 24, 2018 · 9 comments

Comments

@toyowata
Copy link
Contributor

toyowata commented Oct 24, 2018

Description

I wrote a following program and works fine on OS5.9.7 but error is happened on OS5.10. 0, 5.10.1 and 5.10.2.
Target Board: Nucleo-F446RE
https://os.mbed.com/users/kenjiArai/code/Mutex_lock_failed_on_os_5_10/

The error message is below.

++ MbedOS Error Info ++
Error Status: 0x80020115 Code: 277 Module: 2
Error Message: Mutex lock failed
Location: 0x8005B01
Error Value: 0xFFFFFFFA
Current Thread: Id: 0x200024D8 Entry: 0x8007045 StackSize: 0x1000 StackMem: 0x200014D8 SP: 0x2001FF50
For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80020115
-- MbedOS Error Info --

Looks like OS internal RTX Kernel bug.
Please give me an advice how to overcome this issue.

Issue request type

[ ] Question
[ ] Enhancement
[x] Bug

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 24, 2018

@pilotak provides an answer to this in the os.mbed.com question.

I believe this one is related #7423 - It was failing before but was silent, there's now error and shows the wrong usage of serial in the interrupt handler.

@ciarmcom
Copy link
Member

Internal Jira reference: https://jira.arm.com/browse/MBOCUSTRIA-97

@0xc0170
Copy link
Contributor

0xc0170 commented Oct 31, 2018

@toyowata I believe this is answered. I'll close it as resolved. If not, please reopen with an update

@maxgerhardt
Copy link
Contributor

@0xc0170 What is the correct usage of the serial API attach() in a Serial object then if you want to read the character that's been received? The cookbook example code (https://os.mbed.com/cookbook/Serial-Interrupts, Rx_interrupt()) is thus wrong, the tutorial doesn't talk about it (https://os.mbed.com/docs/v5.10/tutorials/serial-comm.html), neither does the documentation of Serial (https://os.mbed.com/docs/v5.10/apis/serial.html). I'm having the same problem here.

@pilotak
Copy link
Contributor

pilotak commented Nov 28, 2018

@maxgerhardt it would be something like that

#include "mbed.h"

EventQueue queue;
Serial pc(TX, RX);

void read() {
    printf("%02X\n", pc.getc());
}

int main() {
    Thread eventThread;
    eventThread.start(callback(&queue, &EventQueue::dispatch_forever));

    pc.attach(queue.event(&read));

    wait(osWaitForever);
}

or I made a wrapper around UARTSerial to make it easier

@kjbracey
Copy link
Contributor

@pilotak - that wrapper's seems very... complicated. But hard to judge as I'm not quite sure what the intended timeout semantics are.

The Serial object is basically useless, at least for reception - I've been fighting to deprecate it for some time (#5655), but apparently it's too popular. That example above will compile, but won't work in practice if there's any other threads or work happening - the serial hardware buffer will tend to overrun before the read() function gets called.

If you want to process serial data from interrupt, use RawSerial, which will let you do reads from inside attach. If you want to process data in the foreground, use UARTSerial, which does the interrupt handler and buffering for you. ('UARTSerial' should have been called BufferedSerial, but it had to avoid name collision with its out-of-tree ancestor).

Don't use Serial for input - it will only work reliably for reception if you receive from the interrupt handler, but you're not allowed to receive from the interrupt handler. Catch 22. Or I guess it can be used in a very strict command-response fashion where you send a query and immediately go into a getc loop before the other person can send anything, and the other end never sends anything spontaneously. (Greentea effectively does this).

Or I guess Serial is okay if you have hardware flow control to stop the other side sending when you're not in getc. But people often don't.

Documentation for UARTSerial got stalled because all the examples of how to use it were really about FileHandle - too generic. There is documentation pending for FileHandle at the minute: ARMmbed/mbed-os-5-docs#745, and there are a couple of examples there.

@pilotak
Copy link
Contributor

pilotak commented Nov 28, 2018

@kjbracey-arm it's for receiving block of data sent out every 2 sec with variable block length. And important callback when sending is done - for RS485 DE/RE pin. I was inspired by AT parser lib but yes i could probably make it better or maybe don't need it at all but due to lack of documentation this is the result.

Anyway reading your explanation it sound like Serial should be called deprecated i think or there is a sign that it should support DMA transfers but not done yet #7360

@maxgerhardt
Copy link
Contributor

maxgerhardt commented Nov 28, 2018

I have now worked around this issue by using RawSerial which doesn't attempt to acquire a mutex and reading the data there in the ISR.

@kjbracey
Copy link
Contributor

@pilotak If the data is framed sensibly, a timeout on the reads shouldn't really be required. You just do a non-blocking read of whatever is available, running your state machine. The AT handlers are a bit ugly because they're not state machine based - they're sitting there waiting for a response, and want that wait to have a timeout. It's possible to do better

A simpler model is the PPP data pump (https://github.com/ARMmbed/mbed-os/blob/master/features/lwipstack/ppp_lwip.cpp), but that does rely on lovely nice framing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants