1.使用到的API
1 2 3 4 5
| SemaphoreHandle_t xHandler; xHandler = xSemaphoreCreateBinary(); xSemaphoreGive(xHandler); xSemaphoreTake(xHanlder, timeout); xSemaphoreGiveFromISR(xHandler, portBASE_TYPE *pxHigherPriorityTaskWoken);
|
pxHigherPriorityTaskWoken:对某个信号量而言,可能有不止一个任务处于阻塞态在等待其有效。调用 xSemaphoreGiveFromISR()会让信号量变为有效,所以会让其中一个等待任务切出阻塞态。如果调用 xSemaphoreGiveFromISR()使得一个任务解除阻塞,并且这个任务的优先级高于当前任务(也就是被中断的任务),那么 xSemaphoreGiveFromISR()会在 函 数 内 部 将 *pxHigherPriorityTaskWoken 设为pdTRUE。如果 xSemaphoreGiveFromISR() 将 此 值 设 为pdTRUE,则在中断退出前应当进行一次上下文切换。这样才能保证中断直接返回到就绪态任务中优先级最高的任务中。
2.使用案例(按键控制LED开关)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void flashLED(void *pvParam) {
pinMode(23, OUTPUT); while (1) { if (xSemaphoreTake( xSemaLED, timeOut) == pdPASS ) { if ((xTaskGetTickCount() - btnDeounce) < 100) { digitalWrite(23, !digitalRead(23)); vTaskDelay(1000); } } } }
void readBtn(void *pvParam) {
pinMode(22, INPUT_PULLUP);
while (1) { if (digitalRead(22) == LOW) { xSemaphoreGive(xSemaLED); } } }
attachInterrupt(22, ISR, FALLING); void IRAM_ATTR ISR() { btnDeounce = xTaskGetTickCountFromISR(); xSemaphoreGiveFromISR(xSemaLED, NULL); }
|