2 任务7.2 基于FreeRTOS的电子闹钟设计_第1页
2 任务7.2 基于FreeRTOS的电子闹钟设计_第2页
2 任务7.2 基于FreeRTOS的电子闹钟设计_第3页
2 任务7.2 基于FreeRTOS的电子闹钟设计_第4页
2 任务7.2 基于FreeRTOS的电子闹钟设计_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

项目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、处理软件定时器命令队列单次定时器周期定时器单次定时器的一旦定时超时,只会执行一次其软件定时器超时回调

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论