QuantumLeaps / Super-Simple-Tasker

Event-driven, preemptive, priority-based, hardware RTOS for ARM Cortex-M.
MIT License
143 stars 29 forks source link

ARM cortex M0 design question #5

Open mhanuel26 opened 2 weeks ago

mhanuel26 commented 2 weeks ago

Hi, I was able to port the C code to an Arm Cortex M0. The device does not have a Memory Protection Unit, I was trying to understand the implications for the deferencing issue on NULL pointers but as I am new to it and since library is meant to be used with M0 devices as well I want to check with you. Do you know how this will affect the scheuler and what issues I can expect?

Here is the section code I have commented.

image

I will appreciate your comments, Thank you,

quantum-leaps commented 2 weeks ago

SST has been running on the M0/M0+ for a long time, so there was not much "porting" except compiling the core SST code. The BSP (Board Support Package) might require some adjustements because this part is really specific to the board/MCU type. In the absence of the MPU, you can skip the "NULL-pointer protection". NULL-pointer dereferencing should never happen in a correct program, so it will run correctly. But, of course, it will not catch the mistakes. --MMS

mhanuel26 commented 1 week ago

Hi @quantum-leaps , Thank you for your response, yeah BSP is the section that have the code changes. I have a working SST example for a different MCU vendor, I want to check weather you would like to include the example in your repository or not.

The other thing I would like your thoughts is about implementing the lock for task, since it is a Cortex M0, how do you rise the priority of the current task? The section is TBD in the sources.

image

I will appreciate your response, Manuel

quantum-leaps commented 1 week ago

Unfortunately, Cortex-M0/M0+ (ARMv6-M architecture) is the least appropriate CPU for the SST (the hardware RTOS). This is because the ARMv6-M hardware is so limited. There is no BASEPRI register to lock the hardware "scheduler" only up to a given priority ceiling. And also the ARMv6-M NVIC with just 2 bits of interrupt priority is very limited and just barely adequate to do any prioritization of tasks.

Compare this to ARMv7-M or ARMv8-M architectures (all other Cortex-M) with the BASEPRI register and with 3 or 4 bits of NVIC priority. This is the proper hardware for a hardware RTOS.

So, the bottom line is that with literally thousands of Cortex-M MCUs available on the market, there is no shortage of proper hardware choices for SST. Choosing the M0/M0+ is just missing the point. I wouldn't sweat the Cortex-M0.

Finally, if you'd like to contribute your BSP to the SST repo, please make a pull request.

--MMS

mhanuel26 commented 6 days ago

Hi @quantum-leaps ,

Agree.

Quick question about SST task handling, what are the options for a task to delay the processing of events until a previous event is completed?

I will appreciate your guidance. Thank you,

quantum-leaps commented 6 days ago

Hi Manuel, SST is fundamentally an event-driven, non-blocking kernel, so SST does not have any blocking primitives, such as the delay() function. Instead, SST provides the time events (see the SST_TimeEvt). A time event is an event that the application can request to be delivered after the specified timeout in the future. Please see the Blinky example to see how to use such time events. --MMS

mhanuel26 commented 6 days ago

Hi Miro,

I am already familiar with it as I have used to migrate some of the existing code for the platoform I am working with. I would need to rethink of a way to do it using the time events. For a moment I thought i was able to reschedule the event when the task is busy, but the time event does not allow to specify some parameters for my task.

Basically I am triggering the event from another task such as

image

In this case the event contains the message which is the clock time (from SNTP task). But it might be the case that the led matrix task is busy (i.e. scrolling a text). This case might be silly as probably discarding the event is the reasonable approach. But what if I want to enqueue a couple of different scroll text messages? i.e.

image

The first message trigger the scroll task but as soon as the second event is received I can either restart scrolling with new text or discard the message.

Here is my source code in case you want to have a look.

Thank you, Manuel

quantum-leaps commented 6 days ago

Hi Manuel, In SST events are posted by pointers, so the actual events are all shared among concurrent entities (ISRs and SST tasks). Such sharing is safe when events are immutable, such as the events demonstrated in all SST examples. However, you are using mutable events, which are another story entirely. Currently, SST does not support mutable events.

Your way of posting an event (you call it "triggering an event") is potentially dangerous because your fInitDoneEvt is modified in one task and then it is processed in another concurrent task (mutable event). But you have no guarantee that the processing will not be preempted and the event will be modified again. In other words, this is the classic data race.

Proper handling of mutable events is not trivial. One example of an efficient and reasonably elegant solution is provided in the QP Framework. QP Framework is also event-driven and works well with non-blocking kernels. You might also take a look at the QK kernel, which works very much like the SST.

--MMS