摘要:本文对比了FreeRTOS与裸机模式在瑞萨FSP设计中的区别。裸机模式下,hal_entry中的while(1)是CPU的全部工作;而FreeRTOS模式下,hal_entry仅作为初始化脚本执行硬件Open操作,完成后即退出。若在其中加入while(1)会因优先级问题导致系统卡死。在多线程模式下,main函数仅负责创建任务(如Task_Al_Analysis等)并启动调度器vTaskStartScheduler(),之后CPU将在各任务间切换,main函数后续代码不会执行。

目录

一、FreeRTOS 模式和裸机模式(无 OS)的区别

二、main函数分析


一、FreeRTOS 模式和裸机模式(无 OS)的区别

在瑞萨的 FSP 设计中,hal_entry 依然会被调用,但它的身份变了:

  • 裸机模式(无 OS)main 运行 hal_entry,里面的 while(1) 就是整个 CPU 的全部。

  • FreeRTOS 模式hal_entry 变成了一个初始化脚本。它在第一个线程启动时被顺带调用一次,用来执行硬件的 Open 操作(如 R_IOPORT_Open)。

一旦 hal_entry 里的逻辑跑完,它所在的那个“启动环境”就会功成身退。 如果你在 hal_entry 里写了 while(1),它会因为优先级的原因,可能直接卡死整个系统,让你其他的任务如 Task_Collector 等任务没机会运行。

二、main函数分析

观察一下此时的main函数(以我创建了三个任务的工程为例子)

int main(void)
{
    g_fsp_common_thread_count = 0;
    g_fsp_common_initialized = false;

    /* Create semaphore to make sure common init is done before threads start running. */
    g_fsp_common_initialized_semaphore =
#if configSUPPORT_STATIC_ALLOCATION
                    xSemaphoreCreateCountingStatic(
                    #else
            xSemaphoreCreateCounting (
#endif
                                      256,
                                      1
#if configSUPPORT_STATIC_ALLOCATION
                        , &g_fsp_common_initialized_semaphore_memory
                        #endif
                                      );

    if (NULL == g_fsp_common_initialized_semaphore)
    {
        rtos_startup_err_callback (g_fsp_common_initialized_semaphore, 0);
    }

    /* Init RTOS tasks. */
    Task_Al_Analysis_create ();
    Task_WiFi_Uplink_create ();
    Task_Collector_create ();

    /* Start the scheduler. */
    vTaskStartScheduler ();
    return 0;
}

简化一下

int main(void)
{
    // 1. 初始化一些同步信号量
    // 2. 创建所有你在 FSP 配置里定义的线程
    Task_Al_Analysis_create ();
    Task_WiFi_Uplink_create ();
    Task_Collector_create ();

    // 3. 启动调度器
    vTaskStartScheduler ();

    // 4. 这里的 return 0 永远不会被执行
    return 0;
}

从代码中可以看到目前仅定义了三个任务:

  • Task_Al_Analysis_create()
  • Task_WiFi_Uplink_create()
  • Task_Collector_create()

在多线程模式下,main 函数的任务仅仅是“把舞台搭好(创建任务)”,然后“把幕布拉开(启动调度器)”。一旦 vTaskStartScheduler() 执行,CPU 就只会在各个 Task_xxx 之间来回切换。main函数中接下来的代码,这里是return0 都不会被执行

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐