2026年8月17日月曜日

FreeRTOS on Raspberry Pi Pico (ツールのOSでSMPを選択)

書き込む際には、予めBOOTbuttonをつかってuf2が書き込めるようにしておく

書き込んだらIDEを閉じて再度開いてシリアルモニタする

 /******************************************************

 * FreeRTOS Mutex例題

 * - タスク2つ

 * 共有データの競合回避

 ******************************************************/

SemaphoreHandle_t xMutex;     

// Mutex変数定義 freertosではSemaphoreをMutexにも使う

volatile int sharedCounter = 0;   // 共有リソース、

// volatile をつけると、「この変数は外部から書き換わるかもしれないので、毎回メモリからちゃんと読み込んで」と指示できます

//==== タスク1 カウント値Serial送信 ====

void Task1(void *pvParameters) {

  while(1){

    if(xSemaphoreTake(xMutex, portMAX_DELAY)== pdTRUE){

// // 例:100ミリ秒だけ待つ設定(pdMS_TO_TICKSでミリ秒をシステム時間に変換) if (xSemaphoreTake(xMutex, pdMS_TO_TICKS(100)) == pdTRUE) { // 100ms以内にMutexを取れた場合の処理 xSemaphoreGive(xMutex); } else { // 100ms待っても取れなかった場合のタイムアウト処理 }

      int temp = sharedCounter;       // 共有データ取得

      temp++;

      vTaskDelay(pdMS_TO_TICKS(10));  // あえて遅延を入れて競合を誘発

      sharedCounter = temp;           // 共有データ更新

      Serial.printf("Task1: counter=%d\n", sharedCounter);

      xSemaphoreGive(xMutex); // MUTEX解放

    }

  }

}

//==== タスク2 カウント値Serial送信 ====

void Task2(void *pvParameters) {

  while(1){

    if(xSemaphoreTake(xMutex, portMAX_DELAY)== pdTRUE){

      int temp = sharedCounter;       // 共有データ取得

      temp++;

      vTaskDelay(pdMS_TO_TICKS(10));  // あえて遅延を入れて競合を誘発

      sharedCounter = temp;           // 共有データ更新

      Serial.printf("Task2: counter=%d\n", sharedCounter);

      xSemaphoreGive(xMutex);  

    }    

  }

}

//==== 初期設定 ====

void setup() {

  Serial.begin(115200);

  delay(1000);

  // 開始メッセージ

  Serial.println("\r\n=== Mutex counter demo ===");

  // Mutex生成

  xMutex = xSemaphoreCreateMutex(); //xTaskCreateで自動的に組み込まれる?

  // タスクの生成

  xTaskCreate(Task1, "task1", 2048, NULL, 1, NULL);

// xTaskCreate(Task1, "task1", 2048, NULL, 1, NULL);

                     ②       ③     ④   ⑤   ⑥
コードは注意してご使用ください。
番号引数意味詳しい説明
Task1実行する関数名タスクとして動かしたいC言語の関数を指定します。
"task1"タスクの作業名人間が見て分かりやすくするための名前です(デバッグ用)。
2048スタックサイズこのタスクがメモリ(スタック)を何バイト使うか(※)の指定です。
NULL関数への引数タスク関数にデータを渡さない場合は NULL にします。
1タスクの優先度数字が大きいほど優先されます。標準的な低い優先度です。
NULLタスクハンドル作成したタスクを後から削除・操作しない場合は NULL にします。
※注意(スタックサイズの単位について)
ESP32(Arduino等)では「バイト数(2048バイト)」ですが、一般的なFreeRTOS(マイコンによる)では「ワード数(4バイト単位なら2048×4=8192バイト)」を意味します。ESP32環境であれば2KBのメモリ確保という意味になります。

  xTaskCreate(Task2, "task2", 2048, NULL, 1, NULL);

}

//= アイドルループ ==

void loop() {}

ーーーーーーーーーーーーーーーーーーーーーーーーー

0 件のコメント:

コメントを投稿