This is the block diagram of AL (Abstraction Layer) modules I drew som time ago. I need to review this as the list is far longer, but you get the idea. I actually started on the AL a year ago and managed to destroy my work due to a bug in STM32CubeIDE at the time, so I need to start from scratch more or less – yes I do feel the pain! But, I have myself to blame for bad backup procedures.
alOS embed a RTOS (Real Time Operating System) so that the rest of the code can be independent of what OS we use. The terminology Thread and Task is used to distinguish between actual Threads that need a stack and Tasks running within a thread or main.
alOS provides four bulks of functionality that is important in any system. These are static functions so they can be called anywhere in code and guarantee portability of code. Their actual implementation is different from OS to OS.
Embedded will typically use FreeRTOS (or similar) to create a threading OS, while we use a linear scheduler for tasks. Timers are a combination of HS and SW timers.
Windows will use WinAPI for threads and the same linear scheduler for Tasks and Timers.
|alOS::sleep()||Sleep in ms.|
|alOS::millis()||Get time in ms.|
|alOS::micros()||Get time in ys.|
Create a one way byte or message FIFO. The array used must be created before calling this function. typically a uint8_t array should be declared and used as FIFO buffer.
Send bytes or a message. Will also signal the Receive Task (if any) to execute. Will either insert all bytes in the fifo or none. The caller must handle full fifo signals (returning false).
Receive bytes or a message. Can be used polling in which case it will return 0 if no bytes/messages was found.
|alOS::FIFOReceiveTask()||Set Task to receive a signal for each call to Send.|
Add a thread. A thread execute in parallel on a timer interrupt and need a separate stack.
|alOS::StartThread()||Start thread. This enables the thread to be called.|
|alOS::StopThread()||Stop a thread. This stops the thread from executing.|
|alOS::SignalThread()||This signals the thread to execute once.|
Add a function callback that can be executed on time or signals. A Task need to execute and return so the next task can execute.
|alOS::StartTask()||Start a task.|
|alOS::StopTask();||Stop a Task.|
|alOS::SignalTask();||Signal a task to execute.|
Start a timer. alOS will run itself as a task checking timers and signals ca 1000 times per second.
|alOS::StartTimer()||Start a timer that will call a task in n ms. This is excellent for timeout style functionality.|
|alOS::StartLongTimer()||Start a long timer lasting more than a day.|
|alOS::StopTimer()||Stop a timer.|
FIFO, Timer, Task and Thread reference numbers are unique.
All systems will as a minimum have an elapsed timer counting uS from MCU start. The accuracy of this depends on crystals used and what source is used to maintain the clocks.
alOS guarantee a set of functions related to elapsed timers with uS accuracy. See alRTC for Real Time Clock options.
Threads and Tasks
alOS uses Thread and Task as described here.
A thread need a separate stack and is executed on a system interrupt. It needs to run in a loop and can use techniques like delay() since this allows the OS to execute another thread. Basically threads execute in “parallel” with the RTOS using a time interrupt to switch content usually 1000 times a sec.
A Task is a single function that must do its job and exit before the scheduler can start the next Task. Tasks are lists of functions that are called on timers or signals within a thread. The difference is that they run in a loop executing in sequence and must be written different from a thread. Tasks are however far more scalable than Threads since you only use a single stack. Usually you will have multiple Tasks running in a Thread.
alOS support 3 types of timers:
- Hardware timers supported by the MCU.
- RTOS Timers supported by FreeRTOS.
- SW Task Timers supported by the linear scheduler.
Using RTOS timers are not recommended, but FreeRTOS (as an example) have their own proprietary timers that can be used if needed.
Hardware timers are subject to the MCU involved, but STM32F405RG (as an example) have 14 hardware timers. Keep in mind that these are called on actual HW interrupts, so they need an ISR type of function.
Task Timers are basically tasks called on time intervals. A normal task will execute once per ms or each 10th ms depending on what you set, but a timer will execute once the timeout event is raised. Task timers can also exist in much higher numbers and it is not any real difference between a task and a task timer. A timer task can be signalled etc.
Hardware timers should however be used for things that require exact timing. Servo pulse control is an example. A SW timer will have some variance in accuracy causing the pulse to vary from second to second. On a servo this will be observed as the servo making small, unexpected moves. A hardware timer is more exact and capable of giving the same pulse from second to second making the servo stable – this is just one example. But, keep in mind that a HW timer is far more expensive to use than a SW timer, so it is not recommended to use a HW timer to blink a led etc.
alOS support a scheme with signal counters, meaning that a task is executed once for each signal you send. This was designed with message queues in mind there you need to process once per message received. Since the timer function will prevent other tasks in the same thread it is healthy to process in bulks – hence the signal counter scheme.
The main queuing mechanism in alOS is easyIPC, meaning you can create a queue between local tasks, threads or to a different device.