Skip to content

PIC32 サポート

Shuta Kimura edited this page Oct 6, 2018 · 16 revisions

TinyThreadsはMIPS32(r2以上)を採用したPIC32シリーズCPUに対応しています。 MPLAB X IDEのMPLAB Harmony Configuratorに統合させ、サードパーティーのライブラリとして選択できるようになります。

インストール方法

  1. Harmonyのインストール先にある、third_partyフォルダを開いて下さい。
    • 例えばWindowsなら、C:\microchip\harmony\v2_06\third_partyなどです。
  2. リリース一覧から必要なバージョンのzipやtarballを取得し、上記のフォルダに展開して下さい。
    • zipやtarballの代わりに、third_partyフォルダ下でgitリポジトリを直接クローンしても構いません。
      • その場合は使用するバージョンのタグをチェックアウトしてください。masterブランチは開発途中の状態が含まれる場合があるため推奨しません。
    • tinythreadsフォルダの中身だけではなく、フォルダ階層ごと展開してください。
    • フォルダの名前は必ずtinythreadsにしてください。
  3. 次のフォルダ構成になっているか確認してください。階層構成やフォルダ名が異なると、正しく動作しません。
    harmony/
      +-- vX_XX/
            +-- third_party/
                  +-- tinythreads/
                        +-- README.md
                        +-- config/
                        +-- templates/
                        +-- TINYTH/
                        +--   : (省略)
    
  4. third_party/config/third_party.hconfig をテキストエディタで開き、次の一行をmenuendmenuの間に挿入し、保存してください。
    source  "$HARMONY_VERSION_PATH/third_party/tinythreads/config/tinythreads.hconfig"
    
  5. MPLAB IDE X で32-bit MPLAB Harmony Projectから生成されたプロジェクトを開き、Harmony Configuratorを起動してください。
    • まだプロジェクトが無い場合は、「使い方」の最初の手順で先にプロジェクトを作成してください。
  6. 以下のように、「Third Party Libraries」内に「Use TinyThreads?」の項目が表示されていればインストール完了です。

使い方

  1. MPLAB IDE X で「File」→「New Projects...」から「32-bit MPLAB Harmony Project」を選択し、「Next」で進んでください。
  2. プロジェクトの生成場所やデバイスの種類は任意です。適切に設定をして「Finish」でプロジェクトを作成してください。
  3. プロジェクト作成直後にHarmony Configuratorが起動しますので、「Third Party Libraries」→「Use TinyThreads?」にチェックを入れてください。すぐ下にTinyThreadsの詳細設定を行う項目「TinyThreads Configuration」が追加されます。
  4. 「TinyThreads Configuration」内の設定を設定してください。
  5. 「Device & Project Configuration」→「Project Configuration」→「XC32 (Global Option)」→「xc32-ld」→「General」を開き、「Heap Size (bytes)」にヒープの容量を設定してください。TinyThreadsはmalloc/freeを使用するため、十分なヒープ容量が必要です。
    • ヒープを最大限に確保する場合、ヒープ容量 = デバイスのRAMサイズ - (Data Memoryの使用量 + メインスレッドのスタック確保サイズ) で決定してください。Data Memoryの使用量はプロジェクトのコンパイルを行うとDashboardウィンドウに表示されます。
    • 初回の設定値に見当がつかない場合、一旦ヒープ容量を初期値のまま後ろのステップを進めてください。コンパイルしてData Memoryの使用量を確認してから、再度Harmony Configuratorで設定し直して下さい。
  6. Generate Codeボタンを用いてコードを生成してください。
  7. プロジェクトのプロパティを開き、「XC32 (Global Options)」の「Additional Options」に-newlib-libcと設定してください。(もし「Use Legacy libc」にチェックがされている場合は、チェックを外してください。)
    • プロジェクトのプロパティは、左側プロジェクト内容一覧のプロジェクト名を右クリックし「Properties」を選択すると開きます。

設定項目

以下に設定項目一覧を示します。なお、プロジェクトで選択しているデバイスが対応していない機能や、オプションの組み合わせにより不要となった設定項目は表示されません。

グループ 名前 説明
Features Enable pthread_cond*() APIs 条件付き変数関連API(pthread_cond_*)を有効にします。
Features Enable pthread_mutex*() APIs ミューテックス関連API(pthread_mutex_*)を有効にします。
Features Enable sem_*() APIs セマフォ関連API(sem_*)を有効にします。
Features Enable pthread_once*() APIs Onceコントロール関連API(pthread_once_*)を有効にします。
Features Enable pthread_rwlock*() APIs 無視されます。現段階ではreader-writerロックは未実装です。
Features Enable pthread_spin*() 無視されます。現段階ではスピンロックは未実装です。
Features Enable sleep() and usleep() APIs スリープ関連API(sleep, usleep)を有効にします。
Features Enable internal profiling (Switch counter) タスク切り替え回数カウントを有効にします。(デバッグ向け)
Features Enable thread name for debugging スレッド名設定機能を有効にします。(デバッグ向け)
Scheduling Enable preemption based on system tick プリエンプションを有効にします。
Scheduling Interval of preemption (in milliseconds) プリエンプションの間隔をミリ秒単位で設定します。
Timer Timer Type プリエンプションやスリープ関数制御に用いるタイマーの種類を指定します。
Timer Timer Module ID 使用するタイマーの番号を指定します。
Timer Timer Priority タイマー割り込みの優先度を指定します。
Timer Timer Sub-priority タイマー割り込みの副優先度を指定します。
Timer CPU Clock Speed (Hz) CPUの動作クロックが表示されます。ユーザーによる設定項目ではありません。
Timer Peripheral Clock Speed (Hz) タイマーの動作クロックが表示されます。ユーザーによる設定項目ではありません。
Timer Timer Resolution (in microseconds) タイマーの分解能をマイクロ秒単位で設定します。プリエンプションやスリープ関数の待ち時間はこの値の倍数に切り上げられます。
Advanced Maximum priority value 優先度の最大値(最も優先度が低い)を指定します。有効な範囲は1~255です。
Advanced Minimum priority value 優先度の最小値(最も優先度が高い)を指定します。有効な範囲は1~255です。
Advanced Default priority value 優先度を明示的に変更しない場合の、デフォルトの優先度を指定します。有効な範囲は上記のmin~maxです。
Advanced Default scheduling policy デフォルトのスケジューリング方式を選択します。
Advanced Minimum stack size for threads デフォルトのスタックの大きさをバイト数で指定します。
Advanced Require thread safe C library スレッドセーフなnewlibへのアクセスを有効にします。この設定を無効にするとRAM使用量を削減できますが、一部のAPIがスレッドセーフではなくなります。スレッドの処理内容が限定的であるなど、安全が担保されている場合のみ無効にしてください。詳しくは制約を参照ください。
Advanced Enable assertion check TinyThreads内部でのアサーションチェックを追加します。
Advanced Issue WAIT instruction in idle thread 有効にすると、アイドルスレッドでWAIT命令を発行します。
Advanced Use shadow register set to store context Shadow register setを利用した高速なスレッド切り替えを有効にします。
Advanced Enabled delayed switch for FPU registers FPU関連レジスタの遅延切り替えを有効にします。
Advanced Disallow FPU usage in ISR ISR内でのFPU関連命令の使用を禁止します。
Advanced Enabled delayed switch for DSP registers DSP関連レジスタの遅延切り替えを有効にします。
Advanced Disallow DSP usage in ISR ISR内でのDSP関連命令の使用を禁止します。

FPU/DSPの遅延切り替えについて

TinyThreadsはFPU/DSPコンテキストの遅延切り替えに対応しています。遅延切り替えとは、スレッドの切り替えやISR実行時にはFPU/DSPレジスタの待避・復帰を行わず、実際にFPU命令やDSP命令を用いてレジスタにアクセスを行った際に初めて切り替えを行う仕組みです。

FPU/DSP関連レジスタはサイズが大きいため、切り替え(待避・復帰操作)に時間がかかります。そのため、必要になった場合のみ切り替えを行うことで、スレッド切り替えやISRの出入りにかかる時間を削減します。アプリケーション内でFPU/DSPを用いるスレッドが少数の場合に特に効果を発揮します。

本機能はFPU/DSP使用時にわざと例外を発生させ、それをTinyThreads側で捕捉することで実現しています。ユーザー側プログラムでは特別な操作は必要ありません。

制約

  • ISRでのAPI利用に関して
    • TinyThreadsが提供するAPIのうち、ISR(割り込みハンドラ)内で使用が許可されているのはsem_post()のみです。
    • 他の関数をISR内で使用した場合、動作は未定義です。
  • libcの種類としてはnewlibのみに対応します。デフォルトのlibcやLegacy libcには対応していません。
    • コンパイルオプションから-legacy-libcは外し、-newlib-libcを追加してください。
  • XC32プロジェクトではデフォルトでヒープがごく少量(2KB)しか設定されませんが、TinyThreadsはmalloc/freeですべてのメモリを確保するため、もっと多くのヒープ領域が必要です。
    • Harmony ConfiguratorのXC32 (Global Options)からヒープサイズを設定してください。
    • プロジェクトのプロパティのxc32-ldから設定すると、Harmony Configuratorでコード生成する度に上書きされてしまうためご注意ください。
  • v1.3時点では、ISA(Instruction Set Architecture) ModeはMIPS32のみ対応です。microMIPSには対応していません。
  • Shadow register set利用時特有の制約
    • 同時に存在できるスレッドはShadow register setの個数が最大となります。これにはmain()関数が実行されるデフォルトスレッドと、動作すべきスレッドが無い場合に時間を消費するアイドルスレッドも含まれます。
      • 例えば、Shadow register setが7個の場合、pthread_create()で同時に生成できるスレッドはそこから2を引いた5個が最大です。
      • この制約のため、GPRセットを2個(つまりShadow registerは1個)しか持っていないPIC32MMシリーズなどでは、この機能を利用できません。
      • 同時生成スレッド数の上限を越えてスレッドを生成しようとすると、pthread_create()EAGAINを返して失敗します。