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 (;;)
    {
        timeout_tick = rtos_next_busy_tick();
        if (platform_pre_suppress_ticks_and_sleep_processing(
          timeout_tick) > some_limit)
        {
            rtos_stop_scheduler();
            platform_pre_sleep_processing();
            platform_post_sleep_processing();
            tick_cnt = how_long_has_I_slept();
            rtos_compensate_system_ticks(tick_cnt);
            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 scheduler

  • rtos_compensate_system_tick compensates ticks counter of RTOS

  • rtos_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.

Table 5.1: Relevant RT-Thread APIs
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.

Table 5.2: Relevant LiteOS APIs
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.

Table 5.3: Relevant ThreadX APIs
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 =
      platform_pre_suppress_ticks_and_sleep_processing(0xffffff);
    if (ticks < 5) return;
    enter_critical();
    platform_pre_sleep_processing();
    platform_post_sleep_processing();
    leave_critical();
    platform_os_idle_resumed_hook();
}