In the past I have worked with different OS systems. The problem here was always
that they had different APIs, or e.g. a different meaning for the priorities of
a task. So there are OS systems where a low priority number means a high priority
and vice versa. Since I didn't always want to change the calls in my application
with another OS, there is the OSAL for this.
In addition to TinyCTS, the OSAL also supports
Using 2 examples, Blinky and lwIP, I show how to use the OSAL here. Blinky is more
used here to illustrate what needs to be changed in a TinyCTS application, and lwIP
to measure the difference in performance.
When I developed TinyCTS, the OSAL was already taken into account. That's why
OSAL has the same API as TinyCTS. This also makes it easier when you switch an existing
TinyCTS application to µC/OS-III or FreeRTOS.
The priorities of the task are set up in such a way that a smaller number has a higher
task priority than a larger number.
SEGGER Embedded Studio
v7.30 was used as the compiler.
With an existing TinyCTS application, two changes must be made in "main.c"
and in the "StartTask".
In "main.c", "tal_init" is replaced by "osal_Init":
And in "StartTask" "osal_InitPost" must be added:
In the "Preprocessor Definitions" "RTOS_TCTS" is used for TinyCTS:
And the "Process Stack Size" must be set not to 0:
Furthermore, it must be ensured that a task which can be terminated calls "OS_TaskExit"
as the last function:
The changes with "osal_Init" and "osal_InitPost" are also required
here as with TinyCTS. In the "Preprocessor Definitions", "RTOS_UCOS3"
is now required instead of "RTOS_TCTS". And the "Process Stack Size"
must be set to 0:
Same as µC/OS-III but here "RTOS_FREERTOS" is needed at the
Compared to TinyCTS and µC/OS-III, the default FreeRTOS has a slightly different
behavior in the task statistics. With TinyCTS and µC/OS-III, the task utilization
is displayed directly. This means that the display has a high value even if the load is
correspondingly high. When the utilization is over again, the value is directly low
But if you now do an iperf test with FreeRTOS, for example, the value of the task
utilization increases slowly and is still at a high value after the test. It takes a
while for the value to normalize again.
The difference is that with TinyCTS and µC/OS-III the internal values for the
measurement are calculated by a statistic task and will be set to 0 every 500ms. As a
result, there is a direct display of the utilization. With FreeRTOS, the values are not
reset again, so accumulated values are used here.
I had also tried to reset the internal values in FreeRTOS after the statistics output.
But this was not working here.
Test task statistic with blinky
For testing the task statistic there exist two tasks, P10 and P50. P10 consume 10
and P50 consume 50 percent of utilization. The corresponding tasks can be stopped
and started with "1" (P10) and "5" (P50):
Here P10 and P50 are running, and consume 60 percent of utilization. The task
statistics are working in case of TinyCTS and µC/OS-III, but unfortunately not
correct with FreeRTOS. In the case of FreeRTOS, it only works if the tasks, here P10
and P50, are running from the beginning. If the tasks are stopped and restarted a
little later, incorrect values are calculated. This is due to the fact that the ratio
of the runtime of the individual tasks to the complete runtime of the system is always
It works for TinyCTS and µC/OS-III because a separate statistics task with a
period of 500 milliseconds is used here.
New FreeRTOS statistic
In order to solve the problem with the statistics, the same procedure was implemented
here as with TinyCTS and µC/OS-III. An additional statistics task was used for
this, which recalculates the values every 500 milliseconds.
But there is still a small problem here. If FreeRTOS is operated in preemtive mode,
the calculation of the percentage utilization is correct. But in cooperative mode the
values are 17% too small.
How was this 17% determined?
The P10 and P50 task is used to control the utilization. The values here were
correspondingly 17% too small.
Test performance with iperf / lwIP
For the test here I used an iMX RT1062 Developer's Kit from Embedded Artists.
And for the compiler SEGGER Embedded Studio for ARM v7.30 was used.
For the later performance test, iperf v2.1.9 was used in the terminal on a Mac.
The computer and the evaluation board are connected to each other via a 1GBit
The application was compiled each time in "SDRAM Release" mode and then
loaded into the target's SDRAM with JTAG and started.
Inside the terminal of the Mac iperf was started with: iperf -c 192.168.1.200 -P 1
The cpu load of the target can be checked in the terminal of the target by pressing
With TinyCTS, µC/OS-III and FreeRTOS a bandwidth of 94.9 Mbits/sec could be
achieved. But the CPU load of the target was very different:
- 38% TinyCTS (cooperative)
- 59% µC/OS-III (preemtive)
- 67% FreeRTOS (cooperative, 76% with 17% added)
- 13% FreeRTOS (preemtive, only 55.9 Mbits/sec)
At the moment I have no idea why the performance in case of preemtive mode with
FreeRTOS is lower than in cooperative mode.
And it always surprises me that TinyCTS has the best performance here. I hope that
this is not an error in the calculation of the statistic in TinyCTS.
osal-blinky-ea1062_20230806 example for a Cortex-M7
board (9.01 MB)
osal-lwip-ea1062_20230806 example for a Cortex-M7
board (11.4 MB)