ロシアの1぀のRTOSの抂芁、パヌト8。割り蟌みの凊理

RTOS MAXによる「知識の本」の第1巻の最埌の蚘事を公開しおいたす。 この非公匏ガむドが、このRTOSで䜜業する必芁がある堎合に、同僚に圹立぀こずを願っおいたす。



前の蚘事

パヌト1.䞀般情報

パヌト2. RTOS MAXのカヌネル

パヌト3.最も単玔なプログラムの構造

パヌト4.有甚な理論

パヌト5.最初のアプリケヌション

パヌト6.スレッド同期ツヌル

パヌト7.タスク間でデヌタを亀換する手段

パヌト8.割り蟌みの凊理この蚘事



䞭断が重芁な理由



コンピュヌタヌサむ゚ンスの教垫は、ポヌリングだけでなく䞭断に぀いおの䜜業があるこずを非垞に奜んでいたす。その埌、圌らは通垞、䞭断の凊理の小さな䟋を挙げお、トピックに぀いお忘れたす。 さらに、実際のプログラミングでは、自分のスキンではなく、このビゞネスの基本を理解する必芁がありたす。



シングルタスクシステムでプログラミングする堎合、尋問機噚を操䜜するために「抜け出す」こずができたす。 マルチタスクシステムでは、これはたすたす困難になっおいたす。



最も単玔な䟋を考えおみたしょう。 9600ボヌずいう非垞に䜎い速床でシリアルポヌトから受信したす。 実際の速床は長幎250 KBaudの領域にありたしたが、問題を解決するために速床を萜ずすだけではなく、超䜎速バヌゞョンを考えおみたしょう。



シリアルポヌトには1バむトがありたす-これは私のお気に入りのポヌト蚭定で10ビットです8デヌタビット、および開始ず停止。 合蚈、960バむト/秒です。 1000に切り䞊げたす。これは1ミリ秒あたり1バむトです。 時間軞にむベントを配眮したす。







兞型的なコントロヌラが次のバむトが到着する前に次のバむトを凊理する時間がない堎合、ラむンから来た新しい倀によっお䞊曞きされたす。 STM32コントロヌラヌの説明から、ダむアグラムでこれの本質を怜蚎しおください。







デフォルトでは、タスクは1ミリ秒ごずに切り替えられたす。 5぀のタスクの順次切り替えの堎合を時間軞䞊に配眮したしょう。







タスク1でCOMポヌトをポヌリングしたす。2぀の図を組み合わせおみたしょう...







ご芧のずおり、シリアルポヌトからの4バむトは、それらを埅機しおいるタスクが非アクティブなずきに送信されたす。 倧きなハヌドりェアキュヌを持぀コントロヌラヌがありたす。 たずえば、ESP8266はハヌドりェアバッファヌで128バむトを受信できたす。 このようなコントロヌラで考慮される状況は䜕もありたせん-タスク1は、機噚によっお蓄積されたデヌタを受け取りたす。 ただし、たずえば、すべおのSTM32入力バッファでは、1バむトしか䜿甚できたせん。 そしお、圌らにずっお、ポヌリングの死のためにマルチタスク環境でシリアルポヌトを操䜜するこずは、9600ビット/秒のようなずんでもない速床でも同様です。



正しい解決策は、バッファメモリに到着したバむトを远加しお、凊理タスクが倧量に蓄積されたすべおを凊理するようにするこずです。 たたは、ある皮の前凊理たずえば、遅延なしで可胜な堎合はパケットの初期分析を実行し、凊理枈みのパラメヌタヌを凊理タスクに転送したす。



もちろん、ほずんどの読者に最も近いものずしお、シリアルポヌトを備えた䟋を遞択したした。 実際、シングルタスク環境でもポヌリングが受け入れられず、マルチタスク環境では䞍可胜な堎合が倚くありたす。 最初に頭に浮かぶのは、゚ンゞン速床を維持するこずです。 実際のケヌスは、゚ンゞンが1回転あたり2回のフィヌドバックパルスから、毎分最倧5,000回転の速床で回転するこずです。



回転速床を枬定するための兞型的なアルゎリズムの1぀では、タむマヌを䜿甚しおこれらのパルスの繰り返し呚期を枬定する必芁がありたす。 ぀たり、到着時にタむマヌを取り、新しい枬定のためにタむマヌを再起動する必芁がありたす。 パルスが到着しおから読み取り倀が取埗されるたでにランダムな時間が経過するず、枬定粟床が倧幅に䜎䞋したす。 たいおいの堎合、単玔に倧幅に䜎䞋するのではなく、容認できないほど䜎䞋したす。



状況を掚定しおみたしょう-毎分10,000フィヌドバックパルス。 60で陀算するず、167 Hzになりたす。 5ミリ秒に1パルス。これは、枬定の粟床を倱わないように、発生した瞬間にできる限り近く凊理する必芁がありたす。 むンパルスの到着時間を予枬するこずは䞍可胜です-゚ンゞンは圌に満足するように回転したす。 5぀のタスクの堎合、次のタスクぞの制埡の移行を埅぀可胜性のある時間は、パルス繰り返し呚期の半分以䞊です。 たずえば、次のような状況です。







むンパルスが到着しおから調査を実行するタスクが起動するたでにどのくらい時間が経過したかは䞍明です。 ご芧のずおり、ここでは、割り蟌みによっおのみ、あらゆる皮類の合理的なデヌタ凊理を実装できたす。 衝動が来お、その到着時刻が蚘憶されおおり、すでに凊理䞭のタスクはい぀でもこの時間を利甚できたす。



以䞊から、



マルチタスク環境での䞭断は匷力なだけでなく、倚くの堎合、機噚を操䜜するための唯䞀の可胜なメカニズムです。


RTOS MAXで割り蟌みを凊理するための䞻なメカニズム



RTOS MAXを䜿甚する堎合、割り蟌みは「䟿利」ず「高速」の2぀の方法で凊理できたす。 最初に、メむンオプション「䟿利」ず芋なされるものを怜蚎したす。



OS内では、共通のタスクが開発されたすが、 Taskから継承するのではなく、 TaskIrqから継承する必芁がありたす。 䞭断が発生するずすぐに他のすべおのタスクを眮き換える必芁があるため、このタスクには高い優先順䜍が䞎えられたす。 TaskIrqクラスには、IrqHandler仮想関数が含たれおいたす。これは、割り蟌みの凊理に関連するすべおのアクションをそこに配眮するこずでオヌバヌラむドする必芁がありたす。



初期化䞭に、割り蟌みコントロヌラヌのプログラミングを介しお割り蟌みを有効にする必芁がありたす最埌の2぀の段萜で「割り蟌み」ずいう蚀葉が䜕回蚀われたかが怖いですが、残念ながらそれなしでは䜕も起こりたせん。 蚈画タスクを蚭定するずきは、特別なクラスから継承されるため、凊理する割り蟌み芁求の数をパラメヌタヌの圢匏で指定する必芁がありたす。



むデオロギヌ的に、このタスクの課題は次のように衚すこずができたす。







そのため、優先床を高くする必芁がありたす。他のタスクず倉わらないため、それらを眮き換える必芁があり、これは優先床の助けを借りお行われたす。 次に実甚的な䟋を考えおみたしょう。 ここに兞型的なタスクがありたす-シリアルポヌトに接続された無線モゞュヌルのハンドラヌ。 ご芧のずおり、実際にはTaskIrqから継承されおおり、IrqHandler関数は実際にブロックされおいたす。







テキスト
class PortRadioTask : public TaskIrq { public: PortRadioTask() : TaskIrq("Radio") {} virtual void IrqHandler(); };
      
      







これがこのタスクの远加方法です。



 const int Radio_IrqNumber = EXTI15_10_IRQn; ... result = TaskIrq::Add(radio_task = new PortRadioTask, Radio_IrqNumber, Task::PriorityRealtime);
      
      





無線モゞュヌルの䟋のNVICセットアップは、このセクションの範囲倖です。 私の意芋では、この䟋ではあたり説明的ではありたせん。 玔粋に説明のために、別の䟋で特定のプロセッサに察しおNVICがどのように構成されおいるかを瀺したす優先順䜍を倉曎するこずはできたせんが、優先順䜍を倉曎するオプションは特別に遞択されたす。



  NVIC_EnableIRQ(EXTI9_5_IRQn); NVIC_SetPriority(EXTI9_5_IRQn,1);
      
      





だから。 タスクが蚘述され、そのTaskIrq機胜がブロックされ、タスクがスケゞュヌラヌに远加されたす。次は䜕ですか そしお-OSのケア。 割り蟌みが発生するず、内郚割り蟌みハンドラヌ自䜓がスケゞュヌラヌを呌び出したす。 1-タスクをアクティブにしたす。 ここで重芁なのは、タスクの優先床が高く 、他のタスクが混み合うこずが保蚌されるこずです。 そしお、しばらくしおからタスクを切り替えるために必芁、IrqHandler関数が制埡を獲埗したす。 この関数の本䜓に配眮するものは、アプリケヌションプログラマの問題ですドキュメントの次の郚分では、䞋䜍レベルのドラむバを操䜜するための䞀般的な゜リュヌションに぀いお説明したす。



暙準゜リュヌション





割り蟌みハンドラの簡単な䟋



 Semaphore s_sema_radio_irq(0, 1); //       void PortRadioTask::IrqHandler() { s_sema_radio_irq.Signal(); }
      
      





メむンメカニズムの䜿甚時に起こりうる問題



メむンの割り蟌み凊理メカニズムを䜿甚するこずで発生する可胜性のある問題はすべお、1぀のこずに関連しおいたす。ハンドラヌタスクを起動するには、タスクコンテキストを切り替える必芁がありたす。 時間がかかりたす。 2぀のタスクがあるシステムでの実際の䜜業では、オシログラムで、切り替えが4.7マむクロ秒で発生したこずがわかりたした。 䞀般に、時間はビルドオプション、タスクの数、およびその他の条件に䟝存したす。 さらに掚定の基瀎ずしお、10マむクロ秒ずいうかなり珟実的でかなり䞞い倀を取りたしょう。



マむクロコントロヌラによっお凊理される機噚の兞型的なシナリオをいく぀か芋おみたしょう。 簡単なものから始めたしょう。 250キロビットの速床でシリアルポヌトを介しおG-CODEコマンドを受信するCNCマシン。 既に述べたように、シリアルポヌトでは、バむトは10ビット8デヌタビットに加えお、開始ビットず停止ビットです。 合蚈で、バむト到着率は25 kHzです。 40マむクロ秒で1バむト。 たた、コンテキストの切り替えには10マむクロ秒かかりたす。







マむクロコントロヌラ匷力な32ビットマむクロコントロヌラの動䜜時間の4分の1は、コンテキストの切り替えにのみ䜿甚されたす。これは、Gコヌドの行が1぀ず぀、かなり高密床のストリヌムになるためです。 これは受け入れられたすか 可胜性が高いはい。



さらに、150 mm / sの速床で印刷する3Dプリンタヌで1ミリメヌトルあたり200ステップを必芁ずするステッピングモヌタヌを䜿甚するには、30 kHzの呚波数で動䜜する必芁がありたす。 これは4分の1以䞊です。



Gコヌドは、ステッピングモヌタヌを制埡する同じコントロヌラヌで採甚されおいたす。 合蚈するず、割り蟌みを入力するためにプロセッサ時間の半分以䞊がすでに必芁です。



もちろん、このオプションは受け入れられたせん 。



しかし、䞀方で。 同じ速床で同じシリアルポヌトを䜿甚したすが、32バむトパケットが1秒間に4回送信される無線モゞュヌルに接続したす。 したがっお、プロセッサの負荷は1200マむクロ秒の長さのセクションで増加し、そのようなピヌク負荷の期間は1秒で4800マむクロ秒以内に発生したす。 これは時間の4.8です。 受け入れられたすか たいおいの堎合。 ぀たり、暙準的な方法で凊理するためのこのオプションは受け入れられるず考えおいたす。



同様に、フィヌドバック信号から゚ンゞン速床を決定するための前述のメカニズムは受け入れられないず掚定できたす-タむマヌは信号が到着した瞬間に可胜な限り近づけるべきです。 たた、湿床センサヌからの読み取り倀の取埗は完党に受け入れられたす。 同時に、シリアルポヌトからのデヌタを毎秒921キロビットの速床で凊理するず、タスクを切り替えるのに100の時間がかかるため、受け入れられたせん...たあなどです。 Acceptable Unacceptableゲヌムは長時間プレむできたす。 䞀般原則を定匏化したしょう。



䞭断がめったに起こらない堎合、このオプションは受け入れられたす。



䞭断が頻繁に発生しおコンテキストの切り替えに100以䞊かかる堎合、このオプションは受け入れられたせん



コンテキストの切り替えにかかる時間の割合が高い堎合、これはめったに起こらず、十分に短いバヌストで発生したす-オプションは受け入れ可胜です。



高呚波でのスむッチングが䞀定の堎合、このオプションは受け入れられたせん。



どのような代替品を提䟛できたすか もちろん、盎接割り蟌み凊理。



䞻なメカニズムを拒吊すべきではない理由



「すべおの堎合に盎接割り蟌み凊理を提䟛しないのはなぜですか」 RTOS MAXの開発者にたったく同じ質問をしたした。 残念ながら、圌らの答えは質的でした。暙準凊理がさらに䟿利な理由がありたす。



簡単なものから始めたしょう。 割り蟌みハンドラヌの名前。 ARMファミリ内でも、それらは異なりたす。 STM32ずMilanderファミリヌの最も顕著な違いは次のずおりです。

STM32 ミランダヌ
USART1_IRQHandler UART1_IRQHandler
TIM1_UP_TIM10_IRQHandler Timer1_IRQHandler
TIM2_IRQHandler Timer2_IRQHandler


移行䞭に、それらを曞き換える必芁がありたす。 基本的なメカニズムでは、ハンドラヌの名前はOSの関心事です。 それらはアプリケヌションプログラマから隠されおいたすベクトルの名前が隠されおいないのは残念ですが、それなしではできたせん。



さらに、暙準ハンドラヌを䜿甚するず、通垞のタスクが呌び出されたす。 真の割り蟌みハンドラは、アプリケヌションプログラマの目には芋えたせん。 ハンドラヌタスクを起動し、コンテキストを切り替える必芁があるこずをスケゞュヌラヌに通知したす。 それ以倖はすべお共通のタスクです。 しかし、䞭断があるず、すべおが異なりたす。 OSの説明リアルタむムであっおも、Windowsであっおもを芋るず、非垞に倚くのメカニズムが割り蟌みハンドラヌで機胜しないこずがわかりたす。 RTOS MAXのメカニズムをすばやく調べたす。







いく぀かの゚ントリが黄色であるず思われる理由を芋おみたしょう結局、ある条件䞋では、メカニズムは利甚可胜ですが、赀色でマヌクされおいたす。 これらのメカニズムを実装する堎合、関数を再入力する可胜性を排陀する必芁がありたす。 このため、クリティカルセクションがその䞭に配眮されたす。これは、思い出すように、優先床がMAX_SYSCALL_INTERRUPT_PRIORITYよりも䜎いすべおの割り蟌みをブロックしたす。 実際、それだけです。 䞭断は䞀時的に犁止されおいたす。 ぀たり、盎接割り蟌み凊理の恩恵は受けたせん。 䞀方、メむンの割り蟌み凊理゚ンゞンで利甚可胜なすべおの蚭備は倱われたす。 䞀般に、メむンの割り蟌み凊理メカニズムを盎接のメカニズムに優先しお拒吊する状況では、セマフォを蚭定できず、メッセヌゞキュヌを䜿甚できたせん。 したがっお、衚では赀でマヌクされおいたす。



したがっお、OSのすべおの機胜を䜿甚できる堎合は、それらを䜿甚する方がより簡単であり、これが極端に必芁な堎合にのみ割り蟌みの盎接凊理に進みたす。



盎接割り蟌み凊理



盎接割り蟌み凊理では、反応速床はマむクロコントロヌラヌの機胜によっおのみ決定されたす。 各プロゞェクトで䜿甚可胜なstartupXXXX.sファむルから割り蟌みハンドラヌのリストを取埗するず䟿利です。 PinListAndTimerDemoデモアプリケヌションは、タむマヌ2からの割り蟌みを凊理したす。ハンドラヌの名前をすばやく芋぀ける方法を芋おみたしょう。



0



ハンドラヌの名前がわかれば、次のルヌルを䜿甚しおそれを行うのは非垞に簡単です。





したがっお、前述の䟋では、開始コヌドのタむマヌ2からの割り蟌みハンドラヌは次のように名前が付けられおいたす。







そしお、凊理機胜、それぞれ、



 extern "C" void TIM2_IRQHandler (void) { ...
      
      





このような割り蟌みのハンドラヌはできるだけ早く実行する必芁があるこずを芚えおおくこずが重芁です。 プログラムがハンドラヌにある間、他のすべおのタスクは機胜せず、優先順䜍の䜎い割り蟌みはブロックされたす。



割り蟌みハンドラヌは、デヌタをすばやく受け入れ、さらに凊理するためにデヌタを挿入し、すぐに䜜業を停止する必芁がありたす。 耇雑な蚈算や、割り蟌みハンドラでのその他の䜙分な䜜業を芋぀ける必芁はありたせん。



割り蟌みをメむンタスクに接続するための䟿利なメカニズムは、リングバッファです。 割り蟌みは、受信したデヌタを到着するずそこに入れ、䞀郚のタスクはそれを受け取り、凊理速床を気にせずに䜿甚したす。



mcucppラむブラリのリングバッファヌ



補助ラむブラリずしお䜿甚されるKonstantin Chizhovのmcucppラむブラリには、すでにリングバッファの実装が含たれおいたす。 ドキュメントの次の郚分でラむブラリに぀いお倚くのこずを述べたすが、今のずころ、ファむルring_buffer.hを考えおみたしょう。



RingBufferクラスは、䜜業でnew挔算子を䜿甚しお各芁玠を远加するため、リアルタむムアプリケヌションおよび特に割り蟌みでは䜿甚できたせん。 しかし、同じヘッダヌファむルには、RingBufferPO2クラスが含たれおいたす。リングバッファヌのサむズは2のべき乗の倍数です。 このクラスは、事前に割り圓おられたバッファヌで機胜するだけでなく、マむクロコントロヌラヌコマンドシステムが蚱可する「1぀のラむタヌ、1぀のリヌダヌ」スキヌムに察しおスレッドセヌフです危険なカりンタヌはアトミックアクセスクラスを介しお曞き蟌たれ、セキュリティは既にそのクラスによっお決定されおいたす。



クラスは次のように定矩されたす。



テンプレヌト<size_t SIZE、クラスT、クラスAtomic = VoidAtomic>

クラスRingBufferPO2



SIZE-芁玠の数。 2の环乗の倍数でなければなりたせん。そうしないず、コンパむラヌぱラヌをスロヌしたす。



Tは、保存されるデヌタのタむプです。 スカラヌず構造の䞡方が蚱可されたす。



Atomic-操䜜の原子性を保蚌するクラス指定されおいない堎合、原子性は提䟛されたせん。



デヌタを保存するためのバッファは、クラスのメンバヌ倉数です。 したがっお、クラスオブゞェクトは、十分な空き領域スタック、ヒヌプ、グロヌバルメモリ、特別に定矩されたメモリプヌルなどがあるプヌルに配眮する必芁がありたす。


COMポヌトから受信したバむトのバッファヌの宣蚀䟋64文字



 Mcucpp::Containers::RingBufferPO2<64, uint8_t, Mcucpp::Atomic> bufFromUart;     ,   <b>bool push_back(const T& value)</b>
      
      





結果がfalseの堎合、バッファがいっぱいであるため、デヌタは配眮されおいたせん。



通垞、関数を䜿甚しお、キュヌからデヌタをプッシュするデヌタを取埗したす。 スカラヌ量の堎合、これは正圓化されたすが、構造の堎合-远加のコピヌ操䜜が実行されたす-デヌタは叀い堎所から削陀されるため、新しい堎所にコピヌされたす。 おそらく、コピヌを防ぐために、mcucppラむブラリの䜜成者はわずかに異なる方法を䜿甚したした。 キュヌからのデヌタはプッシュされたせんが、読み取られたすそれらぞのリンクが取埗されたす。 デヌタを削陀するには、別の機胜が䜿甚されたす。



メむンデヌタ読み取り関数は、次のように呌び出すこずができたす。



const Tフロントconst

Tバック



ご芧のずおり、デヌタぞのリンクを返したす。぀たり、 コピヌしたせん。



キュヌ内の最新のアむテムぞのリンクを取埗できたす。



const Tbackconst

Tフロント



むンデックスでキュヌを操䜜するこずもできたす



const T挔算子[]size_type iconst

T挔算子[]size_type i



さお、芁玠が䞍芁になったら 、次の関数を䜿甚しおキュヌから削陀する必芁がありたす。



bool pop_front



キュヌが空の堎合、関数はfalseを返したす。



混雑ず空のキュヌをチェックするための補助機胜もありたす。



bool fullconst

bool emptyconst



珟圚キュヌにあるアむテムの正確な数を確認できたす。



size_type sizeconst



最埌に、キュヌの容量を調べるこずができたすただし、䞀定であり、プログラム開発の段階で蚭定されたすが、動的バッファずの互換性のために、これらの機胜が圹立぀堎合がありたす。



size_type max_size

size_type容量



1぀ではなく2぀の関数を呌び出すアプロヌチがどれほど悪いかを確認したしょう。 適切なベンチマヌクを取埗するには、コヌドフラグメントを個別の呌び出しでフレヌム化したす察応する行を消したす。







テキスト
  txtOuter.ShowSymbol('A'); txtOuter.ShowSymbol(bufFromUart.front()); bufFromUart.pop_front(); txtOuter.ShowSymbol('B');
      
      







察応するアセンブラコヌドは次のようになりたす。







テキスト
00025c 2141 MOVS r1,#0x41 ;288

00025e a801 ADD r0,sp,#4 ;288

000260 f7fffffe BL _ZN9TextOuter10ShowSymbolEwb ; TextOuter::ShowSymbol(wchar_t, bool)

000264 484b LDR r0,|L4.916|

000266 2201 MOVS r2,#1 ;290

000268 f8901044 LDRB r1,[r0,#0x44] ;290

00026c f001013f AND r1,r1,#0x3f ;290

000270 5c09 LDRB r1,[r1,r0] ;290

000272 a801 ADD r0,sp,#4 ;290

000274 f7fffffe BL _ZN9TextOuter10ShowSymbolEwb ;

000278 f3bf8f4f DSB ;290

00027c 4845 LDR r0,|L4.916|

00027e 6c02 LDR r2,[r0,#0x40] ;290

000280 6c41 LDR r1,[r0,#0x44] ;290

000282 428a CMP r2,r1 ;290

000284 d001 BEQ |L4.650|

000286 1c49 ADDS r1,r1,#1 ;290

000288 6441 STR r1,[r0,#0x44] ;290

|L4.650|

00028a 2201 MOVS r2,#1 ;293

00028c 2142 MOVS r1,#0x42 ;293

00028e a801 ADD r0,sp,#4 ;293

000290 f7fffffe BL _ZN9TextOuter10ShowSymbolEwb ;








ご芧のずおり、オプティマむザヌは関数呌び出しを行わず、すべおを盎線的に配眮したした。 たた、コヌドの品質は、1぀たたは2぀の関数があれば違いはありたせん。 構造を䜿甚する堎合、コピヌは行われないためです。



リングバッファの䟋



実際、この䟋は単玔です。 COMポヌトからのデヌタをバッファリングする䟋ずしお考えおください。 ドキュメントの第3郚では、COMポヌトずその割り蟌みの詳现な操䜜を怜蚎したす。 64芁玠のバッファヌを宣蚀したす平均30文字の行が凊理された堎合、そのようなバッファヌは確実にオヌバヌフロヌしないず盎感的に刀断したした。



 #include <ring_buffer.h> #include <atomic.h> ... Mcucpp::Containers::RingBufferPO2<64, uint8_t, Mcucpp::Atomic> bufFromUart;
      
      





割り蟌みハンドラヌで、バッファヌにデヌタを入れたす。



 bufFromUart.push_back (Buf[i]);
      
      





そしお、タスクの1぀では、ずりわけ次のようなアクションを実行したす。



  while (!bufFromUart.empty()) { char ch = bufFromUart.front(); bufFromUart.pop_front(); ...
      
      





デヌタが䞊曞きされる心配はありたせん蚀うたでもなく、キュヌのサむズはオヌバヌフロヌしないように十分でなければなりたせん。 さお、受け取ったキャラクタヌchでいく぀かのアクションを実行したす。 キュヌが空の堎合、指定されたルヌプぞの゚ントリは発生したせん。



混合割り蟌み凊理



混乱を避けるために、簡単なフレヌズから始めたす。割り蟌みの凊理を開始するために必芁なものはすべお既に説明されおいたす。 他のすべおはすでに曲技飛行です。 おそらく最も正しいこずは、最初に2぀の極端な方法ゆっくりず䟿利に、たた迅速に、あたり䟿利ではないを習埗しおから、セクションのこの郚分の読み取りに戻るこずです。



䞭断を凊理する方法はさたざたです。 最初に、ハンドラヌが曞き盎され、重芁なアクションが最初に実行され、次に通垞の高優先床タスクがアクティブ化されたす。 特に、呚波数枬定の堎合、このハンドラヌでは、実際のタむマヌ倀は足からの割り蟌みの瞬間に取埗でき、その埌タむマヌは次の枬定のために開始され、その埌、タむマヌから受け取った倀の凊理の問題は通垞のタスクに委任されたす。 たあ、そしお他のもの。 即時の反応が重芁であり、コンテキストの切り替えに時間がかかるずいう事実が重芁でない堎合は、この方法を䜿甚できたす。



そこで、TaskIrqによっお生成されたタスクを䜜成し、独自の割り蟌みハンドラヌを䜜成し、その䞭でタむムクリティカルなアクションを実行したした...次に䜕をしたすか



そしお、 MaksIrqHandler関数を呌び出す必芁がありたす。 この関数は、コンテキスト切り替えを開始し、割り蟌み関連関数ぞの制埡転送を行いたす。







テキスト
 extern "C" { extern void MaksIrqHandler (); void EXTI15_10_IRQHandler() { if (EXTI_GetITStatus(EXTI_Line13) != RESET) { /* Clear interrupt flag - ,   ! */ EXTI_ClearITPendingBit(EXTI_Line13); //      MaksIrqHandler (); } } }
      
      







仮想割り蟌み



そしお最埌に、割り蟌みに盎接関連しおいないが、割り蟌みに関連付けられおいるメカニズムを怜蚎したす。 このメカニズムは、必須ではなく、プログラマに远加の衚珟情報を提䟛するだけです。



タスクを䜜成するずき、 TaskIRQ埌続クラスに 、実際には存圚しない割り蟌み番号を割り圓おるこずができたす。 FIRST_VIRT_IRQ倀よりも倧きくする必芁がありたすARMアヌキテクチャの堎合、この倀は0x100ですが、他のアヌキテクチャの堎合は異なる堎合がありたす。



このようなタスクは実際の割り蟌みに関連付けられおおらず、カヌネルによっお自動的にアクティブ化されるこずはありたせん。 ただし、プログラマはい぀でも関数を呌び出すこずができたす。



void ProceedIrqint irq_num;



その埌、タスクは、䞭断に関連するタスクのアクティブ化のすべおの原則に埓っおアクティブ化されたす。 なんで オプションはおそらく最も玠晎らしいです。 たずえば、1぀のベクタヌで耇数のデバむスが「ハング」した堎合、同じ物理割り蟌みハンドラヌから耇数の異なるハンドラヌタスクを呌び出すこずができたすIRQラむンの範囲が広くおも、コントロヌラヌ開発者でさえ呌び出しを組み合わせるこずができたす。 䞀般に、OS開発者の1人が説明したように、「メカニズムは寄付されたした。なぜ䜿甚しないのですか」 ProceedIrq 関数は、いずれにしおもシステムの内郚ニヌズに必芁です。



これに関しお、䞭栞の怜蚎はドラフトが完了したず芋なすこずができたす。 ドラむバヌは先行しおいたすが、マニュアルの第2巻ではそれらに぀いお説明しおいたす。



All Articles