![](https://img-blog.csdnimg.cn/20201014180756919.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
FreeRTOS
文章平均质量分 67
成草
这个作者很懒,什么都没留下…
展开
-
任务通知详解
前言1、从 v8.2.0 版本开始,FreeRTOS 新增了任务通知(Task Notifictions)这个功能,可以使用任务通知来代替代队列、二值信号量、计数型信号量和事件标志组。使用任务通知来实现二值信号量功能的时候,解除任务阻塞的时间比直接使用二值信号量要快 45%,并且使用的 RAM 更少2、使用限制:● FreeRTOS 的任务通知只能有一个接收任务,其实大多数的应用都是这种情况。● 接收任务可以因为接收任务通知而进入阻塞态,但是发送任务不会因为任务通知发送失败而阻塞。API发送任原创 2021-11-30 10:26:13 · 543 阅读 · 0 评论 -
事件标志组
前言1、用于任务可与多个事件或任务进行同步,只能使用事件标志组(或者任务通知模拟事件标志组),此时信号量就无能为力了2、configUSE_16_BIT_TICKS 为 0 的时候,EventBits_t 类型的变量可以存储 24 个事件位,另外的那高 8 位有其他用。事件位 0 存放在这个变量的 bit0 上,变量的 bit1 就是事件位 1,以此类推。对于 STM32 来说一个事件标志组最多可以存储 24 个事件位。 configUSE_16_BIT_TICKS 为 1 的时候事件标志组可以存储 8原创 2021-11-30 10:13:12 · 513 阅读 · 0 评论 -
HAL库配置FreeRTOS
HAL库配置1:修改HAL库定时器时钟源。 由于HAL库内部会使用systick定时器用于系统延时功能,而FreeRTOS也需要一个定时器用于操作系统内核调度的使用,顾需修改HAL库的时钟源。由于用了TIM1作为HAL库的时钟源,所以会自动创建定时器中断的回调函数HAL_TIM_PeriodElapsedCallback(定时器中断回调函数就这么一个),所以我们如果想用定时器中断回调函数就直接用这个就行(在main.c中,如果在写一个,就会报错重复定义)2:配置FreeRTOS内核功能1)暂时只需原创 2021-11-28 16:01:51 · 2699 阅读 · 0 评论 -
软件定时器
前言1:硬件定时器:CPU内部自带的定时器模块,通过初始化、配置可以实现定时,定时时间到以后就会执行相应的定时器中断处理函数。硬件定时器一般都带有其它功能,比如PWM输出、输入捕获等等功能。但是缺点是硬件定时器数量少!!2:软件定时器:软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数(我们在创建软件定时器时指定时间到达后要调用的函数),被定时器调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期,简而言之,当定时器的定时周期到了以后就会执行回调函数。3原创 2021-10-22 16:48:07 · 1280 阅读 · 0 评论 -
信号量详解
前言1:信号量作用:共享访问资源,与任务同步2:FreeRTOS中信号量分为如下几种:1)二值信号量:更适合用于同步(任务与任务或任务与中断的同步),没有优先级继承。 二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的2)计数型信号量3)互斥信号量:与二值信号量类似,适用于互斥访问4)递归互斥信号量:除了这个其他都用xSemaphoreGive释放信号量和xSemaphoreTake获取信号量二值信号量API1:更适合用于同步(任务与任务或任务与中断的同步),没原创 2021-10-22 14:22:46 · 1769 阅读 · 0 评论 -
消息队列详解
前言1:在没有os时中断与任务,任务与任务之间进行消息传递依靠全局变量,但是如果在使用了OS的应用中使用全局变量会涉及到“资源管理的问题”。所以,在FreeRTOS中使用其提供的消息队列进行消息的传递2:当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为原创 2021-10-21 14:48:52 · 493 阅读 · 0 评论 -
FreeRTOS原函数库API
xTaskCreateStatic静态任务创建1:任务使用的栈和任务控制块都使用静态内存,即预先定义好的全局变量,这些预先定义好的全局变量都存在内部的 SRAM 中。2:任务的栈占用的是 MCU 内部的 RAM,当任务越多的时候,需要使用的栈空间就越大,即需要使用的RAM 空间就越多。一个 MCU 能够支持多少任务,就得看你的 RAM 空间有多少3:将任务主体函数,任务栈(静态的)和任务控制块(静态的)这三者联系在一起,让任务可以随时被系统启动4:自己需要预先创建任务堆栈,任务控制块,任务句柄/*原创 2021-10-19 15:05:42 · 2646 阅读 · 0 评论 -
支持时间片
前言1:所谓时间片就:是同一个优先级下可以有多个任务,每个任务轮流地享有相同的 CPU 时间,享有 CPU 的时间我们叫时间片。2:在 RTOS 中,最小的时间单位为一个 tick,即 SysTick 的中断周期。RT-Thread 和 μC/OS 可以指定时间片的大小为多个 tick,但是 FreeRTOS 不一样,时间片只能是一个 tick。与其说 FreeRTOS 支持时间片,倒不如说它的时间片就是正常的任务调度。3:实验原理:之所以在同一个优先级下可以有多个任务 ,最终还是得益于taskRES原创 2021-10-18 14:14:56 · 111 阅读 · 0 评论 -
任务延时列表的实现
一:前言1:针对上篇延时的缺点(在每个时基中断中需要对所有任务都扫描一遍,费时),进行优化。使用任务延时列表2:任务延时列表工作原理:当任务需要延时的时候,先将任务从就绪列表删除,然后插入到任务延时列表,同时更新下一个任务的解锁时刻变量:xNextTaskUnblockTime 的值(xNextTaskUnblockTime =系统时基计数器的值 xTickCount +任务需要延时的值 xTicksToDelay)当系统时基计数器 xTickCount 的值与 xNextTaskUnblockTime原创 2021-10-18 09:17:05 · 117 阅读 · 0 评论 -
支持多优先级
一:前言1:在之前的文章中,FreeRTOS 还没有支持多优先级,只支持两个任务互相切换,从本章开始,任务中开始加入优先级的功能。在 FreeRTOS 中,数字优先级越小,逻辑优先级也越小,这与隔壁的 RT-Thread 和 μC/OS 刚好相反。2:就绪列表 pxReadyTasksLists[ configMAX_PRIORITIES ]里面存的是就绪任务的 TCB 里面的 xStateListItem 节点,数组的下标对应任务的优先级(相同优先级的),优先级越低对应的数组下标越小。空闲任务的优先级原创 2021-10-15 15:47:24 · 121 阅读 · 0 评论 -
空闲任务与阻塞延时的实现
一:前言1:RTOS 中的延时叫阻塞延时,即任务需要延时的时候,任务会放弃 CPU 的使用权,CPU 可以去干其它的事情,当任务延时时间到,重新获取 CPU 使用权,任务继续运行,这样就充分地利用了 CPU 的资源,而不是干等着。2:如果任务都延时了进入阻塞状态,任务可以运行,这个时候 CPU 就会运行空闲任务。在FreeRTOS 中,空闲任务是系统在【启动调度器】的时候创建的优先级最低的任务,空闲任 务主体主要是做一些系统内存的清理工作。但是为了简单起见,我们本章实现的空闲任务只是对一个全局变量进行原创 2021-10-15 11:21:57 · 223 阅读 · 0 评论 -
临界段代码保护
前言1:临界段:在执行的时候不能被中断的代码段,最常见的是对全局变量的操作,能关闭的最大中断 由这个宏决定configMAX_SYSCALL_INTERRUPT_PRIORITY 他是按照单片机的中断等级的,比他小的都不能控制,因为操作的是单片机中的寄存器2:在FreeRTOS中,对中断的开关是通过操作BASEPRI寄存器来实现的。当他设置为5时,所有优先级号>=5的中断都被关闭(等级比他低的都关掉)。若设置为0,则不关闭任何中断1:关中断不能在中断里面使用的/*1:不带返回值的关中断函数,不能嵌原创 2021-10-14 17:01:18 · 2699 阅读 · 0 评论 -
实现调度器
实现调度器vTaskStartScheduler启动调度器,开始多任务调度,启动成功则不返回,就在各种任务中不断切换着1:创建空闲任务2:#if ( configUSE_TIMERS == 1 )使用软件定时器3:使能 NEWLIB4:xTickCount = ( TickType_t ) 05:调用函数 xPortStartScheduler()来初始化跟调度器启动有关的硬件,比如滴答定时器、FPU 单元和 PendSV 中断等等xPortStartScheduler内核相关硬件初始化函数原创 2021-10-26 10:32:29 · 167 阅读 · 0 评论 -
任务切换分析
任务切换任务切换就是在就绪列表中寻找优先级最高的就绪任务,然后去执行该任务,但是现在编写的还不支持优先级,仅实现两个任务的轮流切换#define taskYIELD() portYIELD() //任务切换的本质就是将PendSV的悬起位置1,当没有其他中断运行的时候相应PendSV中断,去执行PendSV中断服务函数,在里面实现任务切换#define portYIELD() \{ \ /* 触发PendSV,产生上下文原创 2021-10-29 15:18:24 · 870 阅读 · 0 评论 -
任务的创建
任务创建1:定义任务栈//任务栈就是全局数组#define TASK1_STACK_SIZE 128StackType_t Task1Stack[TASK1_STACK_SIZE]; //就是uint32_t数组1)栈是单片机RAM里面一段连续的内存空间,栈的大小一般在启动文件或者链接脚本里面指定,最后有c库函数-main进行初始化2)任务堆栈用来存放各种环境参数,比如:系统运行时的全局变量,子函数调用时的局部变量,中断发生时函数的返回地址3)128原创 2021-10-14 15:27:36 · 232 阅读 · 0 评论 -
任务管理_
前言1:调度器:决定运行哪个任务。调度器会不断的启动、停止每一个任务,宏观看上去所有的任务都在同时在执行。作为任务,不需要对调度器的活动有所了解,在任务切入切出时保存上下文环境(寄存器值、堆栈内容)是调度器主要的职责2:栈空间:当任务切出时,它的执行环境会被保存在该任务的栈空间中,这样当任务再次运行时,就能从堆栈中正确的恢复上次的运行环境,任务越多,需要的堆栈空间就越大,而一个系统能运行多少个任务,取决于系统的可用的 SRAM3:宏configUSE_TIME_SLICING : 1,处于就绪态的多原创 2021-10-19 21:08:32 · 146 阅读 · 0 评论 -
FreeRTOS中链表的实现
函数功能void vListInitialise( List_t * const pxList );链表初始化函数/* 节点初始化 */void vListInitialiseItem( ListItem_t * const pxItem ){ /* 初始化该节点所在的链表为空,表示节点还没有插入任何链表 */ pxItem->pvContainer = NULL;}节点初始化代码分析结构体链表结构体/* 节点结构体定义 */struct xLIST_ITEM{ T原创 2021-10-13 17:00:08 · 77 阅读 · 0 评论 -
FreeRTOS 第一章
FreeRTOS官网,可以在这儿获取源码资料和PDF文稿使用的是V9.0版本2018年的portable文件夹:将硬件与软件联系起来软件仿真1:配置仿真时钟,在启动文件中看到的原创 2021-10-12 15:01:22 · 111 阅读 · 0 评论