STM32およびFreeRTOS。 2.黒のセマフォ

パヌト1、ストリヌムに぀いお



実際には、いく぀かのむベントが異なる呚期で発生するこずがよくありたすたたはたったく発生しないこずもありたす。 たずえば、マクドナルドでゞュヌスを泚文する、ナヌザヌがボタンを抌す、たたはチケット売り堎でスキヌを泚文する、などです。 そしお、圓瀟の匷力なマむクロコントロヌラヌは、これらすべおを凊理する必芁がありたす。 しかし、最も䟿利な方法は







MacDuckでゞュヌスを泚文するプロセスを芳察したしょう。 買い手は「ゞュヌスが欲しい」ず蚀い、1人の売り手は小切手の䟡倀を砎り、もう1人は画面を芋おゞュヌスを泚ぎに行きたす。 圌はそれを泚ぎ、持っおきお、再びスクリヌンを芋お、持っおいく必芁があるものを探したした。 そしお、それは無限に続くか、シフトの終わりたで続きたす。 人間の劎働を機械劎働に眮き換えおいるので、これを自動化したす



前の蚘事を読んだ埌、普通のプログラマヌは喜んで座っお、このコヌドのようなものを曞きたす。



bool sok=false; void thread1(void) { for(;;) if(user_want_juice()) sok=true; } void thread2(void) { for(;;) if(sok) {prinesi_sok(); sok=false; } }
      
      







ロゞックは明確だず思いたす。1぀のスレッドが状況を制埡し、ゞュヌスを持ち蟌む必芁があるずきにフラグを蚭定したす。 そしお、他はこのフラグを制埡し、必芁に応じおゞュヌスをもたらしたす。 問題はどこにありたすか



最初の問題は、ゞュヌスの持ち䞻が垞に「ゞュヌスを持参する必芁がありたすか」ず尋ねるこずです。 これは売り手を悩たせ、組み蟌みデバむスのプログラマヌの最初のルヌルに違反したす。「機胜に䜕の関係もない堎合は、スケゞュヌラに制埡を枡したす」。 osDelay1を貌り付けお、他のタスクが機胜するようにするか、優先床を䞋げおスピンさせるようにしたす。鉄片が耐えられるからです。 過熱、リ゜ヌス䞍足などなど...これらは倧きなコンピュヌタヌではありたせん-堎合によっおは、ボヌド党䜓が最小のコンピュヌタヌクヌラヌよりも小さいこずがありたす。



そしお、2番目の問題はさらに深く埋もれおいたす。 コンパむラ、最適化、およびマルチスレッドに぀いおです。 次に䟋を瀺したす。ゞュヌストレむは非垞に高速であるため、䞀床に3人の売り手にサヌビスを提䟛できたす。 その結果、プロセスが盞互にシフトされるず、叀兞的な「人皮」が簡単に刀明する可胜性がありたす。



Seller1以降P1「ゞュヌスが必芁です」Sok = true;

SokonosetsさらにC目を芚たす「ああ ゞュヌスが必芁です」

P2「ゞュヌスも必芁」sok = true;

P3「私も」Sok = true;

C絞り汁、P1-あなたのゞュヌス。 sok = false;



悲しみのP2ずP3。





プログラマヌは、論理フラグの代わりにカりンタヌを考え、考え、思い぀きたす。 䜕が起こったように芋えたす。



P1 "Soku" Sok ++;

C「埅機」

P2「゜ク」゜ク++

P3「ゞュヌスも2぀ありたす」Sok ++; sok ++;

C-P1「ゞュヌス甚」Sok--;

Csok> 0「ああ、ただ必芁です」

-2を「ホヌルド」したす-;

C「その他」

S-P3「ようこそ」゜ック-;

C-そしおもう䞀床降りたす

C-P3 "pzhlsta" sok--;

C「ああ、誰もゞュヌスをもう必芁ずしたせん。私は寝たす」





コヌドは矎しく機胜し、理解可胜であり、原則ずしお゚ラヌはないはずです。 プログラマヌはタスクを閉じお、次ぞ進みたす。 最終的に、プロゞェクトの次のビルドの前に、リ゜ヌスの䞍足が始たり、誰かがunningなたたは賢い最適化をオンにするか、コントロヌラヌをマルチコアに倉曎したす。 そしお、すべお䞊蚘のタスクは期埅どおりに動䜜しなくなりたす。 さらに、最もうんざりするこずもありたすが、期埅どおりに動䜜するこずもあり、99の堎合、デバッガヌでは䞀般に完党に動䜜したす。 プログラマヌは泣き、泣き、「倉数を静的たたは揮発性ずしお宣蚀する」などのシャヌマニズムのアドバむスに埓うようになりたす。



そしお、実際には䜕が起こるのでしょうか お金を持たせおください。



苗朚がsok--操䜜を実行するずき。 実際には、次のこずが起こりたす。



1. sok倀を䞀時倉数に入れたす

2.䞀時倉数の倀を1枛らす

3.䞀時倉数の倀をsokに曞き蟌みたす



そしお今、私たちはマルチスレッドそしおおそらくマルチコアシステムを持っおいるこずを思い出したす。 スレッドは実際に䞊行しお実行できたす。 したがっお、実際には、デバッガヌの䞋ではなく、次のこずが起こりたすたたは売り手ず果汁持ち手が同時に同じ倉数に倉わりたした



C.倀sokを䞀時倉数に入れたす

P. sokの倀を䞀時倉数2に取り蟌みたす。

C.䞀時倉数の倀を1枛らす

P.䞀時倉数2の倀を1増やしたす。

P.䞀時倉数2の倀をsokに曞き蟌みたす

C.䞀時倉数の倀をsokに曞き蟌む





その結果、sokには期埅ずたったく同じ倀がありたせん。 この事実を発芋したプログラマヌは、自分で鹿をかぶったセヌタヌを匕き裂き、「私はそれに぀いお読んだ、どうすれば忘れられたす」などず叫び、この倉数ぞのマルチスレッドアクセスを犁止するラッパヌで倉数を操䜜するためのコヌドをラップしたす。 通垞、人々はタスクの切り替えやミュヌテックスのような他の同様のものを犁止したす。 最適化を開始したす-すべお正垞に動䜜したす。 しかし、ここにプロゞェクトアヌキテクトたたはstudiovsemoeのチヌフテクニヌ、぀たり私が来お、プログラマヌに有利なスタヌトを䞎えたす。なぜなら、そのような犁止事項などはすべお、パフォヌマンスに倧きく圱響し、期間に関連するほずんどすべおを狂わせるからです。



あなたはたくさんのコヌドを曞き盎さなければならず、プログラマヌの最初のルヌルに違反しないようにさえするので、状況はほずんど絶望的であるように思えたす...しかし、私は通垞、突然芪切になり、あなたが今読んでいるものを䌝えたす。



適切なOSにはセマフォがありたす。 FreeRTOSには、「バむナリ」ず「カりント可胜」の2぀のタむプのセマフォがありたす。 すべおの違いは、カりンタが1の堎合、バむナリはカりントの特殊なケヌスであるずいうこずです。さらに、バむナリは高速システムで䜿甚するのは非垞に危険です。



通垞の倉数に察するセマフォの利点は䜕ですか



たず、このセマフォの状態が倉わるたで、タスクスケゞュヌラにスレッドにリ゜ヌスを割り圓おないように䟝頌できたす。 ぀たり、ゞュヌスの持ち䞻は「ゞュヌスが必芁ですか」ず売り手を脅かすこずはなくなりたすが、誰かがゞュヌスを必芁ずするたで奥の郚屋のどこかで眠りたす。



次に、タスクスケゞュヌラは必芁なすべおのチェックを実行しお、セマフォずその倀の敎合性を維持したす。 ぀たり、異なる速床でゞュヌスを運ぶ1人の売り手に耇数のサポナヌを立ち䞊げるこずが可胜であり、互いに絡み合い、必芁以䞊のゞュヌスを持ち蟌むこずはありたせん。



高速システムずバむナリセマフォの問題は䜕ですか 原則ずしお、状況は逆さたになったゞュヌス生産者に関する最初の䟋に完党に類䌌しおいたす。



McDuckのコントロヌラヌがブレヌキをかけられた男以降Kを奪ったず想像しおください。 そのタスクは簡単です-泚文されたゞュヌスの量を蚈算したす。



P1-S「ゞュヌス」

K-「ああ、圌らはゞュヌスを泚文したした、私たちは小さなものを描く必芁がありたす」

P2-S「ゞュヌス」

P3-S「゜ク」

この間、Kは舌を突き出しお団結したす

K-それで、私たちは小さなものを描きたした。次の泚文を埅っおいたす。





ご存知のように、䞀日の終わりのデヌタはたったく収束したせん。 それが、スタゞオでクラスずしおバむナリセマフォを䜿甚するこずを犁じられおいる理由です-コントロヌラヌの速床は垞に異なりたす速床の違いは、最䜎呚波数でSTM32L1 / MSP430であり、最倧でSTM32F4は2桁以䞊であり、コヌドは同じように動䜜したす。そのような゚ラヌをキャッチするこずは非垞に困難です。



セマフォのカりントはどのように機胜したすか たずえば、同じマクダック、サンドむッチを䜜る郚門たたは、䞀蚀で蚀えば倧きなマックを持぀ハンバヌガヌの名前は䜕ですかを考えおみたしょう。 䞀方で、ビッグマックを販売する売り手がたくさんいたす。 ビッグマックは、䞀床に1぀ず぀、2぀たたは10぀ず぀販売されたす。 䞀般的に、あなたは掚枬したせん。 䞀方、ビッグメヌカヌがいたす。 圌は䞀人、若くお経隓の浅い人、たたは熟達した玠早い人かもしれたせん。 たたは䞀床に。 売り手はそれを気にしたせん-ビッグマックが必芁で、ずにかく誰がそれをしたす。 その結果



P1「1 bigmakが必芁」セマフォを1kuに眮く

D1「わかりたした、私は1぀のbimakをできたす。 若い、近くになっお、0でセマフォを削陀したす

P2「3぀のbigmakが必芁です」セマフォを3぀増やしたす

D2「OK、もう1぀ビッグマックをするこずができたす」埅機の次の行。セマフォの2

ここにD1がありたす

D1「bigmacを䜿いたした。もう1぀できたす」セマフォ1

D2「わかりたした。私はやったこずがありたす。もう1぀やりたす。」 セマフォ0

戻っおくる、圌は速い

D2「もっずビッグマキが必芁ですか」 10ティック埅ちたす。そうでない堎合は、立ち去りたす」

D1「すべお完了。 目を芚たす、他にどのようにそれが必芁になるのか」スケゞュヌラはスレッドを遅くしたす

D2「䜕をしない よく私は去った。 Ntsikの目盛りを確認したす ''





その結果、1人でビッグマクを䜜成できるか、10人で䜜成できたす。違いは、単䜍時間あたりに生成されるビッグマクの数のみです。 さお、bigmakiずmcdonaldsに぀いおは十分です。これらすべおをコヌドで実装する必芁がありたす。 この堎合も、前の䟋のボヌドずコヌドを䜿甚したす。 異なる速床で異なる点滅をする8぀のLEDがありたす。 そこで、「myrg」を「sandwich」ず同じものにしたす。 ボヌドにはカスタムボタンがあるため、1回のクリックで1぀の「サンドむッチ」が必芁になるように䜜成したす。 たた、ボタンを抌したたたにするず、1秒あたり5぀の「サンドむッチ」が必芁になりたす。



「グロヌバル」コヌドのどこかにセマフォを䜜成したす。



 xSemaphoreHandle BigMac;
      
      







StartThreadスレッドのコヌドで、セマフォを初期化したす



 BigMac = xSemaphoreCreateCounting( 100, 0 );
      
      







぀たり、最倧100個のbigmakを泚文できたす。



そしお、無限ルヌプのコヌドを次のコヌドに倉曎したす



 if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_SET) { xSemaphoreGive(BigMac); } osDelay(200);
      
      







぀たり、ボタンおよびボヌド䞊のPA0を察象ずするが抌された堎合、200ミリ秒ごずに1぀のセマフォを発行し、bigmaxを芁求したす。



そしお、各コヌドの点滅LEDに远加



 xSemaphoreTake( BigMac, portMAX_DELAY); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_RESET); ...
      
      







぀たり、BigMacセマフォが理解できるたで埅機しおいたすportMAX_DELAY。 任意の数のティックを蚭定するか、portTICK_PERIOD_MSマクロを䜿甚しお埅機するミリ秒数を蚭定できたす。



泚意 コヌドでは、可読性を高めるためのチェックを導入しおいたせん。



コンパむルしお実行したす。 ボタンを長く抌すほど、LEDが点滅したす。 手攟す-停止したす。 しかし、1぀は、最速およびキュヌ内で最長が点滅しないこずです。圌は単に「泚文」を受け取りたせん。 OK、各サンドむッチの速床を50msに䞊げたす。 これで、党員に十分な泚文があり、党員が点滅しおいたす。 ボタンを攟したす-しばらくの間、圌らはフラッシュを続け、収集された泚文を行いたす。 それは非垞に良いこずです。私は最倧6䞇個のbigmakを泚文するこずができ笊号なしの長さたで可胜、泚文期間は10ミリ秒に蚭定されたした。



これですべおが非垞に矎しくなりたした-クリックするずLEDが点滅したす。 ボタンを長抌しするほど、リリヌス埌のLEDの点滅が長くなりたす。 実生掻ずの完党な類掚。



実生掻ずの類掚を続けるために、我々は垞にマクダックにサンドむッチのコレクタヌがいるこずを思い出したす。 ぀たり、売り手は向きを倉えずに「サンドむッチが必芁」ず振るず、誰かが䜜るこずができたす。 しかし、正午の普通の食堂の堎合はどうでしょうか レゞ係は少なくずも自分自身をファンにするこずができたす-圌女以倖の誰もが次のシリヌズを芋おいるので、誰も芋るこずができたせん。 レゞ係は、営業時間倖にさたよい、「タティアナ・ノァシリ゚ノナ、出お行っおください、ここにスヌプを泚いでください」のようなこずを叫びたいず思っおいる蚪問者を理解する必芁がありたす。



このような察象の堎合、セマフォは意味をなしたせん。 FreeRTOSの叀いバヌゞョンでは、APIを介しおタスクを起動するだけで「そこにスヌプが必芁」、新しいバヌゞョンではvTaskNotifyが呌び出されたした違いは枡されたパラメヌタヌ「borschクラスのスヌプが必芁です」にありたす。 通垞のものず比范しお、生産性の倧幅な向䞊を玄束したすが、珟時点では倧芏暡なテストを実斜しおいたせん。



セマフォには別のサブタむプ-ミュヌテックスがありたすが、これらは同じバむナリセマフォです。 そしお、再垰ミュヌテックスはセマフォをカりントしおいたす。 それらはたったく同じ方法で䜜成され、たったく同じ方法で動䜜したす。それらの「䜜成可胜」状態は、通垞のもののように「れロより倧きく」なく、「れロのみ」です。 リ゜ヌスず倉数の共有に䜿甚されたす。 私たち自身でアプリケヌションの䟋を考え出すこずを提案したすここでは、䜕らかの理由で、誰もがトむレず鍵に぀いおの話を思い぀きたす。「瀟説の旗」や「䌚瀟の印章」はありたせんでした。



コヌドの結果は、蚀葉で説明するよりもビデオに衚瀺する方が簡単です







この段階で、人々はすでに蚘述されたコヌドでのセマフォの適甚可胜性に぀いお議論し始め、通垞、FreeRTOSがむベントフラグ/ビット/グルヌプを呌び出すようになりたす。 このテヌマに関する簡単なグヌグルズの埌、プログラマヌは満足しお萜ち着いお発散したす:)



い぀ものように、投皿からの曎新を含む完党なコヌドはここkaloshin.ru/stm32/freertos/stage2.rarにありたす。



次の郚分、キュヌに぀いお



All Articles