APDahlen Applications Engineer
FreeRTOSと割り込みの関係は何でしょうか?
Arduino PORTENTA Pro C33に実装されたFreeRTOSは、ティック(タイムベース)の間隔が1msの割り込み駆動プロセスです。FreeRTOSはC33上で動作する数多くの割り込みサービスルーチン(ISR)の1つにすぎません。これらのISRがリアルタイムシステムでマイクロコントローラのリソースをめぐって競合するとき、私たちは課題に直面します。この問題をプロジェクトの形で組み立ててみましょう。
この技術記事は、以前に紹介したFreeRTOS の紹介の続きです。Arduino PORTENTA Pro C33は、LEDの点滅、Arduinoシリアルモニタへのデータ送信、有線Ethernetによる通信など、さまざまなタスクを含むようにFreeRTOS でプログラムされていたことを思い出してください。このさまざまなタスクがミックスされた状況に対して、この記事で説明されているように直交エンコーダを追加します。また、直交エンコーダは1秒間に11.2kカウントとそこそこ高速なので、カウント漏れを防ぐために注意深くISRを統合する必要があることを思い出してください。直交エンコーダのコードには、位置00から11へのミスカウントのような一般的な間違いを識別するためのステートマシンが含まれていました。
技術的なヒント: 直交エンコーダシステムは、カウンタの遷移を1つでも逃すと、使い物にならなくなることを常に覚えておいてください。マイクロコントローラが忙しすぎてエンコーダを追跡できないと、物理的なメカニズムは混乱し、ますます自己の位置を見失うことになります。
図1は、問題を非常に単純化して表しています。ここでは、直交エンコーダのA出力とB出力が表示されています。3行目は、ISRが直交エンコーダのイベントを処理したことを示すパルスです。丸で囲まれた遷移は、優先度の高いFreeRTOS ISRによって遅延されていることに注意してください。また、DC12VモータはDC1.5Vを印加した状態で非常にゆっくりと動いていることにも注意してください。モータの速度を上げると、FreeRTOSに関連する遅延期間は直交エンコーダの期間よりも長くなります。その結果、トランジションが失敗し、機械的なシステムが失われます。
誤解しないでください。私は決してArduinoやデフォルトのFreeRTOSや割り込み設定に問題があると言っているのではありません。それどころか、その設定は大多数のプロジェクトには完全に適したものになっています。しかし、このプロジェクトではエンコーダの高速リアルタイム動作が求められるため、デフォルト設定では対応できない特殊なケースなのです。
図 1: ロジックアナライザには、直交エンコーダのAおよびB出力が、関連するISRに費やされた時間を示すティックとともに表示されます。FreeRTOSが優先されるときのジャンプを観察してください。
技術的なヒント: もしまだそうしていないのであれば、先に述べた直交エンコーダの記事を参照することをお勧めします。理想的な直交エンコーダのコードが数行で書けることを考えると、有限ステートマシン(FSM)ベースのコードは一見過度なくらい複雑に見えるかもしれません。しかし、コード開発および競合する複数のISRを調整する複雑さを考慮すると、タイムクリティカルなセクションにフェイルセーフメカニズムが組み込まれていることは安心です。FSMはすべてのエラーを検出することはできませんが、失敗した遷移は簡単に検出することができます。これは、毎秒11,000回を超える割り込みが機能しているシステムにとって特に重要なことです。
FreeRTOSは直交エンコーダのような他の高速割り込みとどのように競合しますか?
FreeRTOSは、マイクロコントローラ専用に構築された軽量のオペレーティングシステム(OS)です。複数のタスクの動作を調整、制御して、それらがシームレスに動作しているように見えるように設計されています。マイクロコントローラは限られたリソースであり、いつの時点においても一度に1つのタスクしか実行できないことを思い出してください。ここでは、マルチコアプロセッサやダイレクトメモリアクセス(DMA)などの拡張周辺機器は無視します。
技術的なヒント: タスクはFreeRTOSの基本的な構成要素です。その目的は、大きなマイクロコントローラのプログラムをいくつかの意味のあるタスクに分割し、FreeRTOSのメカニズムを使ってそれらのタスクを調整することです。これらのタスクは、機能やハードウェアによって分けられることもあれば、優先度によって分けられることもあります。例えば、単純なロボットにはモータを制御するタスクが含まれるかもしれません。その場合、ロボットの動作を制御するタスクは遅くなりますが、より高い優先度になる可能性があります。ある意味、これは人間の自律神経系と反射神経系の違いを反映しています。
ソフトウェアやハードウェアによる優先度群の中での優先順位
FreeRTOSの目的は、実行中のタスクを選択して指示し、プログラマーが各タスクに割り当てた優先度に基づいてタスクを入れ替えることです。この優先度は、タスクのインスタンス化の一部としてプログラマーによって割り当てられます。例えば、応答性の高いPID(比例・積分・微分)制御タスクには、バックグラウンド通信タスクよりも高い優先度が割り当てられます。この例では、リアルタイムプロセスの安定性を維持するために、PIDフォアグラウンドタスクを一定の間隔で完了する必要があります。一般的に、ユーザーとのバックグラウンド通信は時間的にクリティカルではありません。
このFreeRTOSに割り当てられた優先度を、マイクロコントローラのさまざまなISRの優先度と混同しないでください。この文脈においては、FreeRTOSのティックは、マイクロコントローラのリソースを競う多くのイベント(タイマ)駆動のISRの1つです。例えば、FreeRTOSのコンテキストスワップ機構自体は、ハードウェアタイマによって駆動されるISRとして存在しています。ハードウェアタイマのティックごとに、FreeRTOS ISRがスワップインされ、通信を起動するPIDの起動など、高レベルのマジックのような処理を実行します。すべてのISRと同様に、FreeRTOSはマイクロコントローラのリソースを占有しないように、できるだけ小さく書かれています。
この低レベルの分析では、FreeRTOS ISRはピンの状態の変化など他のISRと競合します。
attachInterrupt(digitalPinToInterrupt(QUAD1_A_PIN), ISR_QUAD1, CHANGE);
attachInterrupt(digitalPinToInterrupt(QUAD1_B_PIN), ISR_QUAD1, CHANGE);
要約すると、高レベルのFreeRTOSタスクの優先度と低レベルのISRの優先度を混同しないでください。FreeRTOSタスクはソフトウェアレベルで行われるのに対し、ISRの優先度はハードウェアの設定です。
ハードウェアベースのISR優先度とARM NVIC
TPORTENTA Pro C33 は、洗練されたRenesas Arm Cortexプロセッサを搭載しています。このマイクロコントローラは、複雑なリアルタイム環境で動作するように設計されています。その結果、関連するISRの優先度割り当てを可能にする、堅牢な割り込みベクタリングハードウェアメカニズムを備えています。さらに優れているのは、優先度の高いISRが優先度の低いISRをプリエンプトすることができるNVIC(Nested Vectored Interrupt Controller:ネスト型ベクタ割り込みコントローラ)を備えていることです。簡単な例として、FreeRTOS のティックISRにある優先度を割り当て、ArduinoのattachInterruptに別の優先度を割り当てることができます。
それでは、この記事の核心に移りましょう。
これらのハードウェアベースの優先度は、高速の直交エンコーダがフォアグラウンドで動作するように正しく割り当てる必要があります。実際、パルスの見逃しを防ぐために、FreeRTOSよりも高い優先度が必要です。別の言い方をすると、直交エンコーダのNVIC優先度は、FreeRTOSを優先するように選択されます。
Arduino PORTENTA Pro ARMプロセッサのNVIC ISRの優先度はどのように変更するのでしょうか?
NVICの動作を変更する方法はいくつかありますが、ここでは 単純な1行変更の解決策に焦点を当てます。それには、Arduino IDEの内部動作を調べて、renesas_portentaフォルダの中からIRQManager.cppファイルを見つける必要があります。
C:\Users\your_name\AppData\Local\Arduino15\packages\arduino\hardware\renesas_portenta\1.1.0\cores\arduino\IRQManager.cpp
ファイルを見つけたら、優先度を変更します。この例では、デフォルトのArduinoの優先度が12から5に変更されました(数値が小さいほど優先度が高くなります)。相対的に、直交エンコーダに関連付けられた外部割り込みが最も高い優先度になります。
#define EXTERNAL_PIN_PRIORITY 5 // default is 12
Arduino ARMのNVIC優先度を変更する際の制限は何でしょうか?
Arduino IDE(統合開発環境)の深部にある機密ファイルを公開してしまうことになり、Arduinoを簡単に壊してしまうため、個人的にはこのソリューションを好ましく思っていません。また、IDEをアップデートすると新しいファイルを修正する必要があります。言うまでもなく、このソリューションは移植性がなく、すべてのプログラマーが根本的な変更を加える必要があります。最後に、Arduinoチームが基礎構造を変更しないという保証もありません。
もし、Arduino IDEとARM NVICの操作に熟練しているのであれば、コメントするか、より良い解決策を提供してください。希望するARM NVIC優先度でattachInterrupt( )関数をオーバーロードすることができれば素晴らしいですね。あるいは、attachInterrupt( )がNVIC番号を返す方法もあります。これにより、NVIC_SetPriority( )などの関数が使用できるようになります。
直交エンコーダの優先度が高くなるようにARM NVICを構成すると、どのような結果になりますか?
このデモンストレーションでは、割り込み優先度を変更し、直交エンコーダが最優先になるようにしました。 これは、NCIV優先度をデフォルトの12から5に変更することによって行われました。その結果、図1に比べて大幅に改善されています。丸で囲んだ遅延は完全になくなり、モータはカウントを失うことなく最大速度で動作するようになりました。この例は以前のプロジェクトの続きであることに注意してください。C33は、有線Ethernet接続を介して「the quick brown fox jumps over the lazy dog」のメッセージ伝送や、シリアル接続を介した位置カウントのデータ伝送などの高い負荷がかかるプログラムがされています。
こちらからコードをダウンロードできます。FreeRTOSISR.zip(7.3 KB)
直交エンコーダには、堅牢なステートマシンベースのエラー検出メカニズムが含まれていることを思い出してください。システムを操作中にエラーは検出されませんでした。
おわりに
ARM Cortexマイクロコントローラを搭載したArduino PORTENTA Pro C33は、ARM NVICメカニズムによる多彩な割り込み制御機能を備えています。FreeRTOSと組み合わせる場合、FreeRTOSソフトウェア内の割り込み、およびハードウェアベースの割り込みの両方で優先度を慎重に割り当てる必要があります。本記事で紹介した直交エンコーダメカニズムは、この複雑さを探求するための良い出発点となります。私たちはこの豊かなテーマの探索を始めたばかりですので、さらに学び続けることをお勧めします。
以下にコメントと提案をお願いします。前述のように、これはArduino .ino setup ( )関数からNVIC の優先度を設定するための洗練されたなソリューションを必要とするプロジェクトです。
ご健闘をお祈りします。
APDahlen
関連するArduino教育コンテンツについては、こちらのリンクをご参照ください。
著者について
Aaron Dahlen 氏、LCDR USCG(退役)は、DigiKeyでアプリケーションエンジニアを務めています。彼は、技術者およびエンジニアとしての27年間の軍役を通じて構築されたユニークなエレクトロニクスおよびオートメーションのベースを持っており、これは12年間教壇に立ったことよってさらに強化されました(経験と知識の融合)。ミネソタ州立大学Mankato校でMSEEの学位を取得したDahlen氏は、ABET認定EEプログラムで教鞭をとり、EETプログラムのプログラムコーディネーターを務め、軍の電子技術者にコンポーネントレベルの修理を教えてきました。彼はミネソタ州北部の自宅に戻り、このような記事のリサーチや執筆を楽しんでいます。LinkedIn | Aaron Dahlen - Application Engineer - DigiKey