The FreeRTOS application that is being ported is an example from the AMD Vitis™ Unified IDE. You can find it on the Embedded Software GitHub repository or recreate it in the Vitis Unified IDE by selecting . The Zephyr port of this application is built from scratch. To set up the Zephyr environment, follow the instructions on the Zephyr Getting Started Guide.
Before porting the demonstration application, review the differences in how
FreeRTOS and a Zephyr project are configured. For this application, FreeRTOS has the
option to be configured to have configSUPPORT_STATIC_ALLOCATION set to 0 or 1. If this parameter is
enabled, the tasks, timers, and queues can be called using a special API to have
their memory assigned statically. As mentioned in Table 1, the Zephyr project offers the
same functionality without having to set a configuration parameter.
To start with, FreeRTOS and Zephyr applications require a different set of included files. The FreeRTOS architecture requires an include for each component (timer, task, queue) as well as some AMD-specific includes. Notably, xparameters.h is needed to pass hardware information to the application. Conversely, the Zephyr project includes most of what you might need in a single file called kernel.h. Hardware information is passed on to a Zephyr application through Devicetrees.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
The next part of the application defines some constants. Notably, FreeRTOS timers have a timer ID while Zephyr timers do not. The Zephyr project also offers various ways to generate timeout delays in increments of hours, minutes, seconds, milliseconds, microseconds, and nanoseconds. Because you are using seconds for this example, you can use 1 and 10 rather than defining them in microseconds like in the FreeRTOS application.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
In this section, you are declaring the necessary structures and parameters to create your tasks/threads, timer, and queue later in the code. In the Zephyr example, even though the threads are going to be defined dynamically, the memory is statically allocated.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
The next section is the main() function.
There are a few important differences.
- Priorities in FreeRTOS are structured such that the higher the number the higher the priority of the thread. In the Zephyr project, the opposite is the case and negative numbers can be used as a thread’s priority (this is a special priority type which makes the thread a cooperative thread).
- The FreeRTOS application makes use of a macro called configASSERT(). This macro is typically used in FreeRTOS applications to help debug during development. The Zephyr project also offers debug functionality through various configuration options, which are beyond the scope of this exercise.
- FreeRTOS applications use an API called
vTaskStartScheduler()to start the scheduler. Conversely, the Zephyr project does not use a dedicated API call to start its scheduler. During Zephyr's initialization, scheduling is enabled and spawns system and idle threads. The Cmain()function is called in the context of system threads.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
In the next section, aside from syntactic differences, the TX and RX functions have the same implementation in both FreeRTOS and the Zephyr example.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|
Finally, the timer callback/expiry functions are also very similar. The only
major differences come from the fact that the FreeRTOS application uses a
TIMER_ID parameter and makes use of the configASSERT() macro.
| FreeRTOS Code | Zephyr Code |
|---|---|
|
|