RTOS是什么?

RTOS是一款操作系统,相当于Windows\Linux

分为ucos FreeRTOS RT-Thread LiteOS

比裸机开发的优势在于,多任务系统,不必串行

临界区

  • 临界区就是一段执行时不可被打断的代码
  • 操作全局变量不可被打断
  • 临界区的不可被打断机制,导致他不能运行太久,否则会阻塞程序

目录结构

源码放在FreeRTOS/Source文件夹下

  • portable是需要特殊处理适配的
  • include是包含的头文件

代码规范

数据结构

对常见的c语言数据结构重定义

1. #define portCHAR        char
2. #define portFLOAT float
3. #define portDOUBLE double
4. #define portLONG long
5. #define portSHORT short
6. #define portSTACK_TYPE uint32_t
7. #define portBASE_TYPE long
1. typedef int            int32_t;
2. typedef short int16_t;
3. typedef char int8_t;
4. typedef unsigned int uint32_t;
5. typedef unsigned short uint16_t;
6. typedef unsigned char uint8_t;

事实上,上述都是定义在stdint.h中的,因不同的系统Linux\Window\MacOS\RTOS有所不同,作用就是确保不同平台上都精确的占对应的位,占对应的字节(8位一字节)

变量定义

  • char 型变量的前缀是 c

  • short 型变量的前缀是 s

  • long 型变量的前缀是 l

  • 复杂的结构体,句柄等定义的变量名的前缀是 x

  • 变量是无符号型的再加前缀 u,是指针变量则加前缀 p

函数取名

  • 私有函数前加prv

  • 返回值void,前缀v

#define taskYIELD() 表示宏定义在task.h下

任务

概念

单片机写在一个while(1)里,RTOS是内核调度执行。

每一个内核都是一个处理单元,一个内核同时只能处理一个任务

  • 还有一个挂起状态,挂起状态下调度器不可见,如果一个任务较长时间不运行就把他挂起,否则阻塞的话还加个超时判断

创建任务

 ret = xTaskCreate((TaskFunction_t) master_task_main,  /* 任务入口函数 */(1)
“MASTER”, /* 任务名字 */(2)
64*1024, /* 任务栈大小 */(3)
NULL, ,/* 任务入口函数参数 */(4)
TASK_PRIORITY_NORMAL, /* 任务的优先级 */(5)
&task_master_handler); /* 任务句柄指针 */(6)
  • 任务入口函数,是个函数指针,指向要执行的任务。

  • 任务描述名称,字符串形式,最大长度由 FreeRTOSConfig.h 中定义的 configMAX_TASK_NAME_LEN 宏指定,多余部分会被自动截掉,只是方便调试。

  • 任务堆栈大小,单位为字, 4 个字节 uint32_t,这个要注意,否则系统内存紧缺。

  • 任务入口函数形参,不用的时候配置为 0 或者NULL 即可。

  • 任务的优先级,数值越大优先级越高,0 代表最低优先级。基于其SDK开发,可将自定义的所有业务功能task设为同一个优先级,按时间片轮询调度。

  • 任务句柄指针,作用是可以恢复、挂起、删除等等,目前还不知道怎么实现的,也可以直接NULL。

迷糊的一点

void func(){};
void (*p) () = func;

后面可以用p代替func,func代替不了p

  • 但不可以直接void (* p)(){}写函数体,因为这样函数就没名字了

任务调度的时候第一个参数可以填p或&func

任务调度

创建成功后就进入了就绪状态,等待被调度

操作系统的任务调度器只启动一次,且启动了就不返回了,自此之后都由它调度

vTaskStartScheduler()

  • 执行后自动创建空任务和定时器任务。

  • 高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度

  • 相同优先级的任务采用时间片轮转方式进行调度

  • 三个用于任务启动和切换的异常SVC、PendSV 和SysTick,分别用于任务启动、切换、获取时间片

启动方式

都要现在main中初始好硬件和RTOS系统

  1. 所有任务创建完成,启动调度

  2. 创建一个任务,启动调度器,然后在这个任务里创建其他任务,所有任务都创建完成,第一个任务把自己删掉

  3. 为什么要空闲(idle)任务?因为一旦启动就不能停,设置一个优先级最低的空闲任务

状态切换

  • vTaskSuspend(任务函数指针)挂起一个任务

  • vTaskSuspendAll()挂起所有任务

  • vTaskResume(任务函数指针)取消挂起

  • xTaskResumeFromISR(任务函数指针)用于中断,不管被嵌套挂起几次都能解除

  • vTaskDelete(任务函数指针)用于一个任务删除另一个任务。如果是自己删除自身就不用填形参

  • 一般中断服务函数只做标记事件,然后通知其他任务完成其他的事情防止阻塞。

队列

概念

队列是用于任务间通信的特定数据结构

注意:消息空间已满仍在发或者消息空间NULL仍在读,都需要当前任务阻塞等待。

创建

xQueueGenericCreate()申请内存,传入队列占用单元、每个单元字节、队列类型

xQueueGenericReset()初始化,传入队列句柄

发消息

  • xQueueSend()消息拷贝入队,如果是中断里需要用xQueueSendfromISR()

  • 参数依次为:队列句柄、消息、队列满时阻塞超时时间

  • xQueueSendToFrant()队首插入

  • xQueueGenericSend()多个参数,第四个参数表示位置

  • 如果不确定是不是fromISR,就只管发送,让内部判断是系统服务还是中断服务

收消息

xQueueReceive()接收消息并从消息空间删除,记得写阻塞超时的参数

查询

uxQueueMessagesWaiting(句柄)查询队列消息数量

uxQueueSpacesAvailable()查询队列空闲数量

定时器

分类

分为软件定时器、硬件定时器,硬件触发中断且精度高,软件是操作系统封装的接口,基于硬件

  • 通常软件定时器以系统节拍周期为计时单位。系统节拍配置为configTICK_RATE_HZ,该宏在 FreeRTOSConfig.h 中,一般是100或者1000

  • 系统节拍越小开销越大,但也越精确

创建


TimerHandle_t xTimerCreate( const char * const pcTimerName, //定时器名称
const TickType_t xTimerPeriodInTicks, //定时时间
const UBaseType_t uxAutoReload, //是否自动重载
void * const pvTimerID, //回调函数的参数
TimerCallbackFunction_t pxCallbackFunction ) //回调函数
  • 创建成功后处于休眠状态。

    xTimerStart()、

    xTimerReset()、

    xTimerStartFromISR() 、xTimerResetFromISR()

    xTimerChangePeriod()、xTimerChangePeriodFromISR()

    xTimerStop(),xTimerStopfromISR()

    xTimerDelete()
  • 队列和任务都是按需创建一直使用,一般不用删除,但是定时器用完一定要删,而且置句柄NULL

信号量

信号量(Semaphore)是一种实现任务间通信的机制 可以简单认为是为支持多任务同时操作的全局变量

二值信号量

  • 二值信号量看作只有一个消息的队列,因此这个队列只能为空或满

计数信号量

  • 计数信号量则可以被认为长度大于 1 的队列,信号量使用者依然不必关心存储在队列中的消息,只需关心队列是否有消息即可

互斥信号量

优先级翻转问题:假设有任务H,任务M和任务L三个任务,优先级逐次降低。低优先级的任务L抢先占有资源,导致高优先级的任务H阻塞等待,此时再有中等优先级的任务M,它不需要该资源,且优先级高于任务L,它优先执行;之后再执行任务L,最后才执行任务H。看起来就是高优先级的任务反而不如低优先级的任务,即优先级翻转。

任务L先占用资源,任务H申请不到资源会进入阻塞态,同时系统就会把当前正在使用资源的任务L的优先级临时提高到与任务H优先级相同,即使任务M被唤醒了,因为它的优先级比任务H低,所以无法打断任务L,因为任务L的优先级被临时提升到 H;任务L使用完该资源,任务H优先级最高,将接着抢占 CPU 的使用权,这样保证任务H在任务M前优先执行。

事件

计数信号量处理多任务、多中断、多任务与中断同步比较麻烦,引入事件

  • 事件是一种实现任务间通信的机制,可以一对多,多对多,一个任务等待多个事件的触发就叫一对多

RTOS入门的更多相关文章

  1. 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)

    https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...

  2. 16-ESP8266 SDK开发基础入门篇--TCP 服务器 非RTOS运行版,串口透传(串口回调函数处理版)

    https://www.cnblogs.com/yangfengwu/p/11105466.html 其实官方给的RTOS的版本就是在原先非RTOS版本上增加的 https://www.cnblogs ...

  3. 【RTOS】RTOS汇编入门 (1)

    引言 为了提高效率,进行更为底层的操作,RTOS常采用汇编语句,因此了解常用的汇编语句,很有必要 汇编指令 1..equ:类似于c中的#define,表声明常量 例如:.equ PSW 0x10000 ...

  4. 28-ESP8266 SDK开发基础入门篇--编写wifi模块TCP 客户端程序(官方API版,非RTOS版)

    https://www.cnblogs.com/yangfengwu/p/11432795.html 注:这节实现的功能是WIFI模块作为TCP 客户端,连接咱的TCP服务器,然后实现透传 本来想着做 ...

  5. 18-ESP8266 SDK开发基础入门篇--TCP 服务器 RTOS版,串口透传,TCP客户端控制LED

    https://www.cnblogs.com/yangfengwu/p/11112015.html 先规定一下协议 aa 55 02 01 F1 4C 控制LED点亮  F1 4C为CRC高位和低位 ...

  6. 17-ESP8266 SDK开发基础入门篇--TCP服务器 RTOS版,小试牛刀

    https://www.cnblogs.com/yangfengwu/p/11105466.html 现在开始写... lwip即可以用socket 的API  也可以用 netconn  的API实 ...

  7. 2-ESP8266 SDK开发基础入门篇--非RTOS版与RTOS版

    https://www.cnblogs.com/yangfengwu/p/11071580.html 所有的源码 https://gitee.com/yang456/Learn8266SDKDevel ...

  8. 《Cortex-M0权威指南》之Cortex-M0编程入门

    转载请注明来源:cuixiaolei的技术博客 嵌入式系统编程入门 微控制器是如何启动的 为了保存编译号的二进制程序代码,大多数的现代微控制器都会包含片上flash存储器.有些微控制器还可能有一个独立 ...

  9. 如何迅速入门STM32

    我想说,为了学习单片机而去学习单片机的思路不对. 你问,如何系统地入门学习stm32? 本身就是一个错误的问题.假如你会使用8051 , 会写C语言,那么STM32本身并不需要刻意的学习. 你要考虑的 ...

  10. <2013 12 01> 一篇很好的关于windows编程的入门指导(2013年末写的,比较前沿)

    我之前做了不少嵌入式开发,从单片机到ARM到RTOS到Linux等等,可以说走的是电气工程师的路线,对编程也是实用性的,跟计算机学院的科班套路不同.最近同学做一个windowsCE的项目请我帮忙,之前 ...

随机推荐

  1. docker 应用篇————具名挂载和匿名挂载[十三]

    前言 简单整理一下具名挂载和匿名挂载. 正文 来看一下匿名挂载. 这里-v指定了容器内部的路径,但是没有指定容器外部的路径,那么挂载到了什么地方. 用inspect 查看一下. 挂载到这个位置了. 然 ...

  2. 顺通鞋业MES生产工单管理系统软件

    顺通鞋业MES管理系统的"生产执行"是办公室和车间信息交互的枢纽,是一款针对大型鞋业生产企业开发的可配置化智能制造管理系统.工人可以通过车间终端(如安装在机器旁的固定工业触摸屏或移 ...

  3. 力扣118(java)-杨辉三角(简单)

    题目: 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行. 在「杨辉三角」中,每个数是它左上方和右上方的数的和. 示例 1: 输入: numRows = 5输出: [[1], ...

  4. AI和大数据结合,智能运维平台助力流利说提升核心竞争力

    简介: 简介:本文整理自数智创新行--智能运维专场(上海站),流利说最佳实践演讲:<基于SLS千万级在线教育平台统一监控运营实践> 作者:孙文杰 流利说运维总监元乙 阿里云智能技术专家 优 ...

  5. [GPT] golang 有那么多系统包 该如何了解和学习

    在学习和了解Golang(Go语言)的系统包时,可以遵循以下步骤来逐步熟悉并掌握它们: 1. 官方文档阅读: 首先从官方文档入手,Go的标准库文档非常详尽且易于理解.你可以访问 Go标准库 来查看各个 ...

  6. [FE] Quasar BEX 热加载区别: Chrome vs Firefox

    Chrome 浏览器加载扩展程序时指定的是 src-bex 目录.Firefox 指定的是 manifest.json. Quasar 提供的热加载特性是 修改 src/ 目录里的文件,src-bex ...

  7. 修复 WPF 安装 WindowsAppSDK 库构建失败 NETSDK1082 和 NETSDK1112 找不到 win10-arm 失败

    通过在 WPF 项目上安装 WindowsAppSDK 库,可以让 WPF 使用上 Win10 及以上版本提供的 Windows Runtime 强大的 API 集和使用上更多的黑科技.本文记录在安装 ...

  8. dotnet 6 使用 Obfuscar 进行代码混淆

    本文来安利大家 Obfuscar 这个好用的基于 MIT 协议开源的混淆工具.这是一个非常老牌的混淆工具,从 2014 年就对外分发,如今已有累计 495.5K 的 nuget 下载量.而且此工具也在 ...

  9. js的几个截取

    jsfun(){         let str = '01234567'         let str1         str1 = str.slice(2,5)                 ...

  10. 面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?

    一.写在开头 我们在上一篇写ReentrantReadWriteLock读写锁的末尾留了一个小坑,那就是读写锁因为写锁的悲观性,会导致 "写饥饿",这样一来会大大的降低读写效率,而 ...