打印

FreeRTOS 学习四:信号量和互斥锁

[复制链接]
234|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
3月的尾巴|  楼主 | 2018-8-22 09:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1. 简介:此篇**中涉及的函数除特殊说明,包含的头文件都是 semphr.h二值信号量同linux中的原子量,我们可以看成像是一个锁,在使用的时候,需要能拿到锁才能执行程序,尝试拿不到锁,不能运行。二值信号量和互斥锁功能很相似,但是也有一些微妙的不同,互斥锁包括一个优先级集成机制,二值信号量没有。因此,任务和任务、任务和中断之间的同步的时候,二值信号量是一个更好的选择。简单的排斥情况使用互斥锁

2. 函数2.1 二值信号量创建:typedef void * QueueHandle_t;typedef QueueHandle_t SemaphoreHandle_t;SemaphoreHandle_t xSemaphoreCreateBinary( void );1234

1234

返回值:非NULL,返回的是一个二值信号量的指针又叫句柄NULL,因内存不足,创建不成功说明:1.在FreeRTOS的这个函数的界面上有一个重要的提示,在大多数情况下,直接使用任务的notification会比直接使用这个二值信号量要对内存使用高效,此函数依然2.这个函数的使用需要配置宏 configSUPPORT_DYNAMIC_ALLOCATION = 1,不过这个值默认就是13.每个二值信号量都需要一点ram空间来保存信号量的状态4.此函数也有一个xSemaphoreCreateBinaryStatic()函数,用于在编译的时候就确定在ram中的位置5.vSemaphoreCreateBinary函数是之前版本的函数,现版本使用的是xSemaphore…2.2 信号量创建:SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )1

1

参数:uxMaxCount,最大计数量uxInitialCount ,信号量的初始值,当此信号量用于资源管理,值应该为0,当用于资源管理时,应该设为uxMaxCount返回值:非NULL,信号量的句柄NULL,因内存空间不足,创建失败说明:1.这个函数的使用需要配置宏 configSUPPORT_DYNAMIC_ALLOCATION = 1,不过这个值默认就是12.此函数也有一个static后缀的函数:xSemaphoreCreateCountingStatic,在是编译的时候分配固定的地址2.3 互斥量创建:SemaphoreHandle_t xSemaphoreCreateMutex( void );1

1

返回值:非NULL,信号量的句柄NULL,因内存空间不足,创建失败说明:1.这个函数的使用需要配置宏 configSUPPORT_DYNAMIC_ALLOCATION = 1,不过这个值默认就是12.此函数也有一个static后缀的函数:xSemaphoreCreateMutexStatic,在是编译的时候分配固定的地址2.4 递归互斥锁创建:递归互斥锁的使用是为了部分情况下解决死锁的问题,死锁出现的情况如下代码:// 不加锁版本void foo_nolock(){    // do something}// 加锁版本void fun(){    mutex.lock();    foo_nolock();    mutex.unlock();} 123456789101112

123456789101112

言归正传:

SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );1

1

返回值:非NULL,信号量的句柄NULL,因内存空间不足,创建失败说明:1.此函数需要配置 configSUPPORT_DYNAMIC_ALLOCATION = 1 和 configUSE_RECURSIVE_MUTEXES = 1,默认值,两个都是12.有一个static后缀的函数,此处不多说,需要配置configSUPPORT_DYNAMIC_ALLOCATION = 02.5 删除信号量:void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );1

1

参数:xSemaphore,要操作的信号量的句柄说明:能删除递归信号量和非递归的信号量不要删除阻塞任务的信号量2.6 获取信号量:xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );/* 中断中使用 */xSemaphoreTakeFromISR( SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken );/* 递归互斥量时获取 */xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex, TickType_t xTicksToWait );12345

12345

参数:xSemaphore,信号量的句柄xMutex,互斥锁的句柄xTicksToWait,阻塞等待时间,portTICK_PERIOD_MS用于将ms单位转换成tick,如果 INCLUDE_vTaskSuspend = 1,这个值设成portMAX_DELAY,则会限阻塞等待pxHigherPriorityTaskWoken,如果中断中调用中断的这个函数引起一个任务从阻塞态变成非阻塞状态,并且变成非阻塞状态的优先级高于目前的任务,这个指针指向的变量的值变成pdTRUExSemaphoreTake和xSemaphoreTakeRecursive返回值:pdTRUE,获取成功pdFALSE,时间超时后,还没得到信号量xSemaphoreTakeFromISR返回值:pdTRUE,获取成功pdFALSE,获取不成功2.7 归还/释放信号量:xSemaphoreGive( SemaphoreHandle_t xSemaphore );/* 中断中使用 */xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken );/* 递归互斥量时使用 */xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex);12345

12345

参数:xSemaphore,信号量的句柄xMutex,互斥锁的句柄xTicksToWait,阻塞等待时间,portTICK_PERIOD_MS用于将ms单位转换成tick,如果 INCLUDE_vTaskSuspend = 1,这个值设成portMAX_DELAY,则会限阻塞等待pxHigherPriorityTaskWoken,如果中断中调用中断的这个函数引起一个任务从阻塞态变成非阻塞状态,并且变成非阻塞状态的优先级高于目前的任务,这个指针指向的变量的值变成pdTRUE,之后应该有一个任务上线文的切换xSemaphoreGive返回值:pdTRUE,释放成功pdFALSE,释放出现错误xSemaphoreGiveFromISR返回值:pdTRUE,释放成功errQUEUE_FULL,释放出现错误xSemaphoreGiveRecursive返回值:pdTRUE,释放成功2.8 其他对信号量的操作:/* 查询信号量的数目 */UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );/* 查询拥有互斥锁的任务句柄 */TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );1234

1234

uxSemaphoreGetCount返回值:返回信号量的数目xSemaphoreGetMutexHolder返回值:非NULL,任务持有互斥信号量的任务句柄NULL,xMutex不是一个互斥信号量或者信号量没有被任务持有xSemaphoreGetMutexHolder需要注意:需要配置configUSE_MUTEXES = INCLUDE_xSemaphoreGetMutexHolder = 1

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

433

主题

433

帖子

0

粉丝