Blogs | Technical Articles | Videos

Cesium RTOS, a continuation of the popular Micrium µC/ kernels, and FreeRTOS are two popular real-time kernels in the embedded software space. While they are functionally similar and have comparable execution metrics, there are advantages and disadvantages to each of the two product’s APIs. Let’s review some of these differences and make a case for why choosing Cesium RTOS may benefit your project’s overall long-term development and support.

Function Design Differences

There are numerous impactful differences between the software offerings’ APIs. Consider creating a semaphore in FreeRTOS vs Cesium RTOS. FreeRTOS has the following object-creation functions:

  • xSemaporeCreateBinaryStatic()
  • xSemaphoreCreateCounting()
  • xSemaphoreCreateCountingStatic()
  • xSemaphoreCreateMutex()
  • xSemaphoreCreateMutexStatic()
  • xSemaphoreCreateRecursiveMutex()
  • xSemaphoreCreateRecursiveMutexStatic()

Like the semaphore functions shown above, mutexes, and queues use similar variants rather than one unified function for the creation of these kernel objects. This adds to the list of APIs the user must become familiar with.

While these FreeRTOS functions make searching for the specific creation of a counting, binary or static semaphore simpler in your application, there is more effort in understanding each function’s specific purpose. Conversely, with Cesium RTOS the creation of a semaphore or mutex is more straightforward.

  • OSSemCreate()
  • OSMutexCreate()

The arguments you pass will determine which variant of object you create. The simplicity of this approach is that you don’t need to step through multiple redirected creation functions while debugging or familiarizing yourself with the different usages of numerous FreeRTOS counterparts. With the OSSemCreate() function, you can create a binary, counting or static semaphore based on your argument values, setting the initial count and defining the semaphore data object as a static variable or not. These variances in the arguments passed into the create function allow you to create the same type of objects as FreeRTOS without needing separate functions for each. Operationally speaking there is no loss of functionality with Cesium RTOS, just fewer APIs to learn, manage and maintain when debugging.

 

Descriptive Debugging

With FreeRTOS, the Semaphore and Queue creation functions funnel into the “overloaded” instance of their equivalent queue functions. For example:

xSemaphoreCreateCounting()  xQueueCreateCountingSemaphore()

xSemaphoreCreateBinary() → xQueueCreateGeneric()

xSemaphoreCreateMutex() → xQueueCreateMutex() → xQueueGenericCreate()

Tracking errors during debugging becomes more difficult with the increasing depth of function nesting. Debugging the creation of a semaphore, queue or mutex in Cesium RTOS is simplified due to the cleaner call stack. This makes figuring out points of failure or misconfigurations more straightforward. Another example is how the xSemaphoreTake() function funnels into the xQueueSemaphoreTake() function which is quite a large all-encompassing function. It’s logically split into two parts depending on if it was called from a Semaphore or Queue. The extra condition handling makes the function more complex to navigate when debugging. In contrast, the creation functions in Cesium RTOS are more straightforward, short, and optimal for quickly debugging and discerning an issue. Performance wise both are very nearly the same, but from the developer’s point of view, the Cesium RTOS code will be much easier to follow.

 

Feature Differences

Although the functionality provided by both kernel solutions is similar, Cesium RTOS offers several quality-of-life benefits and some unique features of its own. Some of these include more descriptive error return codes, off-the-shelf compatibility with the Cesium suite of software stacks, and overall code cleanliness. Let's cover some of these in detail.

 

Error Return Codes

FreeRTOS return codes are very straightforward and simple. There are typically two values of the return code given from calling their API. pdPASS, pdFAIL, pdTRUE and pdFALSE is what most functions return. For slightly more descriptive return codes some functions may return the values errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, errQUEUE_BLOCKED, errQUEUE_YIELD, errQUEUE_BLOCKED, or errQUEUE_YIELD. That’s all the variance that exists in the error code returns which can pose problems. When trying to instrument code to allow for failure recovery or more intricate error handling, this doesn’t give much detailed feedback. vSemaphoreDelete() perfectly illustrates a function with a lack of error returns. This function utilizes vQueueDelete(). This function’s return code is void which can make it tricky to test if the result of that function was a failure or a success. The queue object can be evaluated to see if it was deleted afterward but it does not appear to set the queue object to something predictable in a failure situation.

/**
* queue. h
* <pre>void vQueueDelete( QueueHandle_t xQueue );</pre>
*
* Delete a queue - freeing all the memory allocated for storing of items
* placed on the queue.
*
* @param xQueue A handle to the queue to be deleted.
*
* \defgroup vQueueDelete vQueueDelete
* \ingroup QueueManagement
*/

void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;

By comparison, Cesium RTOS has a rich array of error return values and messages available to developers that are utilized throughout its APIs. All public-facing OS function APIs accept an (OS_ERR *) type argument. This variable is given a value to reflect the success or failure reasoning when its execution completes. This added detail enables a more precise debugging experience. When you’re saddled with a large application to debug, this additional detail will noticeably impact your development time. For comparison, consider the equivalent Cesium RTOS OSSemDel() function. This function, as previously stated, accepts an (OS_ERR *) type argument which can return one of the following values.

* p_err  is a pointer to a variable that will contain an error code returned by this function.
*
*            OS_ERR_NONE                    The call was successful and the semaphore was deleted
*            OS_ERR_DEL_ISR                 If you attempted to delete the semaphore from an ISR
*            OS_ERR_ILLEGAL_DEL_RUN_TIME    If you are trying to delete the semaphore after you called
*                                             OSStart()
*            OS_ERR_OBJ_PTR_NULL            If 'p_sem' is a NULL pointer
*            OS_ERR_OBJ_TYPE                If 'p_sem' is not pointing at a semaphore
*            OS_ERR_OPT_INVALID             An invalid option was specified
*            OS_ERR_OS_NOT_RUNNING          If uC/OS-III is not running yet
*            OS_ERR_TASK_WAITING            One or more tasks were waiting on the semaphore

This detailed assortment of error values allows developers to design code that can handle error conditions with more nuance during runtime. This makes debugging, trapping certain return values, and pinpointing error locations simpler. Rather than digging down several layers deep into the call stack, the returned error code can be examined to understand what is happening and allow for ease of correcting.

 

Supporting Software Stacks

Another advantage of Cesium RTOS is the offering of supporting products within its software suite. The code design and standards are the same among the Cesium products. This unified approach makes the developer’s learning experience much smoother. Learning to utilize the Cesium RTOS software stacks draws on the API similarity of the other stacks within the suite, strengthening user familiarity and proficiency.

FreeRTOS, being widely used, also has many supporting 3rd party software stacks. However, these products have varying code design standards making navigating each one more challenging. Not only must developers learn a new product but also must become familiar with a new layout style. Porting and integration is possible but becomes more challenging. However, the full line of Cesium RTOS software offerings is designed with interoperability in mind. This aids in speeding up a developer’s learning curve when incorporating new software stacks. Cesium RTOS offers the following product stacks:

  • A file system Cs/FS
  • A network stack Cs/NET with a wide array of application stacks like HTTP, DHCP, and others
  • A USB-Device stack Cs/USBD
  • A USB-Host stack Cs/USBH
  • A Modbus stack Cs/Modbus

There is also support for SSL solutions, Graphical User Interfaces, and other 3rd party offerings.

 

Clean Code

If you’re familiar with any of Micrium’s software stacks you know that clean code is an integral part of the software. There is an important reason for this. The code truly is easier to follow. For example, typically it’s easier to read and understand a diagram when its description is on the same or following page. When the diagram and its breakdown are multiple pages apart it becomes increasingly difficult to follow with the repeated scrolling back and forth. When looking at code, having code and comments mixed into the left column makes it harder to separate the two and focus on one at a time. For this reason, Cesium RTOS code is divided with code on the left and comments on the right. Granted, this has no real performance improvements and is entirely geared toward the user experience. It should be noted that working with code that’s easier to follow has distinct advantages. The cleaner and clearer something is, the simpler it is to learn, utilize and support over time. This makes understanding the Cesium RTOS code easier and thus saves time getting to the development phase.

 

In Conclusion

While the FreeRTOS and Cesium RTOS solutions are similar in performance and feature set, there are advantages to the user experience that Cesium RTOS offers. There are many factors involved in selecting the best RTOS for an application, including performance, functionality, and reliability to name a few. Equally important to developers is the level of effort required to become proficient with the RTOS features and their long-term ease of use (which includes application debugging, an often-overlooked phase of the development cycle.) As your application grows, new feature sets are added and the overall project complexity increases. Cesium RTOS’ built-in user experience enhancements allow you to be more efficient and help improve your productivity in complex applications.