STM32CubeIDEを使ってみよう STM32H7でAzureRTOS編

STM32CubeIDEを使ってみようの続編として __STM32H7__ シリーズで __AzureRTOS__ を使ってみましょう。
##### 本内容は __MOOC - Azure RTOS workshop - 5 ThreadX lab - step1 - First thread creation__ を基に構成しています。
https://www.youtube.com/watch?v=DSbXqWrOnn0
## ドキュメントなど
https://drive.google.com/drive/u/1/folders/16_M2C8ZxRTmknrtYsOwdDvK7vM9NrRys
# Blinkプログラム
最初に __NonOS__ の __Blink__ プログラムを作ります。
こちらは、いつも通りとなります。
__ボード設定__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d9923928-9586-3d43-e564-1a93f0b02b9e.png)
__プロジェクト名__ 入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/2b719bf2-575b-437c-cd0d-e154f0c0b1db.png)
__Yes__ で進んでいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e85820e0-1c69-7f77-392e-dd8786f146f0.png)
__DeviceConfiguration Tool Code Generation__ に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5e49fece-3646-ddee-5b00-400d318929c9.png)
__プログラム__ の追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7e4e79d8-0997-7c26-709d-02917724bb75.png)
以上で、LEDが点滅すると思います。
# AzureRTOSの追加
次に、__AzureRTOS__ の追加のソフトウェアを追加します。
最初に、プロジェクトをコピーします。
今回は、ThreadX1にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3b48ec6e-c053-38d8-e340-b090d8cd6086.png)
そのままでは __DeviceConfiguration__ が開きません。
名前を __ThreadX1.ioc__ に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/497df626-5dda-0162-5b81-53ece2e4c956.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/909a95ed-f435-9428-c2e4-00eff1b05815.png)
__IOCファイル__ を開くことが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d8785ad9-f621-2762-6826-c0e1e30592bf.png)
次に、__Spftware Packs__ から __Select Components__ を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/23053bfc-f00b-e6bc-6177-f75afcc45fb2.png)
__X-CUBE-AZRTOS-H7__ を選択しましょう。
__Install__ していない場合は、インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b30d315d-1059-c285-a5b2-9610e4360ab4.png)
今回は __ThreadX__ の __Core__ のみ使用します。
__Core__ にチェックを入れてOKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ce214c89-d56a-b94f-ebe5-2c5d0ab66e9b.png)
__Software Packs__ が追加され、__X-CUBE-AZRTOS-H7__ が追加されています。
__Mode__ の __RTOS ThreadX__ のチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/146ff432-4b4f-da2c-85ad-e0139c088d36.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/41e2c8e7-d3e4-5fcc-1f42-baa4487a3e4b.png)
このまま、__DeviceConfiguration Tool Code Generation__ をしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e2720450-73f5-55eb-338f-17ec7ea44d08.png)
__警告__ が出ます。
これは、__Systick__ ではなく正規のタイマーが必要という事になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d350e8ac-7c67-4fec-cb83-cfe92ef54f55.png)
動画でもありますが、__TIM__ はどれでもいいようです。（注意：△！のものは避けてください）
今回は、動画通り __Pinout&Configuration__ から __SystemCore__ において __TIM6__ を選んでいます。
__DeviceConfiguration Tool Code Generation__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/0055dbb2-aa75-3df5-c615-38281a3c3e4e.png)
今回は問題なく、__Code Generation__ されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e2720450-73f5-55eb-338f-17ec7ea44d08.png)
# ビルド＆デバッグ
このまま、__ビルド＆デバッグ__ してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/a358df23-761b-08f2-8d7c-c06b8316956d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/50065a57-c63b-b326-773f-084c10de8336.png)
![スクリーンショット ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/c0d5b806-7406-76ae-f3e1-732ff9a13745.png)
NonOSで作ったBlinkのプログラムによりLEDがチカチカすることでしょう。
しませんね
これは、AzureRTOSに遷移しており、mainのプログラムに遷移しない為です。
# Threadの製作
それでは、Threadのプログラムを作り、Lチカをしましょう。
__app_thread.c__ にプログラムを追加します。
最初に __my_thread_entry__ という関数を作ります。

    void my_thread_entry(ULONG initial_input);

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/cb03e261-84b1-489d-5d2e-36d5493469ea.png)
__tx_thread_create__ にてスレッドを生成します。
今回は以下のようなコードになります。

    tx_thread_create(&thread_ptr,"my_thread",my_thread_entry,0x1234,thread_stack,THREAD_STACK_SIZE,15,15,1,TX_AUTO_START);
これはどういうコードなのでしょうか？
第 4 章 - Azure RTOS ThreadX サービスの説明
をご覧ください。

https://learn.microsoft.com/ja-jp/azure/rtos/threadx/chapter4

大雑把に言うと(若干誤りあり）
__UINT tx_thread_create(
    TX_THREAD *thread_ptr, スレッド制御ブロックのポインター
    CHAR *name_ptr, スレッドの名前を指すポインター
    VOID (*entry_function)(ULONG), 実行関数
    ULONG entry_input, エントリ関数に渡される32ビット値
    VOID *stack_start, メモリ領域の開始アドレス
    ULONG stack_size,  メモリ領域のバイト数
    UINT priority, スレッドの優先度(優先度15が一番低い）
    UINT preempt_threshold,  プリエンプションの最高優先度（優先度と同一だとプリエンプションの閾値が無効）
    ULONG time_slice, タイムスライス（1～0xFFFFFFFF、0は無効）
    UINT auto_start);  自動起動かの指定__ 
となるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e1ce3b9f-b0fe-6b4d-313d-a23ddc3bf8cd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f27a89fb-93a0-5a38-e7ac-eeca6c0c9d8d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/cab004c9-e788-ece6-b0ee-941dfaa247f3.png)
__my_thread_entry__ の関数を構成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/0835695a-2834-2e45-378e-3574418d84ec.png)
今回の __app_thread.c__ に __main.h__ がインクルードされていないので追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b2543ab5-9855-da5d-a528-ca0c348da068.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e11b54e8-cae7-0238-525c-27870fea8443.png)
これでLED3が使用できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/34537194-caff-ade4-1923-a192bcc4786e.png)
LED3の点滅プログラムを追加します。
```
void my_thread_entry(ULONG initial_input)
{
	while(1){
		HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
				tx_thread_sleep(20);
	}
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/095848c7-4812-4b11-c135-8fa178287638.png)
このままではいくつかの定義が出来ていないので追加します。
```
# define THREAD_STACK_SIZE 1024
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t thread_stack[THREAD_STACK_SIZE];
TX_THREAD thread_ptr;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/0bae59ae-f413-4b1c-c120-27e9a2ae966b.png)
定義をして、ビルド＆デバックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/635429a8-751d-63f8-de55-44e51c92dfb4.png)
これでLEDが点滅していると思います。
# ThreadList
__Window⇒Show View⇒ThreadX⇒ThreadX ThreadList__ を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3cbf1c57-d57c-d1e5-679c-e5297068e249.png)
__■__ で停止します。（□□の一時停止でも良いようです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d9bacbfd-5c3c-ed1e-bbc1-d75342afa663.png)
__TreadList__ が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/04dad9d9-af7d-3f08-caec-800221bde7d0.png)
再度スタートさせると __TreadList__ が変化します。。
![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d04ef36e-adf8-fa0f-1618-04c287e683f7.png)
これで、ThreadXをとりあえず動かす事が出来ました。