2018年8月16日 星期四

深度探索Arduino[In-depth exploration Arduino] 之 2 :在Arduino上執行 FreeRTOS創建兩個Task(TaskBlink1,TaskBlink2),加入外部中斷控制,利用Binary semaphores實現中斷與TASK同步

深度探索Arduino[In-depth exploration Arduino] 之 2 :在Arduino上執行 FreeRTOS創建兩個Task(TaskBlink1,TaskBlink2),加入外部中斷控制,利用Binary semaphores實現中斷與 TaskBlink2同步,兩個Task分別控制不同的LED。

範例DEMO影片:

功能描述:
TaskBlink1 執行 void TaskBlink1(void *pvParameters) 函數,其優先權是1(數值越低優先權越低,0是最低優先權),TaskBlink1僅在固定時間將LED做toggle(閃爍切換)。

TaskBlink2 執行 void TaskBlink2(void *pvParameters) 函數,其優先權是3 高優先權。而TaskBlink2必須成功“獲取” semaphore時,才往下執行程式,所以 TaskBlink2 嘗試“獲取”semaphore時,當無法獲取時會進入阻塞狀態(Blocked state),且這裡程式設定阻塞時間最大的 'ticks' 數是portMAX_DELAY,所以 TaskBlink2 會被阻塞(Blocked)在此,等待“獲取”semaphore。程式片段如下:
if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE )

此 FreeRTOS/Arduino程式範例加入外部中斷,設定buttonPin 2有按下時,在下降緣觸發 ExternalInterrupt 中斷Handler,此 ExternalInterrupt 中斷Handler是送出一semaphore,來實現 ExternalInterrupt中斷與 TaskBlink2同步。程式片段如下:
void setup() {
  ...
  pinMode(buttonPin, INPUT);
  attachInterrupt(digitalPinToInterrupt( buttonPin ), ExternalInterrupt, FALLING);
  ...
}
static void ExternalInterrupt()
{
  static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
  if( xHigherPriorityTaskWoken == pdTRUE )
    vPortYield();
}

當TaskBlink2成功獲取semaphore時,就往下執行,讓另一個LED亮一下,程式片段如下:
void TaskBlink2(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  pinMode(12, OUTPUT); // initialize digital LED on pin 12 as an output.
  digitalWrite(12, HIGH);   // turn the LED on (HIGH is the voltage level)
  for (;;)
  {
    if( xSemaphoreTake( xSemaphore, portMAX_DELAY ) == pdTRUE )
    {
      digitalWrite(12, LOW);    // turn the LED off by making the voltage LOW
      vTaskDelay( 500 / portTICK_PERIOD_MS ); // wait for one second
      digitalWrite(12, HIGH);   // turn the LED on (HIGH is the voltage level)
    }
  }
}

最後一個很重要的觀念,簡單介紹,FreeRTOS的Binary semaphores與Mutual exclusion兩者功能很相似,但有一些細微差別。Mutual exclusion包括優先級繼承機制,而Binary semaphores是不包含。所以使得Binary semaphores成為實現像任務之間或任務與中斷之間的同步是更好的選擇,那Mutual exclusion是實現簡單互斥的最佳選擇。

完整程式碼:

沒有留言:

張貼留言

FPGA Verilog 的學習經驗,提供給要入門的新手

今天簡單說說 FPGA Verilog 的學習經驗,提供給要入門的新手: 1.對自己寫的FPGA Verilog程式,所生成的數位電路要心中有數。 這一點個人認為很重要,就正如寫 C語言,心中要能生成對應的組合語言一樣,我是這樣要求自己的。 雖然 FPGA Verilog語言...