21.0.1-为什么要讲RTOS?第21章-FreeRTOS项目实战--基础知识之新建任务、启动流程、编码风格、系统配置 21.0-为什么要讲FreeRTOS(掌握)

这个是全网最详细的STM32项目教学视频。
第一篇在这里:
视频在这里:

https://www.bilibili.com/video/BV16x4y1M7EN/?share_source=copy_web&vd_source=f5d5850ab773377dff308188468fbc77

STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随)]
V3:HAL库开发、包括下面功能:PID速度控制、PID循迹、PID跟随、遥控、避障、PID角度控制、openmv视觉控制、电磁循迹、FreeRTOS、K210视觉智能车(更新中)、K230视觉智能车(更新中)、MSPM0G3507视觉智能车(更新中)

在这里插入图片描述

第21章-FreeRTOS项目实战–基础知识之新建任务、启动流程、编码风格、系统配置

了解:明白大概怎么一回事,为后面学习打下基础,或者是留以后检索使用

**掌握:**理解所讲内容,并且会用

熟练:能供迁移应用其他方面

精通:深入掌握理解原理,明白优势劣势,能供迁移应用。

我们后面使用FreeRTOS会完成之前裸机的功能,加入FreeRTOS之前应该需要先测试过之前的裸机程序是否正常,这样后面如果加入FreeRTOS有异常,可以确定是本身功能代码有问题还是移植FreeRTOS带来的问题。
在这里插入图片描述

21.0-为什么要讲FreeRTOS(掌握)

21.0.1-为什么要讲RTOS?

之前我们都使用裸机编程已经完成了前面的功能,难道加入RTOS后就能够完成裸机做不了的功能吗? 答案是否定的,RTOS并不能让单片机完成裸机完全不能实现的功能。

但是,RTOS的优势在于它通过实时任务调度和资源管理,实现多任务并行、精确时间控制和高效任务间通信,从而简化复杂系统的开发与维护

这些话也许有些难以理解,这里举一个栗子。

我们想设计一个温度控制器,具有一下四个模块:按键扫描、数码管显示、温度获取、温度加热。
在这里插入图片描述
大循环中 任务轮流执行

int main(void)
{
    while(1)
    {
		task_temperature_get();//温度数据获取
        delay(100);
        task_led_show();//显示
        delay(100);
        task_key_scan(); //按键检测
        delay(100);
        task_temperature_set(); //温度控制器控制
        delay(100);
        printf("\n\n");
        return 0; 
     }
}

上面程序设置会有一些问题,比如每个任务要求自己的执行频率不同,按键任务需要频繁执行,温度获取任务执行频率不需要那么 快,而且尽量任务的执行干扰减少,温度获取任务的执行速度变化 不能应该到按键任务的执行频率。

所以我们需要编写方便调整任务执行频率的代码结构。

使用定时器 定时执行不同函数任务

unsigned int count; //定义一个全局计数器
void count_add(void)
{
    for(int i = 0;i <500000 ;i++)//假设每一毫秒变量增加一次
        cout++;
}
int main(void)
{
    while(1)
    {
        count_add();//1毫秒延时
        if(count % 1000 == 0)
            task_temperature_get();//温度数据获取
        if(count % 100 == 0)
            task_led_show();//显示
        if(count % 200 == 0)
            task_key_scan(); //按键检测
        if(count % 2000 == 0)
            task_temperature_set(); //温度控制器控制
    }
    return 0;
}

上面我们在一个大循环中使用了一个计数函数count_add,通过根据计数值count的变化来控制任务执行频率,实际单片机编程中,比如count 是硬件定时器中控制增加的变量,比如每1毫秒增加一次,那么上述程序就会实现 task_temperature_get每1000毫秒执行一次,task_led_show函数每100毫秒执行一次。

所以我们就会通过上面的方法实现每个任务都可以进行调节执行频率。

但是还有一个问题,无法修改每个程序的执行顺序,每个任务都有轻重缓急之分,有的任务十分重要,比如task_led_show();显示任务 和task_key_scan();按键同时可以执行时候,我应该优先让task_key_scan();按键 执行。

使用定时器 定时执行不同函数任务 加入函数指针区分优先级

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int task_delay[4] = {0};
//任务一函数内容
void task1(void)
{
    task_delay[0] = 10;//任务的延时时间表示任务10秒后会得到执行
    printf("task1....\n");   
}

//任务二函数内容
void task2(void)
{
    task_delay[1] = 4;//表示任务延时时间 4秒后会得到执行
    printf("task2....\n");   
}
void task3(void)
{
    task_delay[2] = 4;//任务4秒后会得到执行
    printf("task3....\n");   
}
void task4(void)
{
    task_delay[3] = 1;//任务1秒后会得到执行
    printf("task4....\n");   
}
void timer_interrupt(void)//该函数会每一秒执行一次 这个是延时函数的作用 代表任务在执行 进行一定的延时 
{
    for(int i = 0;i<4;i++)//遍历四个任务
    {
        if(task_delay[i])//检测每个任务是否延时时间为零,不为零就减延时时间
            task_delay[i]--;        
    }
    alarm(1); 
}
void(* task[])(void) = {task1,task2,task3,task4};//定义函数指针数组 元素是各个任务的函数指针,该指针分别指向四个任务函数
int main(void)
{
    signal(SIGALRM,timer_interrupt); // 注册信号处理函数
    alarm(1);// 设置定时器,1秒后发送SIGALRM信号 就是每一秒执行一次
    int i;
    while(1)
    {
        for(i = 0;i<4;i++)//遍历四个任务
        {
            if(task_delay[i] == 0)//如果该任务的延时时间为零,就执行该任务
            {
                task[i]();//执行对应任务
                break;
            }
        }
    }
   return 0; 
}

上面通过定义一个函数指针数组,来存放各个任务的函数指针,高优先级的任务放在数组前面,低优先级的任务在数组后面,在main函数中,根据每个任务的演示是否到期,来决定是否执行这个任务。比如当出现两个任务同时到期时候,因为高有优先级任务的函数指针放在数组前面,会被先遍历到,所以会先执行。通过这样的巧妙设计,可以让优先级的任务先执行。

通过上面的程序我们 可以体验到裸机的局限性,并且通过使用 函数指针数组 发现可以提高编程裸机程序效率。

其实电子产品现在又很多功能,但是使用的MCU往往是单核的,于是为了更好完成功能,我们加入FreeRTOS,因为FreeRTOS的内置算法让cpu在不同任务之间快速切换执行,这 样就会看起来实现了“多任务” "同时"执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值