freetros 信号量使用方法实例解析
1. 相关函数介绍
osSemaphoreNew
:创建并初始化一个信号量对象。osSemaphoreGetName
:获取信号量对象的名称。osSemaphoreAcquire
:获取信号量令牌,如果当前没有令牌,则超时放弃。osSemaphoreRelease
:释放一个信号量令牌,直到初始最大计数。osSemaphoreGetCount
:获取当前信号量令牌计数。osSemaphoreDelete
:删除信号量对象。
2. 实例代码
// 定义信号量句柄和控制块等
osSemaphoreId_t myCountingSem01Handle;
osStaticSemaphoreDef_t myCountingSem01ControlBlock;
const osSemaphoreAttr_t myCountingSem01_attributes = {
.name = "myCountingSem01",
.cb_mem = &myCountingSem01ControlBlock,
.cb_size = sizeof(myCountingSem01ControlBlock),
};
// 创建信号量的函数
void initTask( void ){
// 创建计数信号量,初始值和最大值都为3
myCountingSem01Handle = osSemaphoreNew(3, 3, &myCountingSem01_attributes);
}
// 释放信号量的任务函数
void mainTask(void *argument){
int cnt;
osStatus_t sem_osStatus;
for(;;) {
// 释放计数信号量
sem_osStatus = osSemaphoreRelease(myCountingSem01Handle);
if( sem_osStatus == osOK ){
printf("mainTask: osSemaphoreRelease \r\n");
// 获取当前的计数值
cnt = osSemaphoreGetCount(myCountingSem01Handle);
printf("mainTask osSemaphoreGetCount: %d \r\n", cnt);
}
osDelay(30);
}
}
// 获取信号量的任务函数
void monitorTask(void *argument){
osStatus_t sem_osStatus;
int cnt;
for(;;) {
// 获取计数信号量,等待超时时间为100
sem_osStatus = osSemaphoreAcquire(myCountingSem01Handle, 100);
if( sem_osStatus == osOK ){
printf("monitorTask: osSemaphoreAcquire \r\n");
// 获取当前的计数值
cnt = osSemaphoreGetCount(myCountingSem01Handle);
printf("monitorTask osSemaphoreGetCount: %d \r\n", cnt);
}
osDelay(10);
}
}
3. 代码解析
- 首先,定义了
myCountingSem01Handle
作为信号量句柄,myCountingSem01ControlBlock
作为静态信号量控制块,myCountingSem01_attributes
用于设置信号量的属性,包括名称、控制块内存和大小。 - 在
initTask
函数中,使用osSemaphoreNew
函数创建了一个名为myCountingSem01
的计数信号量,初始值和最大值都为 3。 mainTask
函数中,通过osSemaphoreRelease
不断释放信号量,并在释放成功后使用osSemaphoreGetCount
获取当前信号量的计数值并打印。monitorTask
函数中,通过osSemaphoreAcquire
尝试获取信号量,设置了超时时间为 100。如果获取成功,同样使用osSemaphoreGetCount
获取当前计数值并打印。
4. 测试结果
编译代码并下载到板卡上运行后,根据计数信号量的定义,当Task
获取到信号时,计数值会减一;当Task
释放信号时,计数值会加一。通过打印的日志信息可以验证信号量的使用是否符合预期。例如,mainTask
释放信号量后计数值增加,monitorTask
获取信号量后计数值减少。