m5stackはPlatformIOでESP-IDFは使えなかった

#`ESP-IDF`を試してみようとしたきっかけ

`m5stack`で`Arudino`を使ってパルスカウンターを作ってみました。

>パルスカウンターを作ってみる
https://qiita.com/zasshyu6/items/d4a1d719e59c713b2eeb


ですが、タイマ割込が`1usec`以下だと`vTaskDelay`をかけてもリセットがかかってしまう。
また、今回のパルスカウンターでは、`5usec`以上でないと動いてくれないので、`100kHz`周期が限界。
通常制御だと確かに十分な速度ですが、パルスカウンターとして使う場合はさすがに遅くないかな・・・
もともと`Arduino`の`loop()`の待ち時間が遅いというのでとりあえず`Arduino`以外であたりをつけてみる。

というわけで、今度は`ESP-IDF`を使ってみようと思いました。
`ESP-IDF`初めてなので、とりあえずUARTでループバックを作ろうとしました。

結論として言えば、**作れませんでした。**
`cpu_start.c:(.text.main_task+0x5f): undefined reference to 'app_main'`
というコンパイラエラーが出てしまい、elfファイルが作れませんでした。
(`PlatformIO`で`m5stack`のライブラリ限定かもしれませんが・・・)

`m5stack`について調べたことは以下の記事に乗せています。
>m5stackで遊ぼう
https://qiita.com/zasshyu6/items/35a1048a9781bdcfebb7

以下は、`ESP-IDF`を使う為に調べたことです。

##開発環境
- `windows 10 Home 64bit `
- `Visual Studio Code 1.38.1`
- `PlatformIO`
    - 使用ライブラリは`ESP-IDF`
    - 使用言語は`C++`


`Arduino`って言語というよりライブラリでしたね・・・
今まで全部言語でくくっちゃってました・・・
また、気づいたら`Visual Studio Code`がアップデートされてました。

##`ESP-IDF`について

`ESP32`および`ESP8266`用の開発ライブラリで、`driver`がついているため各種周辺機能にアクセスできます。
`Arduino`よりもマイコンっぽく使える！ライブラリですね。
`PlatformIO`をインストールするときに一緒にライブラリがインストールされます。
`PLatFormIO`の入れ方は以下の記事を参考にしました。わかりやすかったです。
>M5Stackの開発環境を整える - PlatformIO IDE編
https://qiita.com/lutecia16v/items/1c560bdd7eac7ebeaff7

プロジェクト作成で`Arduino`を選択していた部分を`ESP-IDF`に変更するとプロジェクトが作成されます。
開発環境組み立ては非常に楽ですね。

プロジェクトを作成すると、`sdkconfig.h`という設定ファイルだけが作成されました。
`main.cpp`が作成されないのでどうやって動かすんだろ？と思って探したら、サンプルがパッケージの中にありました。
とりあえずサンプルのmainをコピペしてきて色々調べてみます。

##`ESP-IDF`のスタートアップについて

サンプルの`main.c`の中身は、`FreeRTOS`と`driver`をインクルードして、
Lチカのタスクを生成、`app_main()`で起動させているといった流れでした。
`driver`はそのまま周辺機能やI/Oポートにアクセスするためのヘッダみたいです。

`driver`がインストールされてるから`FreeRTOS`はいらないんじゃないか？と思っていたのですが、
スタートアップについて`ESP-IDF`の公式が説明してくれていました。

>(公式)General Notes About ESP-IDF Programming
https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/general-notes.html

流れは`ROM`からプログラムを読みだして`RAM`へ展開してソフトを起動させるといった普通のブート動作です。
面白いのが、ソフト起動してから`FreeRTOS`でスケジューリング開始させてから動作開始といった`FreeRTOS`ありきの起動方法です。
`ESP-IDF`は公式で`FreeRTOS`を使うマイコンってことでよさそうです。

確か、`Arduino`でもマルチコア対応のために`FreeRTOS`を使っていたので、
`ESP-IDF`でもタイマ割込の周期を`1 μsec`以下は難しそうですね。
それでも練習がてら、試しては見たいところです。

##`PlatfromIO`+`ESP-IDF`のLCD表示ライブラリが見当たらない!?
次に、せっかく`m5stack`なのですから、LCD表示をしてみようと思いました。
今まで、`m5stack.h`内の`TFT_eSPI`を使っていたのですが、`m5stack.h`をincludeすることができません。
`Arduino.h`を参照して`m5stack.h`内の`TFT_eSPI`は作られているので、今回のフレームワークである`ESP_IDF`をは参照に失敗します。
`PlatformIO`で配布してくれているライブラリを調べてみましたが、すべてフレームワークが`Arduino`でした・・・
(だれか`PlatformIO`で`ESP-IDF`に対応したLCDライブラリを見つけた人がいたら教えてください)

`PlatformIO`の公式外ですが、外部ライブラリで`m5stack`に対応しているライブラリはありました。
>ESP32 TFT display library
https://www.esp32.com/viewtopic.php?t=1937

これを使ったLCDテストが`youtube`には上がってたので試そうと思ってダウンロードしましたが・・・
中にあったサンプルファイルをコンパイルしても通らず・・・
コンパイルエラーを消そうと頑張ってみましたが、`PlatformIO`のコンポーネントとぶつかっている様子でしたので断念しました。

結局、`PlatfromIO`+`ESP-IDF`でLCD表示を行うためには、ライブラリを自作するしかないようです。

##そしてコンパイルエラーが始まる
UARTループバックはサンプルがあったのでそれをとりあえずコピペしてコンパイルをしてみました。
はじめは、`xTaskCreate`の引数の`TaskHandle_t`がNULLだとコンパイルが通らないので適当に名前を付けて、
コールバック関数の引数をポインタ持たせてあげてコンパイルを通しました。
そしてLink時に以下のエラーメッセージが出ました。
`cpu_start.c:(.text.main_task+0x5f): undefined reference to 'app_main'`
cpu_start.cは`PlatformIO`で用意されるところなのでこれを言われちゃうと何もできず・・・
断念しました。

##結論
 - LCD用のライブラリがない
 - サンプルがコンパイルできない

上記2点をもって、自分のような知識不足の初学者は使うべきではないと思いました。

####補足
`PlatformIO`自体は自動で必要なファイルを用意してくれるので非常に便利です。
また、`VScode`のオートコンプリートと定義検索と`PlatformIO`の`Arduino`環境はすごく楽で使いやすいです。

今回できなかったという点ですが、自分の環境(`m5stack`)に限るかもしれないです。
また、`PlatformIO`のアップデート次第では使えるようになると思います。
是非ともどなたか試してみて、うまくいったら教えてください。