文章目录
- 一、前言
- 二、实验目的
- 三、API
- 3.1、osSemaphoreAttr_t
- 3.2、osSemaphoreNew
- 3.3、osSemaphoreAcquire
- 3.4、osSemaphoreRelease
- 3.5、osSemaphoreGetCount
- 四、代码
- 4.1、main.h
- 4.2、main.c
- 五、Event Recorder调试
- 5.1、线程A每隔1S时间运行一次
- 5.1、按下按键KEY0,获取全部信号量
- 5.2、按下按键KEY1,释放信号量
一、前言
信号量常用于管理和保护对共享资源的访问,信号量跟互斥量非常相似。在同一个时刻上互斥量只允许一个线程访问共享的资源,但是,信号量允许一个固定的数量的线程或ISR同时访问共享资源池。使用信号量,可以管理访问一组相同的外设(比如多个DMA channels)。
一个信号量对象应该被初始化为可使用的共享资源的最大数量。可使用的共享资源的最大数量是通过函数osSemaphoreNew设定的。每一次信号量的获取是使用osSemaphoreAcquire获得(信号量在有效的状态下),接着信号量的数量被递减。当信号量的数量是0时,就没有更多的信号量可以被获取。此时,线程与ISR继续从此信号量对象获取信号量时,就会进入阻塞态一直等待,直到其他线程或ISR使用osSemaphoreRelease将信号量释放,信号量的数量递增。
以上都是从RTX5官方文档翻译过来的。除此之外,我强烈建议把《嵌入式实时操作系统uc/OS-III》的第13章-资源管理仔细读几遍,在实际工作中反复思考。
STM32工程:
链接:https://pan.baidu.com/s/1SBWXuNQqf-9tWJdEPgJdoA 提取码:5kti
二、实验目的
1、线程A每隔1s时间就会从信号量New Semaphore获取一个信号量,获取成功的话,打印信息表示获取成功。获取不了的话,进入阻塞态,直到信号量New Semaphre有信号量被线程A获取。
2、按下按键KEY0,从信号量New Semaphore获取一个信号量(不会将信号量释放回去)。
3、按下按键KEY1,将信号量New Semaphore的信号量释放回去。
4、连续按下按键KEY0,将信号量New Semaphore的信号量全部获取后,线程A将一直保持阻塞态,不能运行。接着,按下KEY1将信号量释放后,线程A又能周期地运行下去了。
三、API
3.1、osSemaphoreAttr_t
/* 信号量属性 */
const osSemaphoreAttr_t sema_New_Attr =
{
.name = "New Semaphore", /* 信号量的名字 */
};
3.2、osSemaphoreNew
/* 使用案例1 */
osSemaphoreId_t semaID_New = NULL; /* 保存信号量ID */
/* 创建信号量 */
semaID_New = osSemaphoreNew(5U, /* 信号量的最大值为5 */
5U, /* 信号量的初始值为5 */
&sema_New_Attr /* 信号量的属性 */
);
/* 使用案例2 */
osSemaphoreId_t semaID_New = NULL; /* 保存信号量ID */
/* 创建信号量(当信号量的最大值为1时,信号量就类似一个互斥量了) */
semaID_New = osSemaphoreNew(1U, /* 信号量的最大值为1 */
1U, /* 信号量的初始值为1 */
&sema_New_Attr /* 信号量的属性 */
);
3.3、osSemaphoreAcquire
/* 使用案例1 */
status = osSemaphoreAcquire(semaID_New,osWaitForever); /* 获取信号量,一直等到有信号量 */
switch(status)
{
case osOK:
printf("the semaphore is got successfully.\r\n"); /* 打印信息 */
break;
case osErrorResource:
printf("occur osErrorResource.\r\n"); /* 打印信息 */
break;
case osErrorParameter:
printf("occur osErrorParameter.\r\n"); /* 打印信息 */
break;
default:
break;
}
/* 使用案例2 */
status = osSemaphoreAcquire(semaID_New,10U); /* 获取信号量,超时时间10个time ticks */
switch(status)
{
case osOK:
printf("the semaphore is got successfully.\r\n"); /* 打印信息 */
break;
case osErrorResource:
printf("occur osErrorResource.\r\n"); /* 打印信息 */
break;
case osErrorParameter:
printf("occur osErrorParameter.\r\n"); /* 打印信息 */
break;
default:
break;
}
3.4、osSemaphoreRelease
osSemaphoreRelease(semaID_New); /* 释放一个信号量 */
3.5、osSemaphoreGetCount
uint32_t number_Of_Sema;
number_Of_Sema = osSemaphoreGetCount(semaID_New); /* 获取当前的信号量剩余数量 */
四、代码
4.1、main.h
4.2、main.c
五、Event Recorder调试
5.1、线程A每隔1S时间运行一次
5.1、按下按键KEY0,获取全部信号量
5.2、按下按键KEY1,释放信号量