Newer
Older
m5stickcplus / _build / html / _sources / week2.rst.txt
@Motoki Miura Motoki Miura on 23 Mar 2021 4 KB mutex
2週目
========================

1週目で学んだことを活かして、組み合わせてみましょう。


複数人で書いたプログラムを統合する
------------------------------------------------------------------------------

- Arduino IDEでは、プログラムを複数のファイル(たとえば、main.ino / sub.ino / hoge.cpp / hoge.h ) に分割して記述することができます。複数ファイルに分割することで、関数定義を機能別にまとめることができ、管理しやすくなります。
- Arduino IDEでは、プログラムを構成する、複数のファイル(スケッチブック)を、1つのフォルダに入れて管理します。(スケッチブックのことを、他のIDEでは「プロジェクト」と呼ぶ場合もある)
- スケッチブックに別のファイル(hogehoge.ino) を追加するには、右上にあるシリアルモニタをひらくアイコンの、下の「▼」ボタンからメニューをひらき、「新規タブ」を選択し、ファイル名(拡張子.ino をのぞいた、hogehogeの部分のみ)を入力します。
- スケッチブックをコピーしたいときは、内包するフォルダごとコピーしてください。**その際、フォルダ名と、メインのソースコードファイル名(拡張子以外の部分)は、一致している必要があります。**
- 複数のファイルを置いたときの挙動について: ``***.ino`` ファイルの内容は、単純にメインのタブ(フォルダ名と同じinoファイル)にマージされます。``***.cpp`` や ``***.c`` という拡張子でファイルを作成した場合は、``***.h`` を作成する必要があります。`参考:Properly using separate tabs with Arduino IDE <https://arduino.stackexchange.com/questions/50210/properly-using-separate-tabs-with-arduino-ide>`_ 
- Git を利用すると、複数人で作業したファイルを統合しやすいです。

タスク
--------------------------------------------------

複数の機能を1つの ``loop()`` にまとめようとすると、プログラムが複雑になります。タスクを用いると、 ``loop()`` に相当する関数を複数定義し、並列に動作させることができます。

:numref:`task01` に、タスクを利用する例を示します。3つの異なるタスクを作成し、それぞれの関数内部で ``setup()`` と ``loop()`` に相当する処理を記述しています。
引数の詳細については、`非公式日本語リファレンス <https://lang-ship.com/reference/unofficial/M5StickC/Functions/freertos/task>`_ を参照してください。
ここの例では、1つのファイルに記述していますが、タスクごとに別のファイルにすることもできます。 例では使用していませんが、 ``TaskHandle_t`` は、タスクの一時停止(サスペンド)や、再開(レジューム)、削除のときに利用します。

.. literalinclude:: src/task01.ino
  :caption: 
  :name: task01
  :language: arduino
  :linenos:
..  :emphasize-lines: 6-7, 15,19

.. note:: 参考:  `FreeRTOSでマルチタスク (on ESP32) <https://qiita.com/hideakitai/items/bd95d0db63097b8808f9>`_

タスク生成時に、引数を渡すこともできます。:numref:`task02` に、引数を渡す例を示します。(次で述べるミューテックスを使って、排他制御もしています。)

.. literalinclude:: src/task02.ino
  :caption: 
  :name: task02
  :language: arduino
  :linenos:
  :emphasize-lines: 1,6,8,20,21,33,41

.. warning:: 引数をアドレスで渡すとき、関数内で宣言したローカル変数は使えません。グローバルな変数を使用する必要があります。

ミューテックスとセマフォ
----------------------------------------------------------

複数のタスクを並列動作させると、リソースに同時アクセスすることで意図しない動作を引き起こすことがあります。
ミューテックスを用いると、リソースに同時にアクセスできるタスクを限定することができます。これを「排他制御」と呼びます。

バイナリセマフォは、タスク間またはタスクと割り込み間の同期に適しています。
バイナリセマフォとミューテックスは似ていますが、いくつか本質的な違いがあります。ミューテックスは優先度を継承する機構が備わっていますが、バイナリセマフォには備わっていません。



.. note:: 参考: `RTOS binary semaphore API <https://www.freertos.org/xSemaphoreCreateBinary.html>`_ 

ただし、バイナリセマフォを用いるより、`RTOS Task Notifications <https://www.freertos.org/RTOS_Task_Notification_As_Binary_Semaphore.html>`_
を用いたほうが、高速かつメモリ使用量を削減できるようです。

- MCU RTOS習得(2020年版) http://happytech.jp/bRTOS.html