完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1.FreeRTOS 二值信号量
1.1二值信号量简介 信号量实际上就是一个值,这个值被用来解决临界区问题以及实现进程在多处理器环境下的进程同步。 其中,两个最重要的信号量为二进制信号量和计数信号量,计数信号量可以表示为非负的整数而二进制信号量只存在0和1两个值。 二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承。因此二值信号量更适合用于同步(任务与任务或任务与中断的同步), 1.2二值信号量函数 1.2.1 创建信号量 对于二值信号量,若想使用,必须先创建二值信号量,在新版FreeRTOS中,一般使用xSemaphoreCreateBinary()函数动态创建二值信号量。此函数是个宏,具体创建工程是由函数xQueueGenericCreate()完成。其函数原型如下: SemaphoreHandle_t xSemaphoreCreateBinary(void) 参数: 无 返回值: NULL:二值信号量创建失败 其他值:创建成功的二值信号量的句柄 1.2.2 释放信号量 释放信号量的函数有两个,分别如下: 任务级信号量释放函数 xSemaphoreGive(),此函数是个宏,可以用于释放二值信号量、计数型信号量或互斥信号量,其函数原型如下: BaseType_t xSemaphoreGive(xSemaphore) 参数: xSemaphore:要释放的信号量句柄 返回值: PdPASS:释放信号量成功 PdQUEUE_FULL:释放信号量失败 中断级信号量释放函数 xSemaphoreGiveFromISR(),此函数也是个宏,只能用来释放二值信号量和计数型信号量,其函数原型如下: BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, BaseType_t* pxHigherPriorityTaskWoken) 参数: xSemaphore:要释放的信号量句柄 pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换 返回值: PdPASS:释放信号量成功 PdQUEUE_FULL:释放信号量失败 1.2.3 获取信号量 获取信号量的函数也有两个,分别如下: 任务级信号量获取函数xSemaphoreTake(),此函数也是个宏,可以获取二值信号量、计数型信号量和互斥信号量,其函数原型如下: BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xBlockTime) 参数: xSemaphore:要获取的信号量句柄 xBlockTime:阻塞时间 返回值: pdTRUE:获取信号量成功 pdFALSE:超时,获取信号量失败 中断级信号量获取函数 xSemaphoreTakeFromISR(),此函数也是个宏,只能获取二值信号量和计数型信号量,其函数原型如下: BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, BaseType_t* pxHigherPriorityTaskWoken) 参数: xSemaphore:要获取的信号量句柄 pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换 返回值: PdPASS:获取信号量成功 pdFALSE:获取信号量失败 1.3操作实验 1.3.1实验设计 二值信号量可以实现任务与任务之间或者任务与中断之间的同步,在本节实验中,通过按键中断来控制LED灯的亮灭来实现任务与中断之间的同步。 在本实验中,共创建了两个任务,其中一个任务每隔一秒让LED3电平翻转,来表示程序可以正常运行,另外一个任务根据中断中传来的指令来控制不同LED灯的亮灭。 当按键按下时,进入中断,在中断中同时同时释放二值信号量,任务StartTask02()会一直尝试获取二值信号量,当获取到信号量后就会根据中断中的指令进而控制不同的LED灯发生亮灭。 任务及其功能如下: StartDefaultTask():控制LED3闪烁,提示系统正在运行。 StartTask02():进行指令处理,根据接收的指令控制不同的LED灯。 1.3.2实验过程与分析 首先,根据之前几章内容配置好KEY、UART4、LED灯,切换到中间件“Middleware”的“FREERTOS”,默认自动勾选给M4了,然后接口“Interface”选择“CMSIS_V2”。初次接触,下面的参数大部分默认即可,为了运行其它任务,这里需要切换到“Tasks and Queues”标签,可以看到默认有个“defaultTask”任务,我们再点击“Add”再新增一个任务,如所示。 随后生成初始化代码,会弹出Systick被FreeRTOS占用,建议HAL库时钟基准源换成其它。之后FreeRTOS实验默认为此配置。 上述为新建工程配置过程,可参考12.3.2章节进行导入已有工程,工程存放路径【华清远见-FS-MP1A开发资料 2-程序源码ARM体系结构与接口技术FreeRTOS1_FS-MP1A-FreeRTOS】 生成代码后,找到“main.c”,结尾部分会有两个任务函数,分别是“StartDefaultTask()”和“StartTask02()”。两个任务宏观看同时、独立运行,互不干扰。在“StartDefaultTask()”实现LED3每隔一秒闪烁,在“StartTask02()”中实现根据不同的指令控制不同LED灯亮灭。 在本次实验中,释放信号量在中断中进行,每进行一次按键按下,就释放一次信号量。在StartTask02任务中循环检测信号量,当在中断中释放信号量以后,便可以获取到信号量,然后根据指令进行控制,按键1或按键2按下时,分别控制LED1或LED2点亮,按键3按下时,控制LED1和LED2熄灭。 |
|
|
|
只有小组成员才能发言,加入小组>>
3316 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9060 浏览 16 评论
4088 浏览 18 评论
1180浏览 3评论
606浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
600浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 12:37 , Processed in 1.723684 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号