FreeRTOSのeventGroup



下記の記事から続くFreeRTOSの機能に関する記事です。

https://qiita.com/tom_S/items/ea653880132e1fcfed72

FreeRTOSのeventGroupについて説明します。

## eventGroupとは

名前はeventGroupですが、仕様はItronやToppers等のイベントフラグと似たような形です。イベントフラグの使用可能なビット数はFreeRTOSConfig.hで定義するconfigUSE_16_BIT_TICKSの値によって決まります。
configUSE_16_BIT_TICKSが0なら8、configUSE_16_BIT_TICKSが1なら24まで使用することができます。

## タスクの切り替え時の振る舞い

スケジューラの具体的な動きとしては、タスク情報の構造体に待っているビットの値を格納してブロック状態となり、タスクの切り替えを行います。仕様書ではフラグ待ち時はブロックステートとなっていますが、タスクをサスペンドさせた時と同じようにpxDelayedTaskListに追加されるようです。

イベントフラグのセット時は、タスク情報の構造体に保持していたビットの値を参照し、待っていたビットならばステートをreadyステートに変更し、タスクの切り替えを行います。


## API

### xEventGroupCreate
```c
EventGroupHandle_t xEventGroupCreate( void )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグを作成する |
| 引数 | | なし |
|返り値| | 作成に成功したイベントフラグのID。失敗時はNULLが入る |

### xEventGroupWaitBits
```c
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
                                 const EventBits_t uxBitsToWaitFor,
                                 const BaseType_t xClearOnExit,
                                 const BaseType_t xWaitForAllBits,
                                 const TickType_t xTicksToWait )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグを待つ |
| 引数 | xEventGroup | イベントフラグID |
|| uxBitsToWaitFor | 待ちbitパターン |
|| xClearOnExit | イベントフラグが立った際に、<br>フラグをクリアするかどうか |
|| xWaitForAllBits | pdTRUEならば、待っている<br>すべてのbitが立つまで待つ。<br>pdFALSEなら、待っている<br>bitのうちどれかが立つのを待つ |
|| xTicksToWait | タイムアウト時間。タイムアウトを無しに設定する場合は、FreeRTOSConfig.hにて「INCLUDE_vTaskSuspend」を1に定義し、xTicksToWaitはportMAX_DELAYを指定する。 |
|返り値| | 待ち解除時のbitパターン |

### xEventGroupSetBits
```c
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
                                const EventBits_t uxBitsToSet )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグを立てる |
| 引数 | xEventGroup| イベントフラグID |
|| uxBitsToSet | セットするbitパターン |
|返り値| | uxBitsToSet をセットした後のbitパターン |

### xEventGroupSetBitsISR
```c
EventBits_t xEventGroupSetBitsISR( EventGroupHandle_t xEventGroup,
                                   const EventBits_t uxBitsToSet,
                                   BaseType_t *pxHigherPriorityTaskWoken  )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグを立てる |
| 引数 | xEventGroup| イベントフラグID |
|| uxBitsToSet | セットするbitパターン |
|| pxHigherPriorityTaskWoken  | イベントフラグを立てた際にready<br>ステートになるタスクが、その時<br>点でrunningステートのタスクよりも優先度が高い場合にpdTRUEが入る |
|返り値| | uxBitsToSet をセットした後のbit<br>パターン |

### xEventGroupClearBits
```c
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
                                  const EventBits_t uxBitsToClear )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグをクリアする |
| 引数 | xEventGroup| イベントフラグID |
|| uxBitsToClear | クリアするbitパターン。<br>0になっているbitをクリアする |
|返り値| | uxBitsToClear <br>でクリアする前のbitパターン |

### vEventGroupDelete
```c
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
```

| 項目1 |  項目2 | 説明 |
| ------------- |  ------------- | ----------------------------------------------------------------- |
|機能|| イベントフラグを削除する |
| 引数 | xEventGroup | 削除するイベントフラグのID |
|返り値| | なし |


## サンプルソースコード

eventGroupのサンプルソースコードを下記に示します。
下記のサンプルでは、eventGroupを待つタスクとeventGroupをセットするタスクを生成して動作させています。

```c

#define EVENT_PATTERN (0x0001)

TaskHandle_t eventGroupSetTaskHandle;
TaskHandle_t eventGroupWaitTaskHandle;
EventGroupHandle_t eventGroup;


static void eventGroupSetTask(void * argument)
{
	uxArraySize = uxTaskGetNumberOfTasks();

	for( ;; )
	{
		vTaskDelay(100);
		/* イベント(0x001)をセット */
        xEventGroupSetBits(eventGroup, EVENT_PATTERN);
	}
 
    vTaskDelete(NULL); /* 何らかのエラーで処理が終了した場合にはタスクを削除 */
}

static void eventGroupWaitTask(void * argument)
{
	EventBits_t uxBitsToWaitFor = EVENT_PATTERN;

	for( ;; )
	{
        /* イベント待ち */
		xEventGroupWaitBits(eventGroup, uxBitsToWaitFor, pdTRUE, pdFALSE, 1000000);

        /* ここにセットされたビットと対応する処理を行う */
        if (uxBitsToWaitFor & EVENT_PATTERN)
        {
        
        }
	}
 
    vTaskDelete(NULL); /* 何らかのエラーで処理が終了した場合にはタスクを削除 */
}

/* タスクとeventGroupを生成するタスク */
static void StartTask(void const * argument)
{
    eventGroup = xEventGroupCreate();

    if (pdTRUE != xTaskCreate(eventGroupSetTask, "eventGroupSetTask", 1024, NULL, 2, &eventGroupSetTaskHandle))
    {
        return;
    }

    if (pdTRUE != xTaskCreate(eventGroupWaitTask, "eventGroupWaitTask", 1024, NULL, 4, &eventGroupWaitTaskHandle))
    {
        return;
    }

    vTaskDelete(NULL); /* 処理が終わったのでタスクを削除 */
}


```