版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目7嵌入式操作系统FreeRTOS及应用任务7.1基于FreeRTOS的多任务验证概述FreeRTOS项目引导物联网时代,32位MCU性能大幅度提高,价格逐渐走低,成为智能产品开发和设计的第一选择。实时操作系统RTOS(RealTimeOperatingSystem)也成为32位MCU应用的基础软件,它帮助支撑起越来越多的应用需求。本项目使用的STM32CubeMx软件工具,以及集成在CubeMx软件中的FreeRTOS嵌入式实时多任务操作系统,是目前物联网和嵌入式开发的主流平台,无论对有实际项目需求的开发者,还是在校学生都具备实际应用价值。随着软件功能的日趋复杂,迫切需要一个能屏蔽底层硬件的、功能强大的操作系统。基于操作系统的开发方式不仅能有效地提高开发效率,而且能够提高系统的可靠性和稳定性。任务7.1简单介绍了嵌入式操作系统的基本原理,结合实例阐述FreeRTOS在STM32F4系列微控制器的移植和开发流程。任务7.2重点介绍了FreeRTOS的任务管理和任务同步功能,分析了相关接口函数的用法和应用场景,并通过设计一个电子闹钟的综合实例来展示基于FreeRTOS的编程方式。任务目标FreeRTOS职业能力目标(1)能根据RTOS相关手册,利用STM32CubeMX准确配置STM32的操作系统。(2)能够在配置RTOS系统的基础上,配置驱动两只LED灯、配置串口显示浮点数计算能力。本任务的主要目的是帮助读者将RTOS理论付诸实践。实验使用的RTOS是FreeRTOS,选择它的原因如下。(1)FreeRTOS已经作为一个中间件,集成到CubeMx软件工具中。(2)FreeRTOS配置简单。(3)FreeRTOS提供了丰富易用的API。(4)大多数API与主流RTOS的API类似。任务描述485通信本次实验设计了4个任务:start_task()、led0_task()、led1_task()、printf_test()。任务功能如下。(1)start_task():用来创建其他三个任务。(2)led0_task():控制LED0闪烁,闪烁频率为2Hz。(3)led1_task():控制LED1闪烁,闪烁频率为5Hz。(4)printf_test():每秒钟打印一个浮点数的递增操作。任务描述任务要求任务7.1基于FreeRTOS的多任务验证(1)通过STM32CubeMX软件进行RTOS操作系统的配置。(2)实现上述任务描述中的四个任务功能。FreeRTOS1.嵌入式系统的开发方式知识链接轮询方式简单系统无需关心外设状态按键判别驱动指示灯驱动蜂鸣器驱动继电器前后台系统方式多适用于功能简单、系统结构清晰的产品非工作时微控制器处于停机或待机状态,所有的事务由中断服务完成,这样有利于降低功耗。多任务系统方式/基于嵌入式操作系统方式操作系统对嵌入式平台的硬件资源进行统一管理和分配。实时性好、开发效率高。FreeRTOS2.嵌入式操作系统的基本概念知识链接任务任务,也称为线程,是嵌入式操作系统中最重要的概念。在软件设计阶段,将一个复杂的嵌入式系统,根据具体应用,分解成具有独立功能的程序模块,这样的程序模块被称为任务。各个任务之间相互协作,利用操作系统提供的接口函数共同实现整个系统的功能。任务具有以下两大特性。(1)独立性任务之间不能彼此直接调用,也不能直接进行数据交换。(2)并行性操作系统为每个任务虚拟了一个CPU,相互独立的任务各自拥有一个CPU,每个CPU执行各自的任务。内核内核是嵌入式操作系统的核心模块,主要功能是负责任务的调度以及实现任务之间的相互作用(任务同步和通信)。FreeRTOS2.嵌入式操作系统的基本概念知识链接上下文切换任务的上下文(Context)指的是CPU寄存器[包括程序计数器(PC)]。当内核决定运行另外的任务时,它需要保存当前正在运行任务的上下文,这些内容将保存到任务自身的任务栈中。入栈工作完成后,再把下一个将要运行任务的上下文从其任务栈中重新装入CPU的寄存器,然后开始下一个任务的运行,这个过程称为任务切换或上下文切换。内核在嵌入式操作系统中,为了使系统达到高效处理和快速响应的目的,大量采用“事件驱动”的方式来编写任务,这里的事件表示一种具体的操作。例如,按键按下、串口接收完一帧数据以及定时时间到等都可以看作是一个事件。FreeRTOS3.任务调度简介知识链接FreeRTOS一共支持三种任务调度方式:抢占式调度协程式调度时间片调度主要是针对优先级不同的任务,每个任务都有一个优先级,优先级高的任务可以抢占优先级低的任务。主要针对优先级相同的任务,当多个任务的优先级相同时,任务调度器会在每一次系统时钟节拍到的时候切换任务。调度器就是使用相关的调度算法来决定当前需要执行的哪个任务当前执行任务将会一直运行,同时高优先级的任务不会抢占低优先级任务,FreeRTOS现在虽然还支持,但是官方已经表示不再更新协程式调度。FreeRTOS抢占式调度知识链接优先级时间Task1Task2Task3Task2Task31232、Task1、Task2、Task3的优先级分别为1、2、3;在FreeRTOS中任务设置的数值越大,优先级越高,所以TASK3的优先级最高。运行条件:1、创建三个任务:Task1、Task2、Task3抢占抢占阻塞运行过程如下:1、首先Task1在运行中,在这个过程中Task2就绪了,在抢占式调度器的作用下Task2会抢占Task1的运行2、Task2运行过程中,Task3就绪了,在抢占式调度器的作用下Task3会抢占Task2的运行3、Task3运行过程中,Task3阻塞了(系统延时或等待信号量等),此时就绪态中,优先级最高的任务Task2执行4、Task3阻塞解除了(延时到了或者接收到信号量),此时Task3恢复到就绪态中,抢占TasK2的运行总结:1、高优先级任务,优先执行2、高优先级任务不停止,低优先级任务无法执行3、被抢占的任务将会进入就绪态FreeRTOS时间片调度知识链接优先级时间Task1Task2Task3Task1Task21个时间片2、Task1、Task2、Task3的优先级均为1;即3个任务同等优先级运行条件:1、创建三个任务:Task1、Task2、Task31阻塞运行过程如下:1、首先Task1运行完一个时间片后,切换至Task2运行2、Task2运行完一个时间片后,切换至Task3运行3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等),此时直接切换到下一个任务Task14、Task1运行完一个时间片后,切换至Task2运行同等优先级任务轮流地享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期3、注意没有用完的时间片不会再使用,下次任务Task3得到执行还是按照一个时间片的时钟节拍运行2、一个时间片大小,取决为滴答定时器中断周期1、同等优先级任务,轮流执行;时间片流转FreeRTOS任务状态知识链接FreeRTOS中任务共存在4种状态:1、运行态2、就绪态3、阻塞态4、终止态正在执行的任务,该任务就处于运行态,注意在STM32中,同一时间仅一个任务处于运行态如果该任务已经能够被执行,但当前还未被执行,那么该任务处于就绪态如果一个任务因延时或等待外部事件发生,那么这个任务就处于阻塞态当任务的功能已经完成,不再需要该任务时,可以使任务挂起,处于终止状态,并释放任务拥有的资源FreeRTOS任务状态知识链接四种任务状态之间的转换图:当任务创建后,默认处于就绪态,由内核选择所有处于就绪态任务中优先级最高的一个任务来运行。在任务执行过程中,如果等待某个事件的发生或者执行延时操作,该任务将放弃CPU的使用权,变为阻塞态。如果等待的事件已经发生或者延时时间到后,任务又从阻塞态变为就绪态,等待内核的调度。当任务功能已经完成,不再需要该任务时,可以将任务挂起,使之处于终止态。总结:1、仅就绪态可转变成运行态2、其他状态的任务想运行,必须先转变成就绪态FreeRTOS任务三要素知识链接从任务的存储结构上看,任务主要由三部分组成:任务函数、任务栈和任务控制块。(1)任务函数每一个任务都要完成对应的功能,实现这个功能的函数就称为任务函数。任务函数从本质上来说,就相当于一个独立的前后台程序。操作系统所进行的任务调度,本质上就是调度任务函数,从一个任务的任务函数中退出,切换到另一个任务的任务函数中执行。任务函数一般设计为一个无限循环,在循环中至少要调用一次操作系统所提供的接口函数,以实现任务的调度以及任务之间的交互。(2)任务栈由于每个任务都是独立运行的,因此必须给每个任务提供单独的内存空间(RAM),这个内存空间称为任务栈。在任务的运行过程中,任务栈用于保存任务切换时的上下文环境、任务函数中定义的局部变量以及任务调用普通函数时保存的返回地址和传入普通函数的入口参数。在大多数情况下,任务栈的大小一般为几百个字节。(3)任务控制块任务控制块是内核定义的一个数据结构,里面包括了任务的基本属性,如任务栈指针、任务状态、任务优先级以及指向任务函数的指针等,内核通过任务控制块实现对任务的管理和调度。FreeRTOS时钟节拍知识链接知识链接时钟节拍是一个周期性的定时中断,定时中断的时间间隔一般在1ms到10ms之间。时钟节拍可以为操作系统提供延时功能,将任务延时若干整数倍的时钟节拍,以及当任务等待事件发生时,提供超时判断的依据。FreeRTOS嵌入式实时操作系统简介知识链接知识链接嵌入式操作系统(EmbeddedOperatingSystem,EOS)是一种用途广泛的系统软件,过去它主要应用于工业控制和国防系统领域。EOS负责嵌入系统的全部软、硬件资源的分配、调度工作,控制协调并发活动;它必须体现其所在系统的特征,能够通过装卸某些模块来达到系统所要求的功能。STM32常见的几种操作系统对于STM32嵌入式微控制器,常用到的是下面几种嵌入式操作系统:μC/OS-II、eCos、FreeRTOS和RT-thread。FreeRTOS嵌入式实时操作系统简介知识链接知识链接μC/OS-II:μC/OS-II是在μC/OS的基础上发展起来的,是用C语言编写的一个结构小巧、抢占式的多任务实时内核。eCos:eCos即嵌入式可配置操作系统。它是一个源代码开放的可配置、可移植、面向深度嵌入式应用的实时操作系统。它最大特点是配置灵活,采用模块化设计,核心部分由不同的组件构成,包括内核、C语言库和底层运行包等。FreeRTOS:由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、FreeRTOS等少数实时操作系统能在小型RAM单片机上运行。相对于μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,其最新版本为6.0版。RT-thread:RT-thread是一款主要由中国开源社区主导开发的开源实时操作系统(许可证:GPLv2)。实时线程操作系统不仅是一个单一的实时操作系统内核,它也是一个完整的应用系统,包含了实时、嵌入式系统相关的各个组件,如TCP/IP协议栈、文件系统、libc接口和图形用户界面等。2023年RTOS榜单:国产RT-Thread入围排行榜。FreeRTOSFreeRTOS的任务特性知识链接知识链接在使用RTOS的时候,一个实时应用可以是一个独立的任务,每个任务都有自己的运行环境,CPU在任一时间点只能运行一个任务,具体运行哪个任务将由任务调度器决定。RTOS的任务特性如下。任务简单。没有使用限制,任务可以运行无数次。支持抢占和优先级。每个任务都拥有独立的堆栈,导致RAM必须较大。FreeRTOS知识链接任务实施任务实施之前必须准备好表7-1所列的设备/资源。序号设备/资源数量是否准备到位(√)1STM32F407ZET6最小系统1
2配书资源1
表7-1设备/资源清单表要完成本任务,实施步骤可以分成以下6步。使用STM32CubeMX工程配置RTOS。在源文件中添加代码。编译代码。硬件环境搭建。模块固件下载。结果验证。FreeRTOS具体实施步骤知识链接任务实施设置CubeMX环境创建项目,并将其设置为相应的IDE生成代码配置项目包含FreeRTOS,选择时基定时器1)使能FreeRTOS中间件2)设置时基源FreeRTOS具体实施步骤知识链接任务实施3)配置外设4)配置时钟5)在FreeRTOS中添加三个任务在Categories导航栏,单击“Middleware”,选“FREERTOS”,在Configuration栏,单击“TasksandQueues”,双击Task列表中的“Add”,按图7-11进行任务设置。6)生成代码FreeRTOS让我们遍历一下相关的代码。知识链接任务实施(1)创建线程(任务)标识符,如下代码在freertos.c文件中。osThreadIddefaultTaskHandle;osThreadIdled0_TaskHandle;osThreadIdled1_TaskHandle;osThreadIdmyfloat_taskHandle;(2)定义并创建线程,如下代码在freertos.c文件中。
/*Createthethread(s)*//*definitionandcreationofdefaultTask*/………………/*definitionandcreationofled0_Task*/………………/*definitionandcreationofled1_Task*/………………/*definitionandcreationofmyfloat_task*/………………(3)启动FreeRTOS多任务调度器 osKernelStart();(4)任务实现函数 voidStartDefaultTask(voidconst*argument)FreeRTOSfreertos.c文件中的3个任务函数知识链接任务实施FreeRTOS搭建硬件电路知识链接任务实施FreeRTOS构建项目并下载代码知识链接任务实施启动集成开发环境,导入项目。构建、下载并运行项目。观察和测量LED灯闪烁(点亮和熄灭)的时间,观察串口打印的结果是否符合程序代码的预期通过串口调试助手可以发现,大概每隔1s,串口会输出一条消息,浮点数会增加0.01,如图所示。两只LED灯也会以不同频率闪烁,如有条件的话,也可用示波器测试PF9/PF10的频率,看看是否符合预期。FreeRTOS任务小结知识链接任务小结如果已完成任务7.1的所有内容,应该能获得一下能力。知道如何为STM32F407开发板创建CubeMX项目,并配置任务使用FreeRTOS。了解CubeMX工具自动生成的代码文件夹/文件内容。理解源代码main.c文件的结构和内容,尤其是RTOS相关代码。清楚地了解哪些代码可以自动生成,哪些必须由用户提供。成功编译、下载代码到目标板,执行FreeRTOS任务,控制两只LED灯的行为。领会osDelay(或vTaskDelay)函数的行为。FreeRTOS知识链接任务小结--
南昌大学“卓越”辅导员培养工程建设本节结束本节结束27项目7嵌入式操作系统FreeRTOS及应用任务7.2基于FreeRTOS的电子闹钟设计任务目标FreeRTOS职业能力目标(1)掌握FreeRTOS常用接口函数的用法。(2)学会基于FreeRTOS平台下的程序编码与调试。基于STM32F407ZET6核心板设计一个电子钟,具备以下功能。(1)能够显示时/分/秒等时钟信息,通过串口发送到PC显示。(2)能够进行时钟和闹钟的设置,通过PC串口调试助手软件发送数据实现:发送“T+时间”表示设置时钟,如“T093000”表示设置时钟为09:30:00;发送“A+时间”表示设置闹钟,如“A234500”表示设置闹钟为23:45:00。(3)闹钟时间到,控制LED指示灯开启3s后关闭。(4)电子时钟的启动由按键KEY控制,按键KEY按下后,才启动时钟显示。FreeRTOS硬件原理任务分析按键控制引脚PA0,LED指示灯控制引脚PF9。利用UART1完成串口通信,引脚PA9复用为TX,引脚PA10复用为RX。任务分析首先进行需求分析,系统要实现的功能有四个:显示功能、设置功能、闹钟功能和按键功能。我们可以以功能为单元,进行任务的划分。对于按键功能而言,当按键数量较多时,一般将按键功能拆分为按键扫描任务和按键处理任务,二者之间通过消息队列进行数据传递。因此,我们将整个系统划分为以下五个任务。(1)显示任务:完成时钟的显示。(2)设置任务:完成时钟和闹钟的修改。(3)闹钟任务:控制指示灯开启一定的时间后关闭。(4)按键扫描任务:完成按键的定时扫描。(5)按键处理任务:执行按键按下后的具体操作(启动电子时钟工作,进行时钟的显示)。FreeRTOS任务分析任务分析分析系统的中断需求。为了确保电子时钟的准确性,我们使用一个硬件定时器来产生1s的时基。对于串口通信而言,由于通信数据量不大,F407核心板又作为数据的接收方,因此采用中断方式进行串口通信。在明确了系统所使用的中断后,我们可以根据任务优先级的设计原则,对任务的优先级进行如下安排。闹钟任务由定时中断触发,设置任务由串口中断触发,按照中断关联性原则,两个任务的优先级应该为高优先级。由于闹钟任务是紧迫性任务,必须及时执行,按照紧迫性原则,闹钟任务的优先级应该高于设置任务。因此闹钟任务为高优先级“osPriorityHigh”,而设置任务为高于正常优先级“osPriorityAboveNormal”。按键扫描任务为周期性任务,每隔10ms执行,执行较为频繁,按照频繁性原则,设置为正常优先级“osPriorityNormal”。按键处理任务由按键扫描任务触发,按照传递性原则,优先级比按键扫描任务低,设置为低于正常优先级“osPriorityBelowNormal”。显示任务每隔1s将时钟通过串口送到PC显示,属于后台任务,实时性要求较低,设置为低优先级“osPriorityLow”。任务优先级的设置只需要保证各任务之间的高低即可,例如以上几个任务也可以设置为:闹钟任务为“osPriorityNormal4”、设置任务为“osPriorityNormal3”、按键扫描任务为“osPriorityNormal2”、按键处理任务“osPriorityNormall”和显示任务“osPriorityNormal”。FreeRTOS数据结构任务分析时钟数据结构:采用结构体实现,以全局变量的形式实现数据共享。闹钟数据结构:采用结构体实现,以全局变量的形式实现数据共享。通信消息队列:用于串口中断和设置任务的同步和数据传递,串口接收到设置数据后,通过消息队列将数据传递到设置任务。按键消息队列:用于按键扫描任务和按键处理任务的同步和数据传递,按键按下后,通过消息队列将键值传递到按键处理任务,执行相应的按键功能。闹钟信号量:用于定时中断和闹钟的同步,闹钟时间匹配时,启动闹钟任务。事件标志组:用于按键处理任务和显示任务的同步,按键按下后,启动硬件定时器和显示任务。软件定时器:单次触发定时器,实现指示灯控制。互斥量:用于时钟全局变量的互斥访问。使用的数据结构任务的同步和通信FreeRTOS任务与中断之间的逻辑关系任务分析FreeRTOS1.信号量知识链接信号量是一种非常灵活的同步方式,可以运用在多种场合,实现任务同步和资源计数等功能。信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问。按照信号量的功能,可以分为二值信号量、计数信号量。信号量是一种解决同步问题的机制,可以实现对共享资源的有序访问空车位
:信号量资源数(计数值)停车位让出占用车位
:释放信号量(计数值++)假设有一个人需要在停车场停车2、停车场正好有空车位(信号量有资源),那么就可以直接将车开入空车位进行停车(获取信号量成功);3、停车场已经没有空车位了(信号量没有资源),那么这个人可以选择不停车(获取信号量失败);也可以选择等待(任务阻塞)其他人将车开出停车场(释放信号量资源),然后再将车停入空车位。1、首先判断停车场是否还有空车位(判断信号量是否有资源);FreeRTOS1.信号量知识链接任务A
让计数值加1(让出车位)任务B让计数值加1(让出车位)任务D让计数值减1(占用车位)信号量计数值当计数值大于0,代表有信号量资源信号量:用于传递状态当释放信号量,信号量计数值(资源数)加一当获取信号量,信号量计数值(资源数)减一信号量的计数值都有限制:限定最大值。如果最大值被限定为1,那么它就是二值信号量;如果最大值不是1,它就是计数型信号量。任务C让计数值减1(占用车位)FreeRTOS2.二值信号量知识链接二值信号量的本质是一个队列长度为1的队列,该队列就只有空和满两种情况,这就是二值。二值信号量通常用于互斥访问或任务同步,与互斥信号量比较类似,但是二值信号量有可能会导致优先级翻转的问题,所以二值信号量更适合用于同步!Give操作相当把该标志置“满”Take操作相当于把该标志取"空"释放二值信号量获取二值信号量Task或ISR二值信号量Task或ISRxSemaphoreGivexSemaphoreGiveFromISRxSemaphoreTakexSemaphoreTakeFromISR使用二值信号量的过程:创建二值信号量→释放二值信号量→获取二值信号量。其运作机制如图所示。使用二值信号量的过程:创建二值信号量
释放二值信号量
获取二值信号量函数描述xSemaphoreCreateBinary()使用动态方式创建二值信号量xSemaphoreCreateBinaryStatic()使用静态方式创建二值信号量xSemaphoreGive()释放信号量xSemaphoreGiveFromISR()在中断中释放信号量xSemaphoreTake()获取信号量xSemaphoreTakeFromISR()在中断中获取信号量FreeRTOS2.二值信号量知识链接FreeRTOS3.计数信号量知识链接计数型信号量相当于队列长度大于1的队列,因此计数型信号量能够容纳多个资源,这在计数型信号量被创建的时候确定的计数型信号量适用场合:事件计数资源管理当每次事件发生后,在事件处理函数中释放计数型信号量(计数值+1),其他任务会获取计数型信号量(计数值-1),这种场合一般在创建时将初始计数值设置为0
信号量表示有效的资源数目。任务必须先获取信号量(信号量计数值-1)才能获取资源控制权。当计数值减为零时表示没有的资源。当任务使用完资源后,必须释放信号量(信号量计数值+1)。信号量创建时计数值应等于最大资源数目使用计数型信号量的过程:创建计数型信号量
释放信号量
获取信号量函数描述xSemaphoreCreateCounting()使用动态方法创建计数型信号量。xSemaphoreCreateCountingStatic()使用静态方法创建计数型信号量uxSemaphoreGetCount()获取信号量的计数值FreeRTOS接口函数知识链接FreeRTOS提供了信号量功能,支持二值信号量和计数信号量。经过CMSIS-RTOS2封装后,提供的常用接口函数有以下三个。(1)信号量创建函数(osSemaphoreNew())函数原型osSemaphoreId_tosSemaphoreNew(uint32_tmax_count,uint32_tinitial_count,constosSemaphoreAttr_t*attr);功能描述创建并初始化一个信号量入口参数1max_count:信号量的最大计数值,当max_count=1,表示二值信号量入口参数2initial_count:信号量初值入口参数3attr:指向信号量属性的指针,默认为NULL返回值信号量的句柄,用于标识信号量,如创建时发生错误,返回值为NULL注意事项该函数不能从中断服务程序中调用该函数由CubeMX自动生成FreeRTOS接口函数知识链接(2)信号量获取函数(osSemaphoreAcquire())函数原型osStatus_tosSemaphoreAcquire(osSemaphoreId_tsemaphore_id,uint32_ttimeout);功能描述获取一个信号量入口参数1semaphore_id:信号量的句柄入口参数2timeout:超时等待时间,以时钟节拍为单位,osWaitForever表示无限等待
返回值状态代码,指示函数的执行情况:osOK:成功获取信号量,信号量的值减1osErrorTimeout:在给定时间无法获取信号量osErrorResource:信号量处于无效状态osErrorParameter:参数错误注意事项当超时等待时间为0时,该函数可以从中断服务程序中调用。该函数由用户调用FreeRTOS接口函数知识链接(3)信号量释放函数(osSemaphoreRelease())函数原型osStatus_tosSemaphoreRelease(osSemaphoreId_tsemaphore_id);功能描述释放一个信号量入口参数1semaphore_id:信号量的句柄返回值状态代码,指示函数的执行情况:osOK:信号量成功释放,信号量的值加1osErrorResource:无法释放信号量(信号量的计数值已经达到最大计数值)osErrorParameter:参数错误注意事项该函数可以从中断服务程序中调用。该函数由用户调用FreeRTOS4.互斥信号量知识链接互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中!被多个任务所访问的资源称为共享资源,把程序代码中涉及访问共享资源的语句称为临界区。各个任务在进入各自临界区时,必须采用互斥访问,才能保证共享资源的可靠性和完整性。(2)中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。注意:互斥信号量不能用于中断服务函数中,原因如下:(1)互斥信号量有任务优先级继承的机制,但是中断不是任务,没有任务优先级,所以互斥信号量只能用与任务中,不能用于中断服务函数。FreeRTOS互斥信号量相关API函数知识链接使用互斥信号量:首先将宏configUSE_MUTEXES置1函数描述xSemaphoreCreateMutex()使用动态方法创建互斥信号量。xSemaphoreCreateMutexStatic()使用静态方法创建互斥信号量。创建互斥信号量函数:互斥信号量的释放和获取函数与二值信号量相同!只不过互斥信号量不支持中断中调用使用流程:创建互斥信号量
(task)获取信号量
(give)释放信号量注意:创建互斥信号量时,会主动释放一次信号量FreeRTOS5.事件标志组知识链接事件标志位:用一个位,来表示事件是否发生事件标志组是一组事件标志位的集合,可以简单的理解事件标志组,就是一个整数。可以等待某一位成立,或者等待多位同时成立它的每一个位表示一个事件(高8位不算)每一位事件的含义,由用户自己决定,如:bit0表示按键是否按下,bit1表示是否接受到消息……这些位的值为1:表示事件发生了;值为0:表示事件未发生任意任务或中断都可以读写这些位事件标志组的特点:虽然使用了32位无符号的数据类型变量来存储事件标志,但其中的高8位用作存储事件标志组的控制信息,低24位用作存储事件标志,所以说一个事件组最多可以存储24个事件标志!FreeRTOS(1)事件标志组创建函数知识链接函数原型osEventFlagsId_tosEventFlagsNew(constosEventFlagsAttr_t*attr);功能描述创建一个新的事件标志组入口参数attr:事件标志组的属性,默认值为NULL返回值时间标志组的句柄,用于标识事件标志组。如果发生错误,则返回值为NULL注意事项该函数不能从中断服务程序中调用该函数由用户调用该函数用于创建一个新的事件标志组FreeRTOS(2)事件标志组设置函数知识链接函数原型uint32_tosEventFlagsSet(osEventFlagsId_tef_id,uint32_tflags);功能描述设置指定事件标志组中的一个或多个事件标志位入口参数1ef_id:事件标志组的句柄,表示要设置的事件标志组入口参数2flags:设置的事件标志位。该参数为32位,具有31个事件标志位:从bit0到bit30返回值返回设置后的事件标志组内容或错误代码。具体的错误代码如下:osFlagsErrorUnknown:未指定的错误osFlagsErrorParameter:无法识别有效的事件标志组或对事件标志组的最高位bit31设置osFlagsErrorResource:事件标志组处于无效状态注意事项事件标志位从bit0到bit30,不可以设置bit31。该函数可以从中断服务函数中调用。该函数由用户调用。FreeRTOS(3)时间标志组等待函数知识链接该函数用于等待指定事件标志组中的一个或多个事件标志位,执行时会暂停调用该函数的任务,直到等待事件标志位置位。函数原型uint32_tosEventFlagsWait(osEventFlagsId_tef_id,uint32_tflags,uint32_toptions,uint32_ttimeout);功能描述等待指定事件标志组中的一个或多个事件标志位置位入口参数1ef_id:事件标志组的句柄,表示要等待的事件标志组入口参数2flags:等待的事件标志位。该参数为32位,具有31个事件标志位:bit0到bit30入口参数3options:标志选项。其取值范围如下:osFlagsWaitAny:等待任意一个事件标志位置位(默认取值)osFlagsWaitAll:等待所有事件标志位置位osFlagsNoClear:事件标志位置位后,不清除该标志位返回值返回清除前的事件标志组内容或错误代码。具体的错误代码如下:osFlagsErrorUnknown:未指定的错误osFlagsErrorResource:事件标志组处于无效状态osFlagsErrorParameter:无法标识有效的事件标志组或等待事件标志组的最高位bit31osFlagsErrorTimeout:在给定的超时时间内,等待的事件标志位没有置位注意事项事件标志位从bit0到bit30,不可以等待bit31。当超时等待时间设置为0时,该函数可以从中断服务程序中调用。该函数由用户调用。FreeRTOS6.线程标志知识链接线程标志与事件标志组的功能类似,也可以用于多个任务的同步。唯一的区别是线程标志不需要用户创建,每一个任务创建后就自动拥有一个线程标志。任务的线程标志只能由任务自身等待,由其他任务设置。而事件标志组则相当于一个公用的资源,任何任务都可以设置或等待。FreeRTOS提供了线程标志的功能,每一个线程标志具有31个线程标志位(每一个线程标志位相当于一个二值信号量)。经过CMSIS-RTOS2封装后,提供的常用接口函数有以下两个。线程标志设置函数(osThreadFlagsSet())线程标志等待函数(osThreadFlagsWait())FreeRTOS(1)线程标志设置函数知识链接函数原型uint32_tosThreadFlagsSet(osThreadId_tthread_id,uint32_tflags);功能描述设置指定任务的线程标志中的一个或多个线程标志位入口参数1Thread_id:任务的句柄入口参数2flags:设置的线程标志位,该参数为32位,具有31个线程标志位:bit0到bit30。例如,设置线程标志的bit3时,flags为0x08;设置线程标志的bit0和bit3时,flag为0x09返回值返回设置后的线程标志内容或错误代码。具体的错误代码如下:osFlagsErrorUnknown:未指定的错误osFlagsErrorParameter:无法标识有效的任务或对线程标志的最高位bit31设置osFlagsErrorResource:任务处于无效状态注意事项线程标志位从bit0到bit30,不可以设置bit31。该函数可以从中断服务程序中调用。该函数由用户调用FreeRTOS(2)线程标志等待函数知识链接函数原型uint32_tosThreadFlagsWait(uint32_tflags,uint32_toptions,uint32_ttimeout);功能描述等待任务自身的线程标志中的一个或多个线程标志位入口参数1flags:等待的线程标志位。该参数为32位,具有31个线程标志位:bit0到bit30。例如,要等待线程标志的bit0和bit2时,flags为0x05;要等待bit0、bitl和bit2时,flags为0x07。入口参数2options:标志选项。其取值如下:osFlagsWaitAny:等待任意一个线程标志位置位(默认取值)osFlagsWaitAll:等待所有线程标志位置位osFlagsNoClear:线程标志位置位后,不清除该标志位(默认情况为清除线程标志位)入口参数3timeout:等待线程标志的超时时间,以时钟节拍为单位。当timeout为0时,该函数立即返回;当timeout为osWaitForever时,该函数将无限等待,直到等待的线程标志位置位返回值返回清除前的线程标志内容或错误代码。具体的错误代码如下:osFlagsErrorUnknown:未指定的错误osFlagsErrorResource:线程标志处于无效状态osFlagsErrorParameter:对线程标志的最高位设置osFlagsErrorTimeout:在给定的超时时间内,等待的线程标志位没有置位注意事项线程标志位从bit0到bit30,不可以等待bit31。该函数不能从中断服务程序中调用。该函数由用户调用。FreeRTOS6.消息队列知识链接使用信号量、事件标志组和线程标志进行任务同步时,只能提供同步的时刻信息,无法在任务之间进行数据传输。要实现任务间的数据传输,一般使用以下两种方式。1)全局变量2)消息队列一个队列只允许任务间传递的消息为同一种数据类型,如果需要在任务间传递不同数据类型的消息时,那么就可以使用队列集!作用:用于对多个队列或信号量进行“监听”,其中不管哪一个消息到来,都可让任务退出阻塞状态。假设:有个接收任务,使用到队列接收和信号量的获取,如下:接收任务(){等待接收队列;
获取信号量
;}接收任务(){等待队列集中消息;if(队列还是信号量); ……}FreeRTOS(1)消息队列创建函数知识链接函数原型osMessageQueueId_tosMessageQueueNew(uint32_tmsg_count,uint32_tmsg_size,constosMessageQueueAttr_t*attr);功能描述创建一个新的消息队列入口参数1msg_count:消息队列中可以容纳的最大消息数量入口参数2msg_size;每个消息的大小(以字节为单位)入口参数3attr:指向消息队列属性的指针,默认值为NULL返回值消息队列的句柄,用于标识消息队列。如果创建时发生错误,则返回值为NULL注意事项每个消息的大小必须由实际传输数据的字节数来决定。该函数不能从中断服务程序中调用。该函数由CubeMX软件自动生成。FreeRTOS(2)消息放入函数知识链接函数原型osStatus_tosMessageQueuePut(osMessageQueueId_tmq_id,constvoid*msg_ptr,uint8_tmsg_prio,uint32_ttimeout);功能描述向指定的消息队列中放入一个消息入口参数1mq_id:消息队列的句柄入口参数2msg_ptr:指向存放消息的缓冲区指针(该消息将放入指定的消息队列中)入口参数3msg_prio:消息的优先级入口参数4timeout:超时等待时间,以时钟节拍为单位,osWaitForever表示无限等待返回值状态代码,指示函数的执行情况:osOK:消息已经成功放入消息队列osErrorTimeout:在给定的超时时间内无法将消息放入消息队列osErrorResource:消息队列中没有足够的空间存放消息osErrorParameter:参数错误注意事项消息传递的过程是数据的复制,而不是传递数据的地址。当超时等待时间设置为0时,该函数可以从中断服务程序中调用。由于消息传递的过程是数据的复制,在中断中调用时,单个消息不宜过大,避免增加中断服务程序的执行时间。该函数由用户调用。FreeRTOS(3)消息获取函数知识链接函数原型osStatus_tosMessageQueueGet(osMessageQueueId_tmq_id,void*msg_ptr,uint8_t*msg_prio,uint32_ttimeout);功能描述从指定的消息队列中获取一个消息入口参数1mq_id:消息队列的句柄入口参数2msg_ptr:指向存放消息的缓冲区指针(从消息队列中获取的消息将存放到该缓冲区)入口参数3msg_prio:消息的优先级。入口参数4timeout:超时等待时间,以时钟节拍为单位,osWaitForever表示无限等待返回值状态代码,指示函数的执行情况:osOK:从消息队列中成功获取消息osErrorTimeout:在给定的超时时间内无法从消息队列中获取消息osErrorResource:无法从消息队列中获取消息osErrorParameter:参数错误注意事项当超时等待时间设置为0时,该函数可以从中断服务程序中调用。存放消息的缓冲区空间要大于或等于单个消息的大小,否则取出的数据无法全部保存到缓冲区,造成内存溢出。该函数由用户调用。FreeRTOS7.软件定时器知识链接芯片本身自带的定时器模块,硬件定时器的精度一般很高,每次在定时时间到达之后就会自动触发一个中断,用户在中断服务函数中处理信息。软件定时器:是指具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息定时器:从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可自定义定时器的周期硬件定时器:软件定时器优缺点?优点:硬件定时器数量有限,而软件定时器理论上只需有足够内存,就可以创建多个;使用简单、成本低。缺点:软件定时器相对硬件定时器来说,精度没有那么高(因为它以系统时钟为基准,系统时钟中断优先级又是最低,容易被打断)。
对于需要高精度要求的场合,不建议使用软件定时器。FreeRTOSFreeRTOS软件定时器特点知识链接注意:软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数。软件定时器是可裁剪可配置的功能,如果要使能软件定时器,需将configUSE_TIMERS配置项配置成1
可裁剪单次和周期软件定时器支持设置成:单次定时器或周期定时器软件定时器服务任务:在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。软件定时器服务任务作用1、负责软件定时器超时的逻辑判断2、调用超时软件定时器的超时回调函数3、处理软件定时器命令队列单次定时器周期定时器单次定时器的一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启。周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动,从而周期地执行其软件定时器回调函数。FreeRTOS(1)软件定时器创建函数知识链接函数原型osTimerId_tosTimerNew(osTimerFunc_tfunc,osTimerType_ttype,void*argument,constosTimerAttr_t*attr);功能描述创建一个单次触发或周期触发的软件定时器,并将其与回调函数相关联入口参数1func:指向回调函数的函数指针入口参数2type:创建的软件定时器类型,取值范围如下:osTimerOnce:表示单次触发定时器osTimerPeriodic:表示周期触发定时器入口参数3argument:回调函数的入口参数入口参数4attr:指向定时器属性的指针,默认值为NULL返回值软件定时器的句柄,用于标识软件定时器。如果创建时发生错误,则返回值为NULL注意事项该函数不能从中断服务程序中调用。创建软件定时器,并不代表启动了软件定时器,还需要单独启动。该函数由CubeMX软件自动生成。FreeRTOS(2)软件定时器启动函数知识链接函数原型osStatus_tosTimerStart(osTimerId_ttimer_id,uint32_tticks);功能描述启动或重新启动指定的软件定时器入口参数1timer_id:软件定时器的句柄入口参数2ticks:对于单次触发的软件定时器,表示回调函数在延时ticks个时钟节拍后执行;对于周期性触发的软件定时器,表示回调函数每隔ticks个时钟节拍重复执行返回值状态代码,表示函数的执行情况:osOK:软件定时器成功启动或重新启动osErrorResource:软件定时器处于无效状态osErrorParameter:参数错误osErrorISR:不能从中断服务程序中调用注意事项该函数不能从中断服务程序中调用。该函数由用户调用。FreeRTOS(3)软件定时器停止函数知识链接函数原型osStatus_tosTimerStop(osTimerId_ttimer_id);功能描述停止指定的软件定时器入口参数1Timer_id:软件定时器的句柄返回值状态代码,指示函数的执行情况:osOK:指定的软件定时器已经停止osErrorResource:软件定时器未运行osErrorParameter:参数错误osErrorISR:不能从中断服务程序中调用注意事项该函数不能从中断服务程序中调用。该函数由用户调用。FreeRTOS小结知识链接--
南昌大学“卓越”辅导员培养工程建设本节结束本节结束61项目7嵌入式操作系统FreeRTOS及应用任务7.2基于FreeRTOS的电子闹钟设计任务目标职业能力目标(1)掌握FreeRTOS常用接口函数的用法。(2)学会基于FreeRTOS平台下的程序编码与调试。基于STM32F411RETx核心板设计一个电子钟,具备以下功能。(1)能够显示时/分/秒等时钟信息,通过串口发送到PC显示。(2)能够进行时钟和闹钟的设置,通过PC串口调试助手软件发送数据实现:发送“T+时间”表示设置时钟,如“T093000”表示设置时钟为09:30:00;发送“A+时间”表示设置闹钟,如“A234500”表示设置闹钟为23:45:00。(3)闹钟时间到,控制LED指示灯开启3s后关闭。(4)电子时钟的启动由按键KEY控制,按键KEY按下后,才启动时钟显示。FreeRTOS电子闹钟FreeRTOS硬件原理任务分析LED指示灯控制引脚PA5,按键控制引脚PC13。利用UART2完成串口通信,引脚PA2复用为TX,引脚PA3复用为RX。首先进行需求分析,系统要实现的功能有四个:显示功能、设置功能、闹钟功能和按键功能。我们可以以功能为单元,进行任务的划分。对于按键功能而言,当按键数量较多时,一般将按键功能拆分为按键扫描任务和按键处理任务,二者之间通过消息队列进行数据传递。因此,我们将整个系统划分为以下五个任务。(1)显示任务:完成时钟的显示。(2)设置任务:完成时钟和闹钟的修改。(3)闹钟任务:控制指示灯开启一定的时间后关闭。(4)按键扫描任务:完成按键的定时扫描。(5)按键处理任务:执行按键按下后的具体操作(启动电子时钟工作,进行时钟的显示)。FreeRTOS电子闹钟任务实施任务实施前必须准备好表7-19所示的设备和资源。序号设备/资源名称数量是否准备到位(√)1STM32F411RETx最小核心板1
2USB转串口数据线1
表7-19设备清单表FreeRTOS电子闹钟任务实施导航&实施纪要任务实施创建任务。创建消息队列。创建软件定时器。创建二值信号量。创建互斥信号量。修改软件定时器的优先级。修改HAL的时间基准。程序编写。创建项目引脚分配中间件配置编译下载程序搭建硬件环境结果验证中间件配置步骤:FreeRTOS电子闹钟具体实施步骤如下任务实施设置CubeMX环境启动CubeMX软件,依次选择“NewProject”→“StartMyprojectfromMCU”选项,在PartNumberSearch搜索框中输入“STM32F411RE”,选中搜索结果的STM32F411RETx,单选右上角的“StartProject”选项,进入开发板初始化对话框。创建项目,并将其设置为相应的IDE生成代码(1)首先,在主窗口中选择“ProjectManager”选项,打开“Project”标签,打开“ProjectSetting”窗口。(2)在相应的文本框中输入项目名称,选择项目保存路径。(3)将Toolchain/IDE选项设置为“MDK-ARMV5”。选择File菜单中的“SaveProject”选项,保存项目,打开项目所
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 充要条件课件2026-2027学年高一上学期人教A版必修第一册
- 工程制图及CAD 课件 5机件常用的表达方法
- 山东单招试题真题及答案
- 2026年一建民航实务考前易错题重组卷试卷及答案
- 2026年一建矿业实务考前易错题目重组试卷及答案
- 2026年一建矿业工程核心突破试卷及答案
- 2026电源算法面试题及答案
- 2026富士康培训面试题及答案
- 客运公交车、车站、出租车行业事故隐患自查清单
- 点、线、面、体课件2026-2027学年北师大版数学七年级上册
- 2025-2026学年小学英语的教学活动设计
- 2026年安徽省合肥社区工作者考试题库含答案
- 2026-2030中国蒸汽眼罩行业深度调研及投资前景预测研究报告
- (2026版)国开电大法学本科知识产权法历年期末考试总题及答案
- 2025年贵州锦麟化工有限责任公司公开招聘13人笔试历年参考题库附带答案详解
- 银行不良资产评估定价管理办法模版
- 成都湔江投资集团有限公司2026年春季第一批次招聘考试参考题库及答案解析
- 2026公需课人工智能赋能制造业高质量发展试题及答案.backup
- 门诊病案管理工作制度
- 鲜风生活生鲜即时配送
- 丁腈橡胶失效分析案例
评论
0/150
提交评论