FreeRTOS 学习相关笔记 附C语言内容补充

学习视频为【正点原子】手把手教你学FreeRTOS实时系统

文章目录

    • RTOS 入门
      • 裸机
      • RTOS
      • FreeRTOS
        • 任务调度方式
        • 任务状态
      • FreeRTOS 移植
        • 系统配置文件
    • API函数
      • 任务创建和删除
        • 动态方式创建任务
        • 静态方式创建任务
        • 删除任务
      • 任务挂起和恢复函数
      • 调度器挂起与恢复
        • 临界区
        • 任务调度器的挂起和恢复
      • 中断管理
      • 列表和列表项
        • 简介
        • 列表相关API函数
      • 任务调度
      • 时间片调度
      • 任务状态查询
        • 任务时间统计
      • 延时函数
      • FreeRTOS 消息队列
        • 队列
        • API 函数
      • 信号量
        • 二值信号量
      • 事件标志组
      • 任务通知
        • 简介
      • 软件定时器
    • C语言知识补充
      • 指针函数与函数指针
      • define 和 typedef
      • 句柄和指针

RTOS 入门

裸机

裸机:前后台系统,前台系统指中断服务函数,后台系统指大循环。
裸机中断:是一瞬间的事情,不能处理太多问题。可以用来设置标志位,把执行函数放在主函数里面。

RTOS

1、高优先任务只有处于阻塞状态,才会让出CPU资源,来运行低优先级任务。
2、中断可以打断任意任务,因为中断是为硬件实现,任务优先级为软件实现。

任务优先级数字越大,优先级越高;而中断优先级数字越小,优先级越高

FreeRTOS

FreeRTOS官网

任务调度方式

抢占式调度(不同优先级)

时间片调度(同优先级)
在时间片调度中,一个时间片就是SysTick中断周期;没有用完的时间片不会再使
用。

协程式调度(逐渐淘汰)

任务状态

运行态(同一时间仅有一个任务处于运行态)

就绪态

阻塞态

挂起态 vTaskSuspend() 挂起, vTaskResume() 进入就绪

在这里插入图片描述
就绪列表 pxReadyTaskLists[x],其中x代表任务优先级数值
阻塞列表 pxDelayedTaskList
挂起列表 xSuspendTaskList

  • 新创建任务直接挂载到就绪列表中
  • 32位变量,当某个位置一时,代表所对应的优先级就绪列表有任务

FreeRTOS 移植

移植步骤细节根据《FreeRTOS开发指南》的第二章操作

Source文件夹
加粗样式

portable 文件夹是沟通起软件和硬件的桥梁

系统配置文件

《FreeRTOS开发指南》的第三章介绍

include 配置RTOS中可选的API函数
config 完成FreeRTOS的功能配置和裁剪
其他配置项 PendSV 宏定义、SVC宏定义

API函数

任务创建和删除

动态方式创建任务

xTaskCreate() 自动分配内存
在这里插入图片描述

  • uxTaskGetStackHighWaterMark() 用于获取指定任务的任务栈的历史剩余最小值
  • 任务切换是在中断中进行。可使用临界区保护 taskENTER_CRITICAL() 那些不想被打断的程序段。
  • stm32 栈向下生长,由高地址向低地址;堆向上生长,由低地址向高地址。

任务控制块

在这里插入图片描述

任务栈栈顶,与任务切换有关
每个任务都有属于自己的任务控制块,类似身份证

静态方式创建任务

xTaskCreateStatic()
在这里插入图片描述

删除任务

vTaskDelete()
在这里插入图片描述

  • 传入参数NULL,代表删除任务自身
  • 空闲任务会负责释放被删除任务中由系统分配的内存(静态任务内存需由用户删除前提前释放)

任务挂起和恢复函数

API函数描述
vTaskSuspend()挂起任务
vTaskResume()恢复被挂起任务
xTaskResumeFromISR()在中断中恢复被挂起的任务

xTaskResumeFromISR()函数官网例程

宏:INCLUDE_vTaskSuspend 须置为1

带 FromISR 后缀是在 中断函数 中专用的API函数。
使用该函数需要把 INCLUDE_xTaskResumeFromISR 置为1

中断服务程序中要调用freeRTOS的API函数,则中断优先级不能高于Free RTOS所管理的最高优先级
FreeRTOS 能管理的中断优先级为 5-15

官网解释

  • 如果您使用 STM32 和 STM32 驱动器库, 请通过 调用 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ) 来确保所有优先级位都被指定为抢占优先级位,这一步需要 在启动 RTOS 前完成。

调度器挂起与恢复

临界区

临界段(临界区):必须完整运行,不能被打断的代码段

1、外设:IIC、SPI等需严格按照时序初始化的外设
2、系统或用户自身需求

在这里插入图片描述

1、可以嵌套使用 2、尽量保证临界段代码耗时短

临界区是直接屏蔽了中断,系统任务调度靠中断,ISR也靠中断

中断和任务调度可以打断当前程序的运行

任务调度器的挂起和恢复

挂起任务调度器,调用此函数不需要关闭中断。
仅仅是为了防止任务之间的资源争夺,中断照样可以直接响应。

函数描述
vTaskSuspendAll()挂起任务调度器,uxScheduleSuspend加一
xTaskResumeAll()恢复任务调度器,uxScheduleSuspend减一

中断管理

中断:CPU打断正常运行的程序,转而去处理紧急的事件

关闭中断 portDISABLE_INTERRUPTS()
开启中断 portENABLE_INTERRUPTS()

中断优先级数值越小越优先,任务优先级数值越大越优先

调用 任务延时 vTaskDealy()会进入临界区,而在退出临界区代码时会开启中断

PendSV 和 SysTick 设置最低优先级。保证系统任务切换不会阻塞系统其他中断的响应

FreeRTOS的任务中 只能管理中断优先级在5-15的中断服务

列表和列表项

列表是 FreeRTOS 中的一个数据结构,列表被用来跟踪FreeRTOS中的任务。是一个双向环形链表。
列表项就是存放在列表中的项目

简介

列表结构体
在这里插入图片描述
uxNumberOflterms 不包含 xListEnd末尾列表项

列表项结构体
在这里插入图片描述
xItemValue 多用于按升序对列表中的列表项进行排序

迷你列表项

仅用于标记列表的末尾 和 挂载其他插入列表中的列表项
在这里插入图片描述
列表和列表项关系
在这里插入图片描述

列表相关API函数
函数描述
vListInitialise()初始化列表
vListInitialiseItem()初始化列表项
vListInsertEnd()列表末尾插入列表项
vListInsert()列表插入列表项
uxListRemove()列表移除列表项

vListInsertEnd() 插入到pxIndex指针所指向的列表项前面

参考文档《FreeRTOS开发指南》第七章

任务调度

提前阅读《CortexM3权威指南(中文版)》与《FreeRTOS开发指南》第八章

函数描述
vTaskStartScheduler()启动任务调度器
xPortStartScheduler()启动任务调度器中与硬件架构相关的配置部分,以及启动第一个任务
prvStartFirstTask()初始化启动第一个任务前的环境,主要是重新设置MSP指针,并使能全局中断
vPortSVCHandler()SVC 中断服务函数

在启动第一个任务前关闭中断,启动第一个任务时开启中断

任务切换的本质:CPU寄存器的切换
上下文切换:对任务A保存现场,对任务B恢复现场
任务切换的过程在PendSV中断服务函数里边完成

进程堆栈(psp)中断以外所使用的堆栈,所以保存的就是任务栈;主堆栈指针(msp)在中断内使用

时间片调度

同等优先级任务轮流享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期

宏configUSE_TIME_SLICING 和 configUSE_PREEMPTION 须置1

没有用完的时间片不会再使用,下次执行该任务还是按照一个时间片的时钟节拍运行

任务状态查询

参考《FreeRTOS 开发指南》第11章——FreeRTOS其他任务API函数
在这里插入图片描述
任务优先级范围为 0~31

task_num = uxTaskGetNumber0Tasks();
TaskStatus_t* status_array = 0;
/* 所需申请空间 = 任务数量*结构体大小 @param1: 指向TaskStatus_t结构体数组首地址@param2: 接收信息的数组大小@param3: 系统总运行时间,为NULL则省略总运行时间值返回获取信息的任务数量
*/
status_array = mymalloc(SRAMIN, (sizeof(TaskStatus_t) * task_num));	
task_num2 = uxTaskGetSystemState(status_array, task_num, NULL);

在这里插入图片描述

任务时间统计

滴答定时器: 用来为系统提供时钟节拍
时基定时器: 用于统计任务运行时间

使用流程
1、configGENERATE_RUN_TIME_STATES 置 1
2、configUSE_STATES_FORMATTING_FUNCTIONS 置1
2.1、portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化配置任务运行时间统计的时基定时器
时基定时器的计时精度需高于系统时钟节拍精度的10至100倍
2.2、 portGET_RUN_TIME_COUNTER_VALUE() :用于获取该功能时基定时器计数的计数值

延时函数

函数描述
vTaskDelay()相对延时
xTaskDelayUntil()绝对延时

相对延时:每次延时都是从执行函数 vTaskDelay() 开始,直到延时指定的时间结束
绝对延时:将整个任务的运行周期看成一个整体,适用于需要按照一定频率运行的任务
在这里插入图片描述绝对延时适用于需要按照一定频率运行的任务

FreeRTOS 消息队列

队列

队列是任务到任务、任务到中断、中断到任务 数据交流的一种机制(消息传递)
队列中的每一个数据叫做“队列项目”,队列能够存储“队列项目”的最大数量称为队列的长度

全局变量的弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损

写/读队列时 关闭中断,做好保护,防止多任务同时访问冲突

API 函数
函数描述
xQueueCreate()动态方式创建队列
xQueueCreateStatic()静态方式创建

发送
在这里插入图片描述
接收
在这里插入图片描述

信号量

信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问

二值信号量

本质时一个队列长度为1的队列,该队列就只有空和满两种情况。
通常用于互斥访问或任务同步,但有可能会导致优先级翻转的问题
在这里插入图片描述

事件标志组

事件标志位:用一个位,表示事件是否发生
事件标志组就是一组事件标志位的集合
值为1,表示事件发生了;值为0,表示事件未发生

可以等待某一位成立,或者等待多位同时成立
任意任务或中断都可以读写这些位

在这里插入图片描述

同步函数 xEvenGroupSync()

任务通知

简介

任务通知:用来通知任务,任务控制块中的结构体成员变量 ulNotifiedValue 就是这个通知值。
在这里插入图片描述

任务通知的劣势:
1、无法发送数据给ISR
2、无法广播给多个任务,只能被指定的一个任务接收并处理
3、无法缓存多个数据
4、发送受阻不支持阻塞

任务控制块TCB,里边有两个结构体成员变量:
uint32_t ulNotifiedValue 用来表示通知值
uint8_t ucNotifyState 用来表示通知状态

注意:发送通知API函数可以用于任务和中断服务函数中;接收通知API函数只能用于任务中

发送通知相关API函数
在这里插入图片描述

软件定时器

硬件定时器:在中断服务函数中处理信息
软件定时器:在回调函数中处理信息

**注意:**软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数。

需将 configUSE_TIMERS 配置项配置成1
软件定时器服务任务的优先级为 configTIMER_TASK_PRIORITY = 31,及最高
定时器的命令队列长度为 configTIMER_QUEUE_LENGTH = 5

两种状态:休眠态,运行态
新创建的软件定时器处于休眠态
在这里插入图片描述

xTimerDelete() 软件定时器删除

C语言知识补充

一块空闲的内存

主要用来存储地址和临时变量

指针函数与函数指针

/指针函数函数指针
主体函数指针
需求返回类型为指针(地址)指向一个函数
形式void* f(int x, int y)void (*f)(int x, int y)

()的优先级大于*

define 和 typedef

define 多用于定义常量
typedef 多用于为已有的数据类型创建一个新的名称

句柄和指针

指针
指针 是 栈上 存储 指向堆上空间地址的 变量
在这里插入图片描述
句柄
通俗理解:Handle 门把手,通过门把手来操控门

本质:是对 底层硬件实例的 指针的 引用。
在这里插入图片描述
句柄可以有效节约资源,更高效使用空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/620128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发已解决-Failed to connect to gitee.com port 443: Time out 连接超时提示

文章目录 项目场景:问题描述原因分析:解决方案:解决方案1解决方案2:解决方案3:此Bug解决方案总结解决方案总结**心得体会:解决连接超时问题的三种方案**项目场景: 导入Sample时遇到导入失败的情况,并提示“Failed to connect to gitee.com port 443: Time out”连接超…

实战使用工具appuploader上线发布苹果商店

实战使用工具appuploader上线发布苹果商店 我们发布ios应用的时候,步骤繁琐,非常耗时,appuploader工具就是解决一站式从上传到发布到appstore应用商店的,当我们开发完app后,需要将ipa/apk提交给测试人员测试&#xff0…

【python】No module named ‘pip‘问题

一、问题描述 win11上安装的Python版本有几个&#xff0c;不知道那里出问题了。用pip总是提示&#xff1a; Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line …

完整的JAVA酒店管理系统源码带安装部署文档

完整的JAVA酒店管理系统源码带安装部署文档 002.png (135.63 KB, 下载次数: 0) 下载附件 设为封面 半小时前 上传

鸿蒙开发现在就业前景怎样?

随着科技的不断进步&#xff0c;鸿蒙系统逐渐崭露头角&#xff0c;成为智能设备领域的一颗新星。作为华为自主研发的操作系统&#xff0c;鸿蒙系统拥有着广阔的市场前景和就业机会。那么&#xff0c;鸿蒙开发的就业前景究竟怎样呢&#xff1f; 一、市场需求持续增长 随着鸿蒙…

OpenHarmony源码解析之编译构建

前言 OpenHarmony是由开放原子开源基金会&#xff08;OpenAtom Foundation&#xff09;孵化及运营的开源项目&#xff0c;目标是面向全场景、全连接、全智能时代、基于开源的方式&#xff0c;搭建一个智能终端设备操作系统的框架和平台&#xff0c;促进万物互联产业的繁荣发展…

vue3-计算属性

计算属性 模板中的表达式虽然方便&#xff0c;但也只能用来做简单的操作。如果在模板中写太多逻辑&#xff0c;会让模板变得臃肿&#xff0c;难以维护。 根据作者今年是否看过书展示不同信息 <script lang"ts" setup> import { ref, reactive } from "…

杨中科 .NETCORE ENTITY FRAMEWORK CORE-1 EFCORE 第一部分

一 、什么是EF Core 什么是ORM 1、说明: 本课程需要你有数据库、SOL等基础知识。 2、ORM: ObjectRelational Mapping。让开发者用对象操作的形式操作关系数据库 比如插入: User user new User(Name"admin"Password"123”; orm.Save(user);比如查询: Book b…

C#进阶学习

目录 简单数据结构类ArrayList声明增删查改遍历装箱拆箱 Stack声明增取查改遍历装箱拆箱 Queue声明增取查改遍历 Hashtable声明增删查改遍历装箱拆箱 泛型泛型分类泛型的作用泛型约束 常用泛型数据结构类List声明增删查改遍历 Dictionary声明增删查改遍历 LinkedList声明增删查…

设计模式⑤ :一致性

一、前言 有时候不想动脑子&#xff0c;就懒得看源码又不像浪费时间所以会看看书&#xff0c;但是又记不住&#xff0c;所以决定开始写"抄书"系列。本系列大部分内容都是来源于《 图解设计模式》&#xff08;【日】结城浩 著&#xff09;。该系列文章可随意转载。 …

【Docker】Linux中Docker镜像结构及自定义镜像,并且上传仓库可提供使用

目录 一、镜像结构 1. 基本结构 2. 常用命令 二、自定义镜像 1. 基本镜像 2. 进阶镜像 3. 完善镜像 三、镜像上传仓库 每篇一获 一、镜像结构 自定义 Docker 镜像有很多用途&#xff0c;以下是一些主要的应用场景&#xff1a; 一致性环境&#xff1a;通过自定义镜像&a…

Gauss消去法(C++)

文章目录 算法描述顺序Gauss消去法列选主元Gauss消去法全选主元Gauss消去法Gauss-Jordan消去法 算法实现顺序Gauss消去法列选主元Gauss消去法全选主元Gauss消去法列选主元Gauss-Jordan消去法 实例分析 Gauss消去法是求解线性方程组较为有效的方法, 它主要包括两个操作, 即消元和…

正则表达式Regex

是什么&#xff1a;一句话&#xff0c;正则表达式是对字符串执行模式匹配的技术。 从一段字符串中提取出所有英文单词、数字、字母和数字。 如果采用传统方法&#xff1a;将字符串的所有字符分割成单个&#xff0c;根据ASCII码判断&#xff0c;在一定范围内就是字母&#xff…

pymssql 报错误解决办法:20002, severity 9

错误 解决办法 python3.6&#xff0c;安装pymssql低版本&#xff08;pymssql-2.1.5-cp36-cp36m-win32.whl&#xff09;

【教3妹学编程-算法题】构造限制重复的字符串

3妹&#xff1a;“太阳当空照&#xff0c;花儿对我笑&#xff0c;小鸟说早早早&#xff0c;你为什么背上炸药包” 2哥 :3妹&#xff0c;什么事呀这么开森。 3妹&#xff1a;2哥你看今天的天气多好啊&#xff0c;最近一周都是大晴天&#xff0c;艳阳高照 2哥&#xff1a;是啊&am…

相比其他关系型数据库,亚信安慧AntDB JDBC驱动特性有哪些不同之处

关键字&#xff1a;JDBC&#xff0c;双引擎语法&#xff0c;安全加强&#xff0c;批量更新 使用Java语言进行各类应用程序的快速开发成为目前比较主要且流行的开发方式。JDBC是 Java 语言中用来连接和操作关系型数据库的 API&#xff0c;在业务程序与关系型数据库通信时&#…

一文了解Git(所有命令)附带图片

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 其他…

机器学习算法理论:线性回归

线性回归 回归的理论解释&#xff1a;回归分析是确定两种或两种以上变数间相互依赖的定量关系的一种统计分析方法。按照自变量和因变量之间的关系类型&#xff0c;可分为线性回归分析和非线性回归分析。 如果在回归分析中&#xff0c;只包括一个自变量和一个因变量&#xff0c;…

【Linux】Linux基础之权限

目录 一、Linux中的用户1.1 用户之间的身份切换1.2 指令提权 二、权限管理2.1 文件权限2.2 权限操作2.3 chown和chgrp 三、文件类型四、目录文件的权限操作五、权限掩码六、粘滞位 一、Linux中的用户 Linux中主要有两种用户&#xff1a; root&#xff0c;超级用户非root&…

Netfilter 是如何工作的(六):连接跟踪信息的入口创建(in)和出口确认(confirm)

Articles (gitee.io) IPtables-朱双印博客 (zsythink.net) 在 Netfilter 是如何工作的(五) 中连接跟踪信息使用的创建-确认机制的 Netfilter在报文进入系统的入口处&#xff0c;将连接跟踪信息记录在报文上&#xff0c;在出口进行confirm.确认后的连接信息 本文以一个本机上送…