1、硬件信号量和软件信号量的区别
1.1、软件信号量
比如freertos里的Semaphore,通常使用阻塞的方式,使用共享资源。
接口 | 作用 |
---|---|
xSemaphoreTake(sem, 0) | 非阻塞(轮询) |
xSemaphoreTake(sem, pdMS_TO_TICKS(2000)) | 阻塞 |
xSemaphoreTake不能在服务中断程序中调用,如果有必要,可以调用xQueueReceiveFromISR() 来在中断服务程序中获取信号量,虽然这并不是一种正规的操作。
软件信号量必须已经通过调用vSemaphoreCreateBinary(), xSemaphoreCreateMutex() 或 xSemaphoreCreateCounting()来创建。
1.2、硬件信号量
hsem这个硬件信号量,只有非阻塞结合查状态、中断这两种方式,使用共享资源。
非阻塞+查状态方式:不会阻塞任何任务,需要对接口返回值加以判断,再执行不同的操作。
中断方式:当获取不到信号量时,使能对应信号量的中断,当别的任务或核有释放动作时,产生中断,通知你信号量可以获取了。
硬件信号量可以直接获取,无需初始化,获取成功与否会有不同返回值。
2、HSEM硬件信号量工作原理
2.1、获取信号量的两种方式
每个信号量都有一个独立的Rx寄存器和RLRx寄存器。
2.1.1、hsem_take(2步),释放信号量(1步)
获取:先写 Rx[信号量编号] 寄存器,再读回校验。
释放:写Rx [信号量编号] 寄存器。
2.1.2、hsem_fast_take(1步),释放信号量(1步)
获取:直接读 RLRx [信号量编号] 寄存器。
释放:写Rx [信号量编号] 寄存器。
3、中断用法
使能对应信号量的中断,当别的任务或核有释放动作时,产生中断,通知你信号量可以获取。
如何发通知?一步 take + 一步release
一定要和软件信号量的用法区分开来,不然很容易混淆。
使用硬件信号量,代码加返回值判断很重要,基本上全靠返回值决定软件流程。