Windows上でFreeRTOSを動かす

# 概要
FreeRTOSはRTOSなのでマイコン上で動かすものだが
FreeRTOSの学習、またはテスト環境構築のためにはWindows上で動かせる便利なのでその紹介。

# 目次
MSVC上でFreeROTSのデモプロジェクトは軽く調べた感じ以下の３つでした。
[1. FreeRTOS本家](#1-freertos本家)
[2. チュートリアルで使うExample用のプロジェクト](#2-チュートリアルで使うexample用のプロジェクト)
[3. Amazon FreeRTOS](#3.-amazon-freertos)

サンプル動かしていて気づいた点のメモ
[Windows上で動かしていたときのメモ](#windows上で動かしていたときのメモ)
##

# 環境
2020/08/11時点のKernel Version.


##1. FreeRTOS本家
https://www.freertos.org/a00104.html
をダウンロードして
FreeRTOSv10.3.1\FreeRTOS\Demo\WIN32-MSVC\WIN32.sln
を起動。

##2. チュートリアルで使うExample用のプロジェクト
https://www.freertos.org/Documentation/code/
で"Source code using the FreeRTOS Windows port"をダウンロードして
RTOSDemo.slnを起動。

##3. Amazon FreeRTOS
現状こちらが本家なのかな、、
公式から環境
https://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
が提供されているので動かし方の紹介をします。
いろいろ加筆したいなあ。
### FreeRTOSのダウンロード
これがないと始まらないのでまずはFreeRTOSをダウンロードします。
https://github.com/aws/amazon-freertos


FreeRTOS Kernelや、Visual C++のサンプルプロジェクトも含まれています。
> Note: If you download the ZIP file provided by GitHub UI, you will not get the contents of the submodules. (The ZIP file is also not a valid git repository)

とあるように、submoduleが含まれているので、zipでダウンロードではなく、git cloneしましょう。
以下の説明では**freertos**にリネームした前提で進めます。
### Visual C++インストール
https://docs.aws.amazon.com/ja_jp/freertos/latest/userguide/getting_started_windows.html
に従ってインストールする。

>開発環境をセットアップする
WinPCap の最新バージョンをインストールします。
Microsoft Visual Studio をインストールします。
Visual Studio バージョン 2017 および 2019 は動作することが確認されています。Visual Studio のすべてのエディションがサポートされます (Community、Professional、または Enterprise)。
IDE に加えて、[Desktop development with C++ (C++ によるデスクトップ開発)] コンポーネントをインストールします。
最新の Windows 10 SDK をインストールします。これは、[Desktop development with C++ (C++ によるデスクトップ開発)] コンポーネントの [Optional (オプション)] セクションで選択できます。

## サンプルプロジェクトを動かす
手順そのままで大丈夫です。Visual C++を起動してfreertos/ 以下からプロジェクトを起動します。
https://docs.aws.amazon.com/ja_jp/freertos/latest/userguide/getting_started_windows.html
> Visual Studio の [ファイル] メニューから、[開ける] を選択します。[File/Solution (ファイル/ソリューション)] を選択し、projects/pc/windows/visual_studio/aws_demos/aws_demos.sln に移動してから [開ける] を選択します。

ビルド、実行すると↓のように出力されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/ff22268e-e957-6bb4-c8eb-b6c14c0ec1f6.png" width=50%>

# Windows上で動かしていたときのメモ
## 割り込みのエミュレート
マイコンでは必須の割り込みのエミュレート方法です。
https://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
> Defining and Using Simulated Interrupt Service Routines

に説明があります。
main.cにベタ書きして動かすコード（実際のボードのように外部からボタンを押して割り込みは入れられないので、myTask1から割り込みを発生させています。）

```c:main.c
TaskHandle_t myTask1Handle = NULL;
TaskHandle_t myIntTaskHandle = NULL;
void myTask1(void* p) {
    while (1) {
        // 割り込み要因３で割り込みを入れる
        vPortGenerateSimulatedInterrupt(3);
        vTaskDelay(1000);
    }
}
// 割り込みハンドラから起こされるタスク。通常割り込みで重たい処理はやらないので、お作法として。。
void myIntTask(void* p) {
    while (1) {
        vTaskSuspend(NULL); // suspend itself.
        printf("myIntTask\n");
    }
}
// 割り込みハンドラの定義。処理をmyIntTaskに移譲する。Windows上のシミュレーションなので、ここでprintfしても良いが。。
unsigned long ulInterruptName(void) {
    BaseType_t checkIfYieldRequired;
    checkIfYieldRequired = xTaskResumeFromISR(myIntTaskHandle);
    portYIELD_FROM_ISR(checkIfYieldRequired);
    return pdTRUE;
}
int main( void )
{
    const uint32_t ulLongTime_ms = pdMS_TO_TICKS(1000UL);
    prvMiscInitialisation();

    xTaskCreate(myTask1, "task1", 200, (void*)0, tskIDLE_PRIORITY, &myTask1Handle);
    xTaskCreate(myIntTask, "intTask", 200, (void*)0, tskIDLE_PRIORITY, &myIntTaskHandle);

    // 割り込みハンドラ登録
    vPortSetInterruptHandler(3, ulInterruptName);

    vTaskStartScheduler();
}
```
実行すると、、↓のように割り込みハンドラから起こされたmyIntTaskが1秒ごとにprintfします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/72c965ed-ac70-875e-626c-3aa886d2f8c1.png" width=50%>

## Windows実行時の注意
### msgQueue
デフォだとQueueHandle_tが定義されていないとコンパイルエラーがでます。
これは過去バージョンの互換のためのdefine値が有効になっているからです。↓を0にしましょう。

```c:FreeRTOSConfig.h
#define configENABLE_BACKWARD_COMPATIBILITY        1
```

公式の説明は https://www.freertos.org/a00110.html です。
>configENABLE_BACKWARD_COMPATIBILITY
The FreeRTOS.h header file includes a set of #define macros that map the names of data types used in versions of FreeRTOS prior to version 8.0.0 to the names used in FreeRTOS version 8.0.0. The macros allow application code to update the version of FreeRTOS they are built against from a pre 8.0.0 version to a post 8.0.0 version without modification. Setting configENABLE_BACKWARD_COMPATIBILITY to 0 in FreeRTOSConfig.h excludes the macros from the build, and in so doing allowing validation that no pre version 8.0.0 names are being used.