FreeRTOS笔记——多任务系统

0 概述

部分内容参考野火的FreeRTOS相关开发资料,在此做一个学习记录总结。

1 裸机系统与多任务系统

1.1 裸机系统

做51单片机开发的人比较熟悉,在实现LED流水灯时,使用while(1)配合简单延时函数,循环配置引脚寄存器输出高低电平实现灯的亮灭,这个就是属于最常见裸机系统。
裸机系统通常分为轮训系统和前后台系统。

  • 轮询系统
    上面的LED翻转的例子就是轮训系统,一般适用于只需要顺序执行代码,且不需要关心外部事件驱动,如按键检测等。
    伪代码如下:
int main(void) 
{ 
    /* 硬件相关初始化 */ 
    HardWareInit(); 
 
     /* 无限循环 */ 
     for (;;) { 
         /* 处理事情 1 */ 
         DoSomething1(); 
  
         /* 处理事情 2 */ 
         DoSomething2(); 
  
         /* 处理事情 3 */ 
         DoSomething3(); 
     } 
 } 

轮询系统有什么缺点呢?
假设事件3中需要处理一个按键检测的动作,但是按键按下去的时候,正在执行任务1,并且任务1很耗时,这样按键检测的动作就被遗漏了。
并且,如果每个事件都需要及时被处理,但是存在个别事件的处理是耗时的,那么其他事件就只能等待,造成事件处理延时。

  • 前后台系统
    我们将mian函数里面的循环称为后台,中断称之为前台。
    在轮询系统的基础上引入中断机制,外部时间的响应在中断里面完成,如果时间处理不耗时,则可以在中断里面直接处理,否则要将事件的处理放到轮训系统中,一般建议将事件的处理放到后台任务处理。
    伪代码如下:
int flag1 = 0; 
int flag2 = 0; 
int flag3 = 0; 
 
int main(void) 
{ 
    /* 硬件相关初始化 */
    HardWareInit();
 
    /* 无限循环 */ 
    for (;;) { 
        if (flag1) {
            /* 处理事情 */
            DoSomething1();
        } 
 
        if (flag2) {
            /* 处理事情 */
            DoSomething2();
        } 
 
        if (flag3) {
            /* 处理事情 */
            DoSomething3();
        } 
    } 
} 
 
void ISR1(void) 
{ 
    /* 置位标志位 *
    flag1 = 1; 
    /* 如果事件处理时间很短,则在中断里面处理
       如果事件处理时间比较长,在回到前台处理
     */
    DoSomething1();
} 
 
void ISR2(void) 
{ 
    /* 置位标志位 */
    flag2 = 1; 
 
    /* 如果事件处理时间很短,则在中断里面处理
       如果事件处理时间比较长,在回到前台处理
     */
    DoSomething2();
} 
 
void ISR3(void) 
{ 
    /* 置位标志位 */
    flag3 = 1; 
    /* 如果事件处理时间很短,则在中断里面处理
       如果事件处理时间比较长,在回到前台处理
     */
    DoSomething3(); 
} 

相对轮询系统,前后台系统有什么优势呢?
将事件的响应和处理分开了,虽然事件的处理还是在后台程序中,但是前后台系统确保了事件不会丢失,加上中断可以嵌套,因此大大提高了程序的实时响应能力。
在大多数中小型项目中,前后台系统运用的很好。

1.2 多任务系统

多任务系统的时间响应也是在中断中完成,但是事件的处理是在任务中完成,可以认为是和main类似的后台任务模块。
那么什么是任务呢?
我们把程序主体分割成一个个独立的、无限循环、不能返回的小程序,这样的小程序我们称为任务。
应用中为满足不同的需求,会存在多个任务,与前后台系统的后台main处理不同。多任务系统的每个任务和中断一样,也具有优先级,优先级高的任务会被优先执行。当一个紧急的事件在中断被标记后,如果事件的优先级足够高,就会得到立马响应,获取CPU控制权。相比前后台系统,多任务系统的实时性又被提高了,不需要等待其他事假处理完毕才能对自身事件进行处理。
具体的任务调度是由操作系统进行调度管理。
加入多任务系统之后,我们编程的时候就不需要太过于精心的设计程序执行流程,以及担忧各个模块之间的干扰,编程的重点转移到业务实现上,总的来说,编程变得简单了。

1.3 小结

轮询、前后台、多任务系统均有其使用场景,不能一句话判定孰优孰劣。
三种软件系统的区别如下:

模型事件响应时间处理特点
轮询系统main主程序main主程序轮询响应事件,轮询处理事件
前后台系统中断main主程序中断响应事件,轮询处理事件
多任务系统中断任务实时响应事件,实时处理事件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS中,可以使用动态方式创建多任务。首先,通过调用`xTaskCreate()`函数来创建任务。这个会返回一个任务句柄,可以用来后续操作该任务任务的创建需要指定任务函数、任务名称、任务栈大小、任务优先级等参数。任务函数是任务的实际执行代码,可以在其中编写所需的任务逻辑。任务栈大小是为任务分配的内存空间大小,可以根据任务的需求进行合理设置。任务优先级用于任务调度,可以根据任务的重要性和实时性进行适当设置。 在任务创建完成后,可以使用任务句柄来进行任务的操作,如挂起任务、恢复任务、删除任务等。可以使用`vTaskSuspend()`函数来挂起任务,使用`vTaskResume()`函数来恢复任务,使用`vTaskDelete()`函数来删除任务。 需要注意的是,动态创建的任务需要手动管理任务句柄的分配与释放。可以定义一个任务句柄指针,通过函数返回的任务句柄来进行赋值,以便后续操作任务。 以下是一个示例代码,用于动态创建两个任务: ```c TaskHandle_t task1_handle; TaskHandle_t task2_handle; void task1(void *pvParameters) { // 任务1的代码逻辑 } void task2(void *pvParameters) { // 任务2的代码逻辑 } void create_tasks() { // 创建任务1 xTaskCreate(task1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, &task1_handle); // 创建任务2 xTaskCreate(task2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, &task2_handle); } int main() { // 初始化FreeRTOS等操作 // 创建任务 create_tasks(); // 启动任务调度器 vTaskStartScheduler(); // 任务调度器不会返回,因此以下代码永远不会执行 while (1) { // 其他任务的代码逻辑 } } ``` 在上述代码中,`create_tasks()`函数用于创建两个任务,并分别传入相应的任务函数、任务名称、任务栈大小、任务优先级等参数。创建完成后,通过任务句柄`task1_handle`和`task2_handle`来操作任务。 请注意,以上只是一个示例,实际情况下可以根据需要创建更多的任务,以满足系统的需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [FreeRTOS创建动态任务(SRAM动态内存)](https://blog.csdn.net/m0_46579704/article/details/128003729)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值