freertos- 信号其操作API

如图1所示,信号量目的

  • 解决共享资源的访问问题。
  • 处理实现任务-中断/任务-任务间的同步。问题(一个任务可继续执行的触发时机)

2,信号量分类

  • 二值信号量:适合任务间的同步
  • 数值信号量
  • 互斥信号量:具有优先级继承机制,适合任务间对资源的互斥访问。
  • 递归互斥信号量

3,特征

  • 因为信号量阻塞的任务,信号量获取时,高优先级任务优先接触阻塞。
  • 二值信号量是使用仅有1个队列项的队列实现的(是否是满)。
  • 分为中断级别接口和应用级别接口。

4,相关API

 

//定义信号量的句柄类型(等同于队列句柄类型)
//队列句柄类型(typedef void * QueueHandle_t;)
typedef QueueHandle_t SemaphoreHandle_t;

#define semBINARY_SEMAPHORE_QUEUE_LENGTH	( ( uint8_t ) 1U )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH		( ( uint8_t ) 0U )
#define semGIVE_BLOCK_TIME			( ( TickType_t ) 0U )


/*
这个旧的vSemaphoreCreateBinary()宏现在被弃用,代之以xSemaphoreCreateBinary()函数。注意,
使用vSemaphoreCreateBinary()宏创建的二进制信号量是在这样一种状态下创建的,即对“take”信号量的第一个调用将通过,
而使用xSemaphoreCreateBinary()创建的二进制信号量是在这样一种状态下创建的,即信号量必须先“give”,然后才能“take”。
 */
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define vSemaphoreCreateBinary( xSemaphore )																							\
		{																																	\          
			//创建一个容量为1,队列项大小为0byte的 queueQUEUE_TYPE_BINARY_SEMAPHORE 类型动态队列
            ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE );	\
			if( ( xSemaphore ) != NULL )																									\
			{																																\
				( void ) xSemaphoreGive( ( xSemaphore ) );																					\
			}																																\
		}
#endif


#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
    #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
#endif


//创建一个新的二进制信号量实例,并返回一个句柄
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
   //创建一个容量为1,队列项大小为0byte的 queueQUEUE_TYPE_BINARY_SEMAPHORE 类型队列
	#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )
#endif /* configSUPPORT_STATIC_ALLOCATION */


 //宏获取一个信号量。这个信号量之前必须通过调用xSemaphoreCreateBinary()、xSemaphoreCreateMutex()或xsemaphorecreat()来创建。
#define xSemaphoreTake( xSemaphore, xBlockTime )		xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )


 //宏以递归方式获取或'take'互斥类型信号量。互斥锁之前必须使用对xSemaphoreCreateRecursiveMutex()的调用来创建;
#if( configUSE_RECURSIVE_MUTEXES == 1 )
	#define xSemaphoreTakeRecursive( xMutex, xBlockTime )	xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
#endif

//宏释放一个信号量。这个信号量之前必须通过调用xSemaphoreCreateBinary()、xSemaphoreCreateMutex()或xsemaphorecreat()来创建。
//并利用sSemaphoreTake()得到。这个宏不能从ISR中使用。参见xSemaphoreGiveFromISR(),了解可以从ISR中使用的替代方案。
#define xSemaphoreGive( xSemaphore )		xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )

//递归释放或'give'互斥锁类型的信号量,互斥锁之前必须通过调用xSemaphoreCreateRecursiveMutex()来创建;
#if( configUSE_RECURSIVE_MUTEXES == 1 )
	#define xSemaphoreGiveRecursive( xMutex )	xQueueGiveMutexRecursive( ( xMutex ) )
#endif



//宏释放一个信号量。这个信号量之前必须通过调用xSemaphoreCreateBinary()或xsemaphorecreat()来创建。
//互斥类型信号量(使用调用xSemaphoreCreateMutex()创建的信号量)不能与这个宏一起使用。这个宏可以从ISR中使用。
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )


//宏从ISR获取信号量。这个信号量之前必须通过调用xSemaphoreCreateBinary()或xsemaphorecreat()来创建。
//互斥类型信号量(使用调用xSemaphoreCreateMutex()创建的信号量)不能与此宏一起使用。这个宏可以从ISR中使用,
//但是从ISR中获取信号量不是一种常见的操作。只有当中断从资源池中获取对象时(当信号量计数指示可用资源的数量时),它才可能有用
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken )	xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )

//创建一个新的互斥量类型信号量实例,并返回一个句柄,通过这个句柄可以引用新的互斥量。
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
#endif


//创建一个新的互斥量类型信号量实例,并返回一个句柄,通过这个句柄可以引用新的互斥量。
 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
	#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
#endif /* configSUPPORT_STATIC_ALLOCATION */


//创建一个新的递归互斥量类型信号量实例,并返回一个句柄,通过这个句柄可以引用新的递归互斥量。
#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
	#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
#endif

//创建一个新的递归互斥量类型信号量实例,并返回一个句柄,通过这个句柄可以引用新的递归互斥量。
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
	#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )
#endif /* configSUPPORT_STATIC_ALLOCATION */

 //创建一个新的计数信号量实例,并返回一个句柄,通过该句柄可以引用新的计数信号量。
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
#endif

//创建一个新的计数信号量实例,并返回一个句柄,通过该句柄可以引用新的计数信号量。
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
	#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
#endif /* configSUPPORT_STATIC_ALLOCATION */

//删除一个信号量。这个函数必须小心使用。例如,如果互斥对象由任务持有,则不要删除互斥类型信号量。
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )


//如果xMutex确实是互斥类型信号量,返回当前的互斥锁持有者。如果xMutex不是互斥类型信号量,或者互斥是可用的(不是由任务持有),则返回NULL。
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )

//如果xMutex确实是互斥类型信号量,返回当前的互斥锁持有者。如果xMutex不是互斥类型信号量,或者互斥是可用的(不是由任务持有),则返回NULL。
#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )

//如果信号量是计数信号量,那么uxSemaphoreGetCount()返回当前的计数值。如果信号量是二进制信号量,那么如果信号量可用,uxSemaphoreGetCount()返回1,如果信号量不可用,返回0。
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )

 

5、核心数据结构

#define semBINARY_SEMAPHORE_QUEUE_LENGTH    ( ( uint8_t ) 1U )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH        ( ( uint8_t ) 0U )
#define semGIVE_BLOCK_TIME                                        ( ( TickType_t ) 0U )

typedef   long                   BaseType_t;
typedef   unsigned long UBaseType_t;

typedef    QueueHandle_t     SemaphoreHandle_t;
typedef    StaticQueue_t       StaticSemaphore_t;

6、信号核心函数

/------------------------Create-----------------------------------

// 创建 二值信号量

void  vSemaphoreCreateBinary(SemaphoreHandle_t   xSemaphore ) 

xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )

SemaphoreHandle_t  xSemaphoreCreateBinaryStatic( StaticSemaphore_t  *pxStaticSemaphore )

xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE )

 //创建 互斥型信号量

SemaphoreHandle_t   xSemaphoreCreateMutex(void)                     

xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )

SemaphoreHandle_t   xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )

xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )

 //创建 递归互斥型信号量

SemaphoreHandle_t  xSemaphoreCreateRecursiveMutex( void )   

xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )

SemaphoreHandle_t  xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )

xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore )

//创建 数值信号量

SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t  uxMaxCount, UBaseType_t uxInitialCount ) 

xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )

SemaphoreHandle_t  xSemaphoreCreateCountingStatic( UBaseType_t  uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )

xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )

/------------------------Take-----------------------------------

  //获取 信号量

void  xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xBlockTime  )

xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )

// 获取 递归互斥型信号量

void xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex, TickType_t xBlockTime  )

xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )

//中断版本

void xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t *pxHigherPriorityTaskWoken )

xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )

/------------------------Give-----------------------------------

//发送 信号量

void  xSemaphoreGive( SemaphoreHandle_t xSemaphore ) 

xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )

// 发送 递归互斥型信号量

void xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )

xQueueGiveMutexRecursive( ( xMutex ) )

//中断版本

void  xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,  BaseType_t *pxHigherPriorityTaskWoken  )

xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )

/------------------------Get-----------------------------------

 // 获取当前信号量的值

UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore )

 uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )

/------------------------Delete-----------------------------------

 // 删除信号量

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )

/------------------------Holder-----------------------------------

 // 获取互斥信号量的持有者

TaskHandle_t  xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex )

xQueueGetMutexHolder( ( xSemaphore ) )

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值