8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

STM32CubeIDEで学ぶFreeRTOS (1) - シグナルイベント(イベントフラグ)

Last updated at Posted at 2019-07-08

前回記事では、ひとまずFreeRTOSを動かしてみる、までやってみました。

今回(から)は、FreeRTOSの主要機能を体験してみたいと思います。

はじめに

CMSIS-RTOS

当初、動作確認においては、FreeRTOSのI/Fをまんま使おうかと思っていました。

がしかし、STM32CubeIDEの生成コードを見るに、CMSIS I/Fでラップしている模様です。
郷に入りては、、、で、そいつに従うこととします。仕様は以下。

Function Overview
http://www.keil.com/pack/doc/CMSIS/RTOS/html/functionOverview.html

機能を選ぶ

RTOSといえばタスク間通信、タスク間通信で最も簡単なものといえば、イベントフラグでしょう。

前述CMSISによれば、こいつを**「シグナルイベント」**と呼ぶらしいです。今回はそれを紹介します。

本編

1. 環境

前回記事と同じです。
なお、FreeRTOSの有効化やタスク追加等はこの記事に倣っていますので、いったんは試してみることをお勧めします。

2. やってみよう!

実現仕様は以下。地味に高機能です。

  1. UART受信を割り込みで受ける
  2. 割り込みで受信した旨をタスクにイベント通知
  3. イベントを受けたタスクは、単にエコーバック

2-1. U(S)ART割り込み有効化

「Device Configuration Tool」(iocファイルが開いた状態)の左側、「Categories」から「Connectivity」-「USART1」を選びます。
その後、「NVIC Settings」タブで、割り込みを有効化します。
SnapCrab_STM32CubeIDE - Device Configuration Tool - STM32CubeIDE_2019-7-8_14-51-34_No-00.png

設定変更したので、コード生成も忘れずに!

2-2. 割り込み実装

main.cの上部、「/* USER CODE BEGIN 0 */」の箇所を以下とします。

/* USER CODE BEGIN 0 */
uint8_t g_RxData;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Re-Initialize Rx */
  HAL_UART_Receive_IT(&huart1, &g_RxData, 1);
  /* Set Signal */
  osSignalSet(myTask02Handle, 1);
}

/* USER CODE END 0 */

2-3. タスク実装

ユーザータスクを以下とします。

  /* USER CODE BEGIN StartTask02 */
  /* Initlize Rx */
  HAL_UART_Receive_IT(&huart1, &g_RxData, 1);
  /* Infinite loop */
  for(;;)
  {
    /* Wait Signal */
    osSignalWait(1, osWaitForever);
    /* Echo Back */
    HAL_UART_Transmit_IT(&huart1, &g_RxData, 1);
    osDelay(1);
  }
  /* USER CODE END StartTask02 */

2-4. 動かしてみる

Tera Termで動作確認しましたが、無事入力した文字がエコーバックされています(雑)!

3. かんたんな解説

実現仕様とコメント、実動作の通りです、、、というのはさすがに雑過ぎますね。笑

3-1. シグナルイベント(イベントフラグ)とは

シグナルイベント(イベントフラグ)は、名前通りイベント(=何かあったよ!)を通知する仕組みです。
本例でのイベントとは、**「受信したことをタスクに伝える」**です。

  /* Set Signal */
  osSignalSet(myTask02Handle, 1);

でイベントを設定しています。第一パラメータはタスクハンドル(タスクを指し示す番号)。

    /* Wait Signal */
    osSignalWait(1, osWaitForever);

でイベントを待ち合わせています。第二パラメータは「無限に待つよ」という意味です。
ともに存在するパラメータ「1」は、イベントを指し示すビットです。

参考までに、CMSIS仕様は以下です。

Signal Events
http://www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__SignalMgmt.html

3-2. U(S)ART受信割り込み

最初に以下呼び出しをしないと、受信割り込みが上がりません。
また、割り込みハンドラで再度呼び出さないと、以降の割り込みが上がりません。よって複数個所に記載しています。

  HAL_UART_Receive_IT(&huart1, &g_RxData, 1);

パラメータは「1byte受信したら割り込みを上げなさいよ」としています。

3-3. 問題点

タスク(イベント受信側)で受信データを吸い上げていますが、タイミング的に遅い可能性があります。

本来は、割り込みで速やかに受信データを退避してから、何らかの手段でタスクに通知すべきでしょう(と次回記事への伏線を書いてみました)。

おわりに

uITRONなどと比べると、断然シンプルでわかりやすく、使いやすいと思います!

次回もタスク間通信、メッセージあたりの記事を書く予定。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?