天天看點

FreeRTOS專欄13:計數型信号量

計數型信号量簡介:

FreeRTOS專欄13:計數型信号量

計數型信号量的建立:

FreeRTOS專欄13:計數型信号量

計數型信号量動态建立函數:

FreeRTOS專欄13:計數型信号量
FreeRTOS專欄13:計數型信号量

釋放和擷取信号量(與二值信号量相同)

FreeRTOS專欄13:計數型信号量

釋放信号量:

FreeRTOS專欄13:計數型信号量
FreeRTOS專欄13:計數型信号量

擷取信号量:

FreeRTOS專欄13:計數型信号量
FreeRTOS專欄13:計數型信号量
FreeRTOS專欄13:計數型信号量

測試實驗

用按鍵來模拟事件,按鍵按下後表示有事件發生,則釋放計數型信号量。

建立兩個任務,任務1用于按鍵檢測和釋放信号量,按鍵2用于擷取信号量。

測試程式如下所示:

void start_task(void *pvParameters)
{
  taskENTER_CRITICAL();
  count_semphr = xSemaphoreCreateCounting(5, 0);
  if (count_semphr != NULL)
  {
    printf("計數型信号量建立成功\n");
  }
  else
  {
    printf("計數型信号量建立失敗\n");
  }

  // 建立任務1
  xTaskCreate((TaskFunction_t ) task1_task,
              (char *         ) "task1_task",
              (uint16_t       ) TASK1_TASK_SIZE,
              (void *         ) NULL,
              (UBaseType_t    ) TASK1_TASK_PRIO,
              (TaskHandle_t * ) &Task1_Handle);
  // 建立任務2
  xTaskCreate((TaskFunction_t )task2_task,
              (char *         )"task2_task",
              (uint16_t       )TASK2_TASK_SIZE,
              (void *         )NULL,
              (UBaseType_t    )TASK2_TASK_PRIO,
              (TaskHandle_t * )&Task2_Handle);
  taskEXIT_CRITICAL();
  // 删除開始任務
  vTaskDelete(Start_Task_Handle);
}

void task1_task(void *pvParameters)
{
  BaseType_t error_state;
  for (;;)
  {
    // 按鍵KEY1用于釋放信号量
    if (key_scan(KEY1_GPIO_Port, KEY1_Pin) == KEY_ON)
    {
      if (count_semphr != NULL)
      {
        error_state = xSemaphoreGive(count_semphr);
        if (error_state == pdTRUE)
        {
          printf("信号量釋放成功\n");
        }
        else
        {
          printf("信号量釋放失敗\n");
        }
      }
    }
    vTaskDelay(20);
  }
}

void task2_task(void *pvParameters)
{
  BaseType_t error_state;
  UBaseType_t current_semphr_value;
  for (;;)
  {
    // 按鍵KEY2用于擷取信号量
    if (key_scan(KEY2_GPIO_Port, KEY2_Pin) == KEY_ON)
    {
      if (count_semphr != NULL)
      {
        // 等待擷取信号量
        error_state = xSemaphoreTake(count_semphr, portMAX_DELAY);
        if (error_state == pdTRUE)
        {
          printf("擷取信号量成功\n");
          current_semphr_value = uxSemaphoreGetCount(count_semphr);
          printf("目前信号量計數值為%d\n", (int)current_semphr_value);
        }
        else
        {
          printf("擷取信号量失敗\n");
        } 
      }
    }
    vTaskDelay(50);
  }
}
           

測試結果:

FreeRTOS專欄13:計數型信号量
上一篇: Math(js)