I’ve seen several instances in my code where FreeRTOS hangs.
Given an external handle to a semaphore, for instance, if the init code is bypassed (can happen during program development), and the semaphore functions are called with a null pointer, the semaphore code just hangs and does not return an error (such as semaphore not allocated).
Is this something that can be easily fixed?
It’s not intended behavior, but it can happen by accident.
That behavior is by design. Passing a NULL Handle is an error, and the code is hitting an assert that is catching it. It is helping you find that you forgot to initialize the handle.
If you want to add that sort of error, write a wrapper around the functions that test the handle and return the error, else they call the real function.
Hmmm, granted it’s an error, which it ought to be.
I kinda avoid that in my own code.
I’d rather return an error value myself and then trap that.
You can define the assert to whatever you want. See configASSERT().
That’s a system design issue.
Here are two out of several aspects to consider:
Unlike Smartphone/Desktop/Table applications, Industrial Embedded systems typically can not recover from the failure of an individual task. That is because the system as a whole relies on all its task to operate and interact properly. Iow, whereas it doesn’t matter to your Word processor whether a video game running on the same computer crashes or not, your embedded system typically fails irrecoverably if one of its tasks crashes. Thus, there is little benefit in “gracefully” reacting to an individual failure. Typically a system stalled whatsoever will be recovered by a watchdog that recognizes, for example, a forever loop in a fault handler.
In Embedded applications, size matters. Every run time check costs code footprint, so designing an RTOS is always a tightrope walk between desireable robustness and aggressive resource optimization.
In practice, defining an assert in debug mode to catch errors at development time has over time proven to be a fairly reliable QA technique.
The key is the assert hang the system in a way that you can see exactly what the system state was at the time of the error.
If also allows you to remove the asserts and speed up the code a bit when you ‘know’ everything is working. If you define the API to test and return error, you can never ‘optimize’ it away because you ‘know’ that this sort of error can’t happen.
My assert hangs the system and prints an error message on the system console.
I will add if you forget to initialize the handle, you are also likely to forget to test the return value. One big cause of systems strangely misbehaving is people forgetting to test return error flags and something hasn’t been set up as required.