5 Porting
When using NoOS variants of platform bundles, power saving framework needs to be ported to other RTOS(es). The main work is to port the idle process to the targeting RTOS. The idle process11 looks like this:
void idle_task(void)
{
for (;;)
{
= rtos_next_busy_tick();
timeout_tick if (platform_pre_suppress_ticks_and_sleep_processing(
) > some_limit)
timeout_tick{
();
rtos_stop_scheduler();
platform_pre_sleep_processing();
platform_post_sleep_processing= how_long_has_I_slept();
tick_cnt (tick_cnt);
rtos_compensate_system_ticks();
restart_system_ticks();
rtos_resume_scheduler}
();
platform_os_idle_resumed_hook}
}
What needs to be ported is exactly those rtos_...
functionalities:
rtos_next_busy_tick
returns how many ticks the CPU can be put in sleep modes;rtos_stop_scheduler
stops the schedulerrtos_compensate_system_tick
compensates ticks counter of RTOSrtos_resume_scheduler
resumes the scheduler
how_long_has_I_slept
calculates how long the last sleep was in ticks which is used
to compensates ticks counter of RTOS. The result can be deduced by check system tick
registers of CPU, or use other real-time timer including platform_get_us_time
.
restart_system_tick
restarts system ticks.
Besides, optionally, similar function of PLATFORM_CFG_RTOS_ENH_TICK
needs to be ported too.
The idle process must be the only process having the lowest priority. Some RTOS(es) supported multiple processes have the same lowest priority. Developers should ensure that no other processes are having the lowest priority.
5.1 API
NoOS variants of platform bundles provide a collection of APIs to cooperate the porting.
// Pre-suppress ticks and sleep processing
// @return adjusted ticks to sleep
uint32_t platform_pre_suppress_ticks_and_sleep_processing(
// expected ticks to sleep
uint32_t expected_ticks
);
// Preprocessing for tick-less sleep
void platform_pre_sleep_processing(void);
// Postprocessing for tick-less sleep
void platform_post_sleep_processing(void);
// Hook for idle task got resumed
void platform_os_idle_resumed_hook(void);
5.2 Port to FreeRTOS
FreeRTOS12 is a real-time operating system for micro controllers and small microprocessors. It is a cross-platform RTOS kernel that is distributed freely under the MIT open source license.
Platform binaries that has a built-in RTOS bundles FreeRTOS. NoOS variants are certainly portable to FreeRTOS. The portable can be done by just defining several macros to feed above APIs into FreeRTOS, such as:
#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING(xExpectedIdleTime) \
do { \
xExpectedIdleTime = \
platform_pre_suppress_ticks_and_sleep_processing(xExpectedIdleTime);\
} while (0)
A complete example can be found in SDK repository13.
5.3 Port to RT-Thread
RT-Thread14 is an open source embedded real-time operating system for IoT devices. It has a small size, rich features, high performance and scalability.
rtos_...
functionalities can be mapped to relevant RT-Thread APIs as shown in
Table 5.1.
rtos_... Functionalities |
RT-Thread APIs |
---|---|
rtos_next_busy_tick |
rt_timer_next_timeout_tick |
rtos_stop_scheduler |
rt_enter_critical , rt_hw_interrupt_disable |
rtos_compensate_system_tick |
rt_tick_set |
rtos_resume_scheduler |
rt_exit_critical , rt_hw_interrupt_enable |
A complete example can be found in SDK repository15.
5.4 Port to Huawei LiteOS
Huawei LiteOS16 was a lightweight real-time operating system for IoT devices developed by Huawei. It was open source, POSIX compliant, and has been incorporated into HarmonyOS.
rtos_...
functionalities can be mapped to relevant LiteOS APIs as shown in
Table 5.2.
rtos_... Functionalities |
LiteOS APIs |
---|---|
rtos_next_busy_tick |
OsSleepTicksGet |
rtos_stop_scheduler |
LOS_IntLock |
rtos_compensate_system_tick |
OsSysTimeUpdate |
rtos_resume_scheduler |
LOS_IntRestore |
A complete example can be found in SDK repository17.
5.5 Port to Azure RTOS ThreadX
Azure RTOS ThreadX18 is Microsoft’s Real-Time Operating System (RTOS) for deeply embedded, real-time, and IoT applications. It has a small footprint, fast execution speed, and advanced features such as preemption-threshold scheduling, event chaining.
rtos_...
functionalities can be mapped to relevant ThreadX APIs as shown in
Table 5.3.
rtos_... Functionalities |
ThreadX APIs |
---|---|
rtos_next_busy_tick |
tx_timer_get_next |
rtos_stop_scheduler |
TX_DISABLE |
rtos_compensate_system_tick |
tx_time_increment |
rtos_resume_scheduler |
TX_RESTORE |
A detailed explanation can be found online19.
5.6 Truly No OS
It’s possible to run NoOS bundles without any RTOS, including full functional power saving. A complete example can be found in SDK repository20.
In the example, because there are no software timers, and no next busy tick, the whole idle process couldn’t be simpler:
static void idle_process(void)
{
uint32_t ticks =
(0xffffff);
platform_pre_suppress_ticks_and_sleep_processingif (ticks < 5) return;
();
enter_critical();
platform_pre_sleep_processing();
platform_post_sleep_processing();
leave_critical();
platform_os_idle_resumed_hook}
Since system tick interrupts are disabled during sleep, it is called tick-less low power feature in some RTOS(es).↩︎
https://github.com/ingchips/ING918XX_SDK_SOURCE/tree/master/examples/peripheral_console_freertos↩︎
https://github.com/ingchips/ING918XX_SDK_SOURCE/tree/master/examples/peripheral_console_rt-thread↩︎
https://github.com/ingchips/ING918XX_SDK_SOURCE/tree/master/examples-gcc/peripheral_console_liteos↩︎
https://ingchips.github.io/blog/2022-03-11-threadx-porting/↩︎
https://github.com/ingchips/ING918XX_SDK_SOURCE/tree/master/examples-gcc/peripheral_console_realtime↩︎