首页 > 其他分享 >2023年薪火培训电控第六讲 —— RTOS

2023年薪火培训电控第六讲 —— RTOS

时间:2023-07-04 15:04:28浏览次数:49  
标签:需要 优先级 中断 RTOS flag 任务 2023 电控

什么是RTOS

RTOS 是实时操作系统(Real-Time Operating System)的缩写。它是一种专门用于实时任务处理的操作系统,用于管理和调度实时任务,并提供与硬件和外部设备的交互接口。

实时操作系统可以根据任务的时间要求和优先级,对任务进行调度和执行,以满足实时性的需求。它提供了任务管理、任务调度、中断处理、资源管理、通信机制等功能,使开发者能够方便地开发和管理实时应用程序。

操作系统

操作系统是一个控制程序,作为硬件和应用程序之间的桥梁,主要是和硬件打交道,负责协调分配计算资源和内存资源给不同的应用程序使用,并防止系统出现故障。面对来自不同应用程序的大量且互相竞争的资源请求,操作系统通过一个调度算法和内存管理算法尽可能把资源公平,有效率地分配给不同的程序。

实时???

实时性主要分为:硬实时和软实时

  • 硬实时:要求任务在严格的时间限制内完成,并绝对不能错过截止时间。即使有一次时间违规,系统的正确性和可靠性也可能受到严重威胁。
  • 软实时:任务有时间约束,但允许偶尔的时间违规。软实时任务的主要目标是在大部分情况下满足时间约束,但偶尔的延迟可能会被接受。

实时性的要求高主要是为了确保系统能够快速、准确地感知和响应各种情况,以提供安全性、稳定性和高效性能。

比如汽车的安全气囊系统,一旦检测到碰撞,系统必须在几毫秒的时间范围内完成气囊的充气,以在乘客撞击前提供必要的保护。任何延迟或错误可能导致安全气囊无法正常充气,从而无法起到保护作用,造成灾难性的后果。

和裸机开发的不同

裸机开发 基于RTOS的开发
在没有操作系统支持的情况下直接编写代码来控制STM32。需要手动编写任务调度、同步和通信机制,以及处理中断和定时器等底层硬件操作。 更高级别的抽象和便利,使开发过程更加简化和高效。适用于需要处理多任务和并发操作的应用程序,同时提供了丰富的功能和组件来管理任务和资源。

现在市面上常见的RTOS有freeRTOS、RT-Thread、µC/OS等等,本节课主要介绍freeRTOS。

freeRTOS

相关背景:
FreeRTOS是一个热门的嵌入式设备用即时操作系统核心,它最初由Richard Barry于2003年左右开发,并由Barry的公司Real Time Engineers Ltd进行后续的开发和维护。2017年,该公司将FreeRTOS项目的管理权交给了亚马逊网络服务(Amazon Web Services,AWS)。Barry继续作为AWS团队的一员继续开发FreeRTOS。

优势

  • FreeRTOS的设计小巧且简易,整个核心代码只有3到4个C文件,为了让代码容易阅读、移植和维护,大部分的代码都是以C语言编写,只有一些函数采用汇编语言编写。
  • 开源,可免费使用

任务的配置和创建

CUBE MX的配置

  1. 根据自己的开发板选择型号
    • 注意自己手上的是C6还是C8,可以给芯片打个光看一下
  2. RCC
  3. SYS,(这里有一点点不同,需要选择一个定时器作为时基
    以选TIM1为例
  4. 在middleware中选择FREERTOS在下拉菜单中选择CMSIS_V1
  5. 配置时钟频率72MHz
  6. 在Project Manager中进行最后的配置(这部分和以前一样),生成代码,打开project

两种任务配置的方法

直接敲代码

  • Task永远不会返回(return),实现需要套在一个死循环内,如果循环结束了需要调用vTaskDelete()进行删除
void myTask(void *pvParameters){
    
    for(;;){
        /* 任务实现的代码 */

        vTaskDelay(/*下一次执行的最短时间间隔*/);
        /* 让任务进入阻塞状态 */
        /* 也可以用osDelay()函数来实现 */
    }
    vTaskDelete( NULL );
    // NULL表示删除当前的任务,也可通过传入其他任务句柄来删除其他任务
}

我们以翻转一个标志位为例为例:

int flag_a = 0;
/* 在程序前面定义 */

void flip_flag(void* parameter) {
   int* p = parameter;
   for (;;) {
      *p = 1;
      *p = 0;
      vTaskDelay(1);
   }
}

完成函数的定义之后,就可以创建任务

创建任务需要调用如下函数:

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
                        const char * const pcName,
                        uint16_t usStackDepth,
                        void *pvParameters,
                        UBaseType_t uxPriority,
                        TaskHandle_t *pxCreatedTask);
参数 含义
pvTaskCode 任务函数指针
pcName 任务名称,只在debug的时候有用,需要具有描述性。但这个参数不会被freeRTOS使用
usStackDepth 栈深度
pvParameters 参数指针,可以在传入任务后转换为需要的数据类型
uxPriority 任务优先级
pxCreatedTask 传出任务句柄的位置,用于在系统运行的时候改变任务的优先级或者删除

RTOS的标识符命名具有一定的规律,可以在下面这篇博客中进一步了解:
freeRTOS名称规范

MX_FREERTOS_Init()函数内创建任务:

   xTaskCreate(flip_flag, "task_0", 128, &flag_a, 0, NULL);

使用Keil进行仿真

在使用之前,需要修改一下keil的配置

  1. 关闭代码优化
    • 将优化级别改为-O0
  2. 配置仿真参数
    • 将debug页面左边的Use StimulatorLimit Speed to Real Time选上
    • 在下面的Dialog DLL中填入DARMSTM.DLL,Parameter中填入-pSTM32F103C6(如果手上的板子是C8就填C8)

配置完成后,就可以进入debug模式

打开逻辑分析器后,将变量添加到里面,并将我们需要查看的标志位添加到逻辑分析器中



运行后即可看到标志位flag_a的变化,说明任务可以正常执行。

同一个函数也可以用来创建多个任务,

   int flag_b = 0;
   xTaskCreate(flip_flag, "task_1", 128, &flag_b, 0, NULL);


两个任务都可以被执行

CUBE MX同样为我们提供了比较简便的配置方式

  • 在CUBE MX中进行配置

    任务需要填入的参数与之前的相同,优先级改为Normal

再次生成工程后,在freertos.c可以找到cube自动生成的代码,我们在StartTask02()的循环中写程序即可,内容与前面的flip_flag()函数类似。

且在MX_FREERTOS_Init()中,cube已经帮我们添加了创建任务的语句,只需要修改传入的参数

注意:在用cube重新生成工程之后,需要再次修改debug的配置

多任务调度

在实际开发的过程中,系统需要执行多个任务来维持自身的稳定,并对外界变化或指令进行相应。不同任务的执行时间和容忍的延迟各有不同,但我们使用的单片机是单核心的,在任意时刻只会有一个任务被执行,因此我们需要对任务进行合理的调度,来满足任务对于实时性的要求。

三种调度算法

  1. 先来先服务(FCFS)调度算法
    按照任务到达的先后顺序进行调度,先到达的任务先执行。这种算法简单直观,但可能导致长任务优先的问题。

  2. 时间片轮转算法
    将任务按照轮询顺序进行调度,每个任务执行一定的时间片(时间片轮转),然后切换到下一个任务。这种算法能够公平地分配CPU时间,但可能导致上下文切换开销较大。

    可以试着将flip_flag()函数中的延迟注释掉,观察逻辑分析器的波形有什么变化

  3. 优先级调度算法
    为每个任务分配优先级,并按照优先级进行调度。具有较高优先级的任务优先执行,但可能导致低优先级任务的饥饿问题。
    可以通过下面的图了解一下

    用Cubemx生成的FreeRTOS默认有七个优先级,这七个优先级定义在了cmsis_os.h中。与中断优先级不同,任务的优先数越大,则优先级越高。

相关文章

  • 20230704赛后复盘
    复盘时间安排8:00~8:30写&调T1,过样例8:30~9:10胡T2,过样例9:10~9:40研究T3,写了个错误的DP,FALSE9:40~9:45看了眼T4,骗了点分9:45~10:00摸T3正解,摸了一大半然后(就没有然后了)部分分正解(100/100)正解(0/100)无骗无解情况(10/?)失误T2没写freopen,寄…题解T1选择一个数替......
  • 智能化新服务即将惊艳亮相HDC2023 ——华为云Astro爆发低代码能量
    HDC期间可参与华为开发者大会Astro新人抽奖活动,活动链接在文末。福利多多,快来参与!跃跃欲试的开发者们,是否对2023华为云开发者大会充满期待?华为云Astro将引领新一轮低代码技术革命!贯穿AIGC技术的低代码新服务破茧而出——自然语言生成工作流!这神秘的魔法技能,即将呈现在各位望眼欲穿......
  • 2023春招面试题:Java并发相关知识
    1.基础知识回顾1.1什么是多线程?在没有线程的年代,在同一个进程中,程序的处理流程都是顺序的,下一个流程的开始必须等待上一个流程的结束,如果其中某一个流程非常耗时,那么会影响整个流程的处理时间cpu执行过程中并不是一个程序执行完之后cpu才切换,cpu时间片用完,就会切换到下个线程......
  • 2023-07-04 如何处理vue中不能监听到父传子组件props的变化
    前言:父传值给子组件,子组件需要根据传进来的值进行watch监听props中的值并遍历插入一个值,然后同时子组件的页面会跟着渲染。问题就是:子组件无法拿到watch更新的props值,比如传进一个list,然后通过watch来监听并在list里面加入一个新的值,前端页面拿不到新的值故而报错。原因:watch无......
  • SummerResearch_Log_20230703
    WorkingContent:1.这几天找到了提取attention层的代码,并且可以实现可视化:https://github.com/luo3300612/Visualizer效果图大概是这样:用这段代码调用函数,attention_maps[3][0,4,:,:]指的是第3层attention层的第4个注意力头的注意力分数。visualize_grid_to_grid_with_cl......
  • C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704
    C#.NETFramework使用BC库(BouncyCastle)RSA私钥签名公钥验签(验证签名)ver:20230704 环境说明:.NETFramework4.6的控制台程序 。 2020年以后,有部分PKCS8私钥(openssl生成)无法用RsaUtil.LoadPrivateKey(strPriPkcs8, "PKCS8")来解析 (https://www.cnblogs.com/runliuv......
  • .NET周报 【7月第1期 2023-07-02】
    国内文章C#实现Linux视频聊天、远程桌面(源码,支持信创国产化环境,银河麒麟,统信UOS)https://www.cnblogs.com/shawshank/p/17420469.html园子里的有朋友在下载并了解了《C#实现Linux视频会议(源码,支持信创环境,银河麒麟,统信UOS)》中提供的源码后,留言给我说,这个视频会议有点复杂......
  • 2023ACM暑假训练day 8-9 线段树
    目录DAY8-9线段树训练情况简介题DAY8-9线段树训练地址:传送门训练情况简介题题意:思路:......
  • 2023/7/3学习日记
    1.温故了原码,反码,补码的概念2.lowbit函数,用来返回二进制数最低位的1:intlowbit(intx){ returnx&(-x);}3.返回二进制数含有多少1的函数:intcnt(intx){ res=0; while(x>0){ res++; x-=lowbit(x); } returnres;}4.算法学习——状态压缩dp,进阶搜索,双向广度......
  • 2023/7/4常见WEB漏洞原理分析
    一、SQL注入漏洞SQL注入攻击(SQLInjection),简称注入攻击、SQL注入,被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞。在设计程序,忽略了对输入字符串中夹带的SQL指令的检查,被数据库误认为是正常的SQL指令而运行,从而使数据库受到攻击,可能导致数据被窃取、更改、......