大佬教程收集整理的这篇文章主要介绍了【STM32F429】第20章 ThreadX互斥信号量,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514
本章节讲解ThreadX的资源共享机制---互斥信号量(Mutex,即Mutual Exclusion的缩写)。注意,建议初学者学习完前两个章节的信号量后再学习本章节的互斥信号量。
20.1 互斥信号量
20.2 互斥信号量创建函数tx_mutex_create
20.3 互斥信号量获取函数tx_mutex_get
20.4 互斥信号量释放函数tx_mutex_put
20.5 实验例程
20.6 总结
互斥信号量的主要作用是对资源实现互斥访问,使用二值信号量也可以实现互斥访问的功能,不过互斥信号量与二值信号量有区别。下面我们先举一个通过二值信号量实现资源独享,即互斥访问的例子,让大家有一个形象的认识,进而引出要讲解的互斥信号量。
运行条件:
代码实现:
TX_SEMAPHORE Semaphore; /* ********************************************************************************************************* * 函 数 名: AppObjCreate * 功能说明: 创建任务通信机制 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppObjCreate (void) { /* 创建信号量,初始值为1,用于二值信号量 */ tx_semaphore_create(&Semaphore, "Semaphore", 1); }
/* ********************************************************************************************************* * 函 数 名: AppTaskLED * 功能说明: 实现对串口的互斥访问 * 形 参: thread_input是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 2 ********************************************************************************************************* */ static void AppTaskLED(ULONG thread_input) { while(1) { /* 通过二值信号量实现资源互斥访问,永久等待直到资源可用 */ tx_semaphore_get(&Semaphore, TX_WAIT_FOREVER); printf("任务AppTaskLED在运行rn"); bsp_LedToggle(1); bsp_LedToggle(4); tx_semaphore_put(&SemaphorE); tx_thread_sleep(100); } } /* ********************************************************************************************************* * 函 数 名: AppTaskMsgPro * 功能说明: 实现对串口的互斥访问 * 形 参: thread_input是在创建该任务时传递的形参 * 返 回 值: 无 * 优 先 级: 3 ********************************************************************************************************* */ static void AppTaskMsgPro(ULONG thread_input) { while(1) { /* 通过二值信号量实现资源互斥访问,永久等待直到资源可用 */ tx_semaphore_get(&Semaphore, TX_WAIT_FOREVER); printf("任务AppTaskMsgPro在运行rn"); bsp_LedToggle(1); bsp_LedToggle(4); tx_semaphore_put(&SemaphorE); tx_thread_sleep(100); } }
有了上面二值信号量的认识之后,互斥信号量与二值信号量又有什么区别呢?互斥信号量可以防止优先级翻转,而二值信号量不支持,下面我们就讲解一下优先级翻转问题。
下面我们通过如下的框图来说明一下优先级翻转的问题,让大家有一个形象的认识。
运行条件:
运行过程描述如下:
上面就是一个产生优先级翻转问题的现象。
ThreadX互斥信号量是怎么实现的呢?其实相对于二值信号量,互斥信号量就是解决了一下优先级翻转的问题。下面我们通过如下的框图来说明一下ThreadX互斥信号量的实现,让大家有一个形象的认识。
运行条件:
运行过程描述如下:
上面就是一个简单的ThreadX互斥信号量的实现过程。
互斥信号量仅支持用在ThreadX的任务中,中断函数中不可使用。
函数原型:
函数描述:
此函数用于创建互斥信号量。
1、 第1个参数是互斥信号量控制块。
2、 第2个参数是互斥信号量名字。
3、 第3个参数用于设置是否使能优先级继承
TX_INHERIT使能优先级继承,即支持优先级反转。
TX_NO_INHERIT关闭优先级继承。
4、 返回值
TX_succesS (0x00) 互斥信号量创建成功。
TX_MUTEX_ERROR (0x1C) 无效的互斥信号量控制块或者互斥信号量已经创建。
TX_CALLER_ERROR (0x13) 无效调用。
TX_INHERIT_ERROR (0x1F) 无效的优先级继承参数。
注意事项:
使用举例:
static TX_MUTEX AppPrintfSemp; /* 用于printf互斥 */ /* 创建互斥信号量 */ tx_mutex_create(&AppPrintfSemp,"AppPrintfSemp",TX_INHERIT);
函数原型:
函数描述:
此函数用于获取互斥信号量,如果互斥信号量已经被调用的任务所拥有,再次调用会触发所有权计数变量加1操作。如果互斥信号量被一个低优先级任务所拥有,并且在创建互斥信号量的时候使能了优先级继承,那么高优先级任务也要获取互斥信号量时,这个低优先级任务的优先级将提升到和高优先级任务一个等级。
1、 第1个参数是互斥信号量控制块。
2、 第2个参数是等待选项:
如果互斥信号量被一个任务锁拥有,这个形参将派上用场:
3、 返回值
注意事项:
使用举例:
static TX_MUTEX AppPrintfSemp; /* 用于printf互斥 */ /* ********************************************************************************************************* * 函 数 名: App_Printf * 功能说明: 线程安全的printf方式 * 形 参: 同printf的参数。 * 在C中,当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 * 返 回 值: 无 ********************************************************************************************************* */ static void App_Printf(const char *fmt, ...) { char buf_str[200 + 1]; /* 特别注意,如果printf的变量较多,注意此局部变量的大小是否够用 */ va_list v_args; va_start(v_args, fmt); (void)vsnprintf((char *)&buf_str[0], (size_t ) sizeof(buf_str), (char const *) fmt, v_args); va_end(v_args); /* 互斥操作 */ tx_mutex_get(&AppPrintfSemp, TX_WAIT_FOREVER); printf("%s", buf_str); tx_mutex_put(&AppPrintfSemp); }
函数原型:
UINT tx_semaphore_put(TX_SEMAPHORE *semaphore_ptr);
函数描述:
此函数用于释放互斥信号量,当互斥信号量所有权计数变量为0时(每次嵌套调用,此变量都会执行加1操作,释放时执行减1操作),互斥资源才可用。
1、 第1个参数是信号量控制块。
2、 返回值
TX_succesS (0x00) 互斥信号量创建成功。
TX_NOT_owneD(0x1E) 互斥信号量不被调用者所拥有。
TX_MUTEX_ERROR (0x1C) 无效的互斥信号量控制块或者互斥信号量已经创建。
TX_CALLER_ERROR (0x13) 无效调用。
使用举例:
static TX_MUTEX AppPrintfSemp; /* 用于printf互斥 */ /* ********************************************************************************************************* * 函 数 名: App_Printf * 功能说明: 线程安全的printf方式 * 形 参: 同printf的参数。 * 在C中,当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 * 返 回 值: 无 ********************************************************************************************************* */ static void App_Printf(const char *fmt, ...) { char buf_str[200 + 1]; /* 特别注意,如果printf的变量较多,注意此局部变量的大小是否够用 */ va_list v_args; va_start(v_args, fmt); (void)vsnprintf((char *)&buf_str[0], (size_t ) sizeof(buf_str), (char const *) fmt, v_args); va_end(v_args); /* 互斥操作 */ tx_mutex_get(&AppPrintfSemp, TX_WAIT_FOREVER); printf("%s", buf_str); tx_mutex_put(&AppPrintfSemp); }
配套例子:
V6-3015_ThreadX Semaphore
实验目的:
实验内容:
1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况
========================================================
CPU利用率 = 0.89%
任务执行时间 = 0.586484645s
空闲执行时间 = 85.504470575s
中断执行时间 = 0.173225395s
系统总执行时间 = 86.264180615s
=======================================================
任务优先级 任务栈大小 当前使用栈 最大栈使用 任务名
Prio StackSize curstack MaxStack Taskname
2 4092 303 459 App Task Start
5 4092 167 167 App Msp Pro
4 4092 167 167 App Task UserIF
5 4092 167 167 App Task COM
0 1020 191 191 System Timer Thread
串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。
App Task Start任务 :启动任务,这里用作BSP驱动包处理。
App Task MspPro任务 :消息处理,这里用作信号量获取。
App Task UserIF任务 :按键消息处理。
App Task COM任务 :这里用作LED闪烁。
System Timer Thread任务:系统定时器任务
2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。
(2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。
3、默认上电是通过串口打印信息,如果使用RTT打印信息
(1) MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可
#define Enable_RTTViewer 1
(2) Embedded studio继续使用此宏定义为0, 因为Embedded studio仅制作了调试状态RTT方式查看。
串口打印信息方式(AC5,AC6和IAR):
波特率 115200,数据位 8,奇偶校验位无,停止位 1
RTT打印信息方式(AC5,AC6和IAR):
Embedded studio仅支持调试状态RTT打印:
由于Embedded studio不支持中文,所以中文部分显示乱码,不用管。
程序执行框图:
本章节主要为大家讲解了另一个重要的资源共享机制-互斥信号量,其中优先级翻转是互斥信号量中一个比较重要的概念,初学者要花些时间去掌握这个知识点。
以上是大佬教程为你收集整理的【STM32F429】第20章 ThreadX互斥信号量全部内容,希望文章能够帮你解决【STM32F429】第20章 ThreadX互斥信号量所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。