freertos 创建互斥量_FreeRTOS 学习四:信号量和互斥锁

1. 简介:此篇文章中涉及的函数除特殊说明,包含的头文件都是 semphr.h

二值信号量同linux中的原子量,我们可以看成像是一个锁,在使用的时候,需要能拿到锁才能执行程序,尝试拿不到锁,不能运行。

二值信号量和互斥锁功能很相似,但是也有一些微妙的不同,互斥锁包括一个优先级集成机制,二值信号量没有。因此,任务和任务、任务和中断之间的同步的时候,二值信号量是一个更好的选择。简单的排斥情况使用互斥锁2. 函数2.1 二值信号量创建:typedef void * QueueHandle_t;typedef QueueHandle_t SemaphoreHandle_t;SemaphoreHandle_t xSemaphoreCreateBinary( void );1

2

3

41

2

3

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

2

3

4

5

6

7

8

9

10

11

121

2

3

4

5

6

7

8

9

10

11

12

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

2

3

4

51

2

3

4

5参数: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);1

2

3

4

51

2

3

4

5参数: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 );1

2

3

41

2

3

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

作者:老鹏(老学员)时间:2016年12月19日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值