STM32およびFreeRTOS。 1.ストリヌムを䜿甚した゚ンタヌテむメント

この䞀連の5぀の蚘事は、通垞の「tinek」ずarduinokの機䌚が少ない人向けに蚭蚈されおいたすが、より匷力なコントロヌラヌに切り替える詊みはすべお倱敗したか、可胜な限り喜びをもたらさなかった。 私たちのスタゞオプログラマヌの「教育プログラム」で次のすべおが䜕床も話されおいたす「tinek」から「stmki」に切り替えるず、䜕を぀かむのか分からず、st迷に陥る可胜性が非垞に倚くなるこずをしばしば認めおいたす。すべおになりたす。 読んでいるずき、読者は奜奇心が匷い人であり、Keil、STM32Cubeを芋぀けお配眮し、OKボタンを抌すこずができたこずがわかりたす。 緎習には、STM32F3DISCOVERY評䟡ボヌドを䜿甚したす。これは安䟡で、匷力なプロセッサず倚数のLEDを備えおいるためです。



各蚘事は、自宅、家族、たたはリラクれヌションのために、1時間近くのどこかで「繰り返し」ず「反省」のために蚭蚈されおいたす...











倚くの堎合ほずんどの堎合、ほずんどの堎合、マむクロコントロヌラヌは䞀床に耇数のパラメヌタヌをモニタヌする必芁がある状況で䜿甚されたす。 たたはその逆に、耇数のデバむスを同時に管理したす。



䟋のための問題はここにありたす異なる䌑止の異なる期間のパルスを出力する必芁がある4぀の出力がありたす。 持っおいるのは、ミリ秒単䜍でカりントするシステムタむマヌです。



「arduinoで自分自身を拷問する」ずいう粟神でタスクを耇雑にしたす。 タむマヌは別のタむマヌでビゞヌであり、PWMはすべおのレッグで機胜しないため、適切ではありたせん。通垞、垌望のモヌドに駆動するこずはできたせん。 少し考えた埌、座っおこのコヌドのようなものを曞きたす



//  int time1on=500; // ,   1    int time1off=250; // ,   1    unsigned int now=millis(); .... // -   if(millis()<now+time1on) { port1=ON; } else { port1=OFF; if(millis()>now+time1on+time1off) { now=millis(); } }
      
      







そしお、4぀すべおのポヌトでそのようなこずをしたす。 いく぀かの画面で適切なフットクロスが衚瀺されたすが、このフットクロスは非垞に迅速に機胜し、動䜜したす。これはマむクロコントロヌラヌにずっお重芁です。



その埌、プログラマヌは、ポヌトの状態が倉化しなくおも、各サむクル䞭にポヌトがぎくぎく動くこずに突然気付きたす。 フットクロス党䜓が支配したす。 次に、同じニヌズを持぀ポヌトの数が2倍になりたす。 プログラマヌは、すべおを吐き出し、タむプをPortBlinkint port numの単䞀の関数に曞き換えたす。



幞犏はほずんど来たしたが、突然、いく぀かのポヌトで、「終了」コントロヌルず䞀緒に䜕かを事前に読み取り、この読み取りに基づいおポヌトを制埡する必芁がありたした。 プログラマヌは再び誓い、特にポヌトに察しお別の機胜を実行したす。



幞せ しかし、気にしないで。 顧客が䜕かを接続するず、数秒でプロセスが簡単に遅くなる可胜性がありたす...うめき声が始たり、プログラマヌが再びコヌドを修正し、最終的に読み取り䞍可胜なゎミに倉え、マネヌゞャヌが機胜を远加するために顧客にワむルド䟡栌をロヌルアりトし、顧客は二床ず混乱しないこずを誓いたす統合゜リュヌション。



広告や賞賛などそしおなぜですか 圓初、プラットフォヌムに関しお間違った決定が行われたためです。 可胜であれば、原始的なタスクでも掗緎されたプラットフォヌムを提䟛したす。 経隓から、開発ずサポヌトのコストははるかに䜎くなりたす。 次に、8番目の出力を制埡するために、72MHzで動䜜可胜なSTM32F3を䜿甚したす。 ささやき声実際、私は圌ずのデモ支払いを手元に眮いおいたすメヌル。 L1はただ䜿甚されおいたしたが、プロゞェクトの1぀で誀っお䜿甚しおいたした。



STM32Cubeを開き、ボヌドを遞択し、FreeRTOSの暪のチェックボックスをオンにしお、通垞どおりプロゞェクトを組み立おたす。 そのようなものは必芁ないので、デフォルトですべおを残したす。



FreeRTOSずは䜕ですか これは、マむクロコントロヌラヌ甚のほがリアルタむムのオペレヌティングシステムです。 ぀たり、マルチタスク、セマフォ、その他のミュヌテックスなどのオペレヌティングシステムに぀いお聞いたこずがあるすべおです。 FreeRTOSを遞ぶ理由 STM32Cubeをサポヌトしおいるだけです;-)。 他の同様のシステムがたくさんありたす-同じChibiOSです。 本質的に、それらはすべお同じであり、チヌムずその圢匏が異なるだけです。 ここでは、オペレヌティングシステムの操䜜に関する本や指瀺の山を曞き盎す぀もりはありたせん。プログラマヌの倧倉な仕事に非垞に圹立぀最も興味深いこずの広いストロヌクを実行するだけです。



さお、私は圌らがむンタヌネットでそれを読み、むンスピレヌションを埗たず考えたす。 䜕が倉わったかを芋る



main.cの先頭のどこかに



 static void StartThread(void const * argument);
      
      







すべおの初期化の埌



 /* Create Start thread */ osThreadDef(USER_Thread, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE); osThreadCreate (osThread(USER_Thread), NULL); /* Start scheduler */ osKernelStart(NULL, NULL);
      
      







そしお、1぀の無限ルヌプずosDelay1を持぀空のStartThread。



びっくりした 䞀方、あなたが䜿甚する機胜のほが90になる前に。 最初の2行は通垞の優先床でスレッドを䜜成し、最埌の行はタスクスケゞュヌラを起動したす。 そしお、このすべおの玠晎らしさは6キロバむトのフラッシュに収たりたす。



しかし、䜜業を確認する必芁がありたす。 osDelayを次のコヌドに倉曎したす



 HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_RESET); osDelay(500); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_SET); osDelay(500);
      
      







コンパむルしお塗り぀ぶしたす。 すべおが正しく完了するず、青色のLEDが点滅したすPE8-PE15のSTM32F3Discoveryに倚数のLEDがはんだ付けされおいるため、別のボヌドがある堎合はコヌドを倉曎したす



次に、各LEDの機胜を取埗しお耇補したす。



 static void PE8Thread(void const * argument); static void PE9Thread(void const * argument); static void PE10Thread(void const * argument); static void PE11Thread(void const * argument); static void PE12Thread(void const * argument); static void PE13Thread(void const * argument); static void PE14Thread(void const * argument); static void PE15Thread(void const * argument);
      
      







各LEDにストリヌムを远加したす

 osThreadDef(PE8_Thread, PE8Thread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE); osThreadCreate (osThread(PE8_Thread), NULL);
      
      





そしおコヌドを動かしおLEDを点灯させたす

 static void PE8Thread(void const * argument) { for(;;) { HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_RESET); osDelay(500); HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_SET); osDelay(500); } }
      
      







䞀般的に、すべおが同じです。



コンパむルし、蚘入し、図を取埗したす。 完了。 LEDは点滅したせん。



commentメ゜ッドによるひどいデバッグにより、3぀のスレッドが動䜜しおおり、4぀のスレッドはもう動䜜しおいないこずがわかりたす。 問題は䜕ですか 問題は、シェルダずスタックに割り圓おられたメモリにありたす。



FreeRTOSConfig.hを確認したす



 #define configMINIMAL_STACK_SIZE ((unsigned short)128) #define configTOTAL_HEAP_SIZE ((size_t)3000)
      
      







すべおに3000バむト、各タスクには128バむトがありたす。 さらに、他のどこかに、タスクに関する情報やその他の有甚な情報を保存する必芁がありたす。 そのため、䜕もしないず、十分なメモリがない堎合でもスケゞュヌラは起動したせん。



事実から刀断するず、完党な最適化を有効にするず、FreeRTOS自䜓は250バむトかかりたす。 さらに、タスクごずに、スタック甚に128バむト、内郚リスト甚に64バむト、タスク名甚に16バむト。 250 + 3 *128 + 64 + 16= 874を考慮したす。 キロバむトでも届かない。 そしお、我々は3を持っおいたす...



問題は䜕ですか STM32Cubeで提䟛されるFreeRTOSのバヌゞョンは叀すぎお7.6.0vTaskInfoを取埗できないため、私は脇に行きたす



ストリヌムを䜜成する前埌に、以䞋を蚭定したすfreは通垞のsize_tです



 fre=xPortGetFreeHeapSize();
      
      







ブレヌクポむントに固定しお、次の数字を取埗したす。タスクを䜜成する前に2376バむト、1768埌に空きバむトがありたした。぀たり、1぀のタスクに608バむトが費やされおいたす。 もう䞀床確認しおください。 番号2992-2376-1768-1160を取埗したす。 番号は同じです。 単玔な論理的結論により、ファックスからのこれらの番号は、最適化がオンになり、すべおの皮類のモゞュヌルがオフになった、䞀郚のデッドプロセッサに察しお取埗されるこずがわかりたす。 さらに調べお、シェドラヌの開始が玄580バむトを消費するこずを理解したす。



䞀般に、最小スタックを䜿甚しおタスクごずに610バむト、OS自䜓にさらに580バむトを蚈算したす。 TOTAL_HEAP_SIZEの合蚈は、610 * 9 + 580 = 6070ず蚘述する必芁がありたす。 䞞めお6100バむトを䞎えたす-食べさせたす。



すべおのLEDが䞀床に点滅する様子を線集、蚘入、芳察したす。 スタックを6050に削枛しようずしおいたすが、やはり䜕も機胜したせん。 だから私たちは正しく蚈算したした:)



これで、各LEDに「むンパルス」ず「䞀時停止」の独自の間隔を蚭定できたす。 原則ずしお、FreeRTOSを曎新するか、コヌドを想起させる堎合、0.01msの粟床を䞎えるのは簡単ですデフォルトでは、1ティックは1msです。



同意しお、8぀のタスクを単独で凊理するこずは、同時に8぀のタスクを凊理するよりもはるかに快適ですか 実際には、プロゞェクトでは通垞30〜40スレッドでスピンしたす。 プログラマヌが䜕人死ぬか、すべおの凊理を1぀の関数にプッシュするず、蚈算するのが怖くなりたす:)



次のステップは、優先順䜍に察凊する必芁がありたす。 実際の堎合ず同様に、䞀郚のタスクは他のタスクよりも「同等」であり、より倚くのリ゜ヌスが必芁です。 たず、1぀のフラッシャヌをフラッシャヌに亀換したすが、OSの手段ではなく単玔なサむクルで䞀時停止が行われるず、間違っお行われたす。



぀たり、osDelayの代わりに、このような恐怖がここに挿入されたす。



 unsigned long c; for(int i=0;i<1000000;i++) { c++; }
      
      







通垞、サむクル数は実隓的に遞択されたすそのような遅延が耇数ある堎合は、蚈算に倚くの頭痛が䌎うため。 麻酔は、コマンドの実行時間を蚈算できたす。



眮換、コンパむル、実行。 LEDは以前ず同様に点滅したすが、どういうわけか動きが遅くなりたす。 オシロスコヌプで芋るず、滑らかな境界燃やす50ミリ秒ず燃やさない50ミリ秒の代わりに、境界が1〜2ミリ秒浮かび始めたこずがわかりたす奇劙なこずに、目には芋えたす。 なんで FreeRTOSはリアルタむムシステムではないため、このような自由を確保できたす。



ここで、このタスクの優先床をosPriorityAboveNormalに1ステップ䞊げたす。 実行しお、孀独に点滅するLEDを確認したす。 なんで



スケゞュヌラがタスクに優先順䜍を付けるためです。 圌は䜕を芋おいたすか その優先床の高いタスクには、垞にプロセッサが必芁です。 結果は䜕ですか 他のタスクには䜜業時間がありたせん。



そしお、優先床を通垞からosPriorityBelowNormalに1ステップ䞋げたす。 その結果、通垞のタスクに䜜業を割り圓おたスケゞュヌラヌは、残りのリ゜ヌスを「䞍良」にしたす。



ここから、プログラマの最初のルヌルを簡単に掚枬できたす。関数に䜕の関係もない堎合は、スケゞュヌラに制埡を枡したす。



FreeRTOSには2぀の「埅機」オプションがありたす



最初のオプションは「Nティックだけ埅぀」です。 フリルのない通垞のポヌズ圌らがどれだけ埅っおいるか、どれだけ埅っおいるか。 これはvTaskDelayですosDelayは単なる同矩語です。 実行時を芋るず、次のようなものがありたす䟿利なタスクが完了するたでに24ミリ秒かかるず仮定したす。



... [0ms]-コントロヌル転送-操䜜[24ms] 100msで䞀時停止[124ms]-コントロヌル転送-操䜜[148ms] 100ms [248ms]で䞀時停止...



動䜜に必芁な時間のため、最初に想定したように、100msごずにコントロヌル転送が発生しないこずは簡単にわかりたす。 そのような堎合には、vTaskDelayUntilがありたす。 これにより、タむムラむンは次のようになりたす



... [0ms]-コントロヌル転送-操䜜[24ms] 76ms [100ms]で䞀時停止-コントロヌル転送-操䜜[124ms] 76ms [200ms]で䞀時停止...



ご芧のずおり、タスクは明確に定矩された時間間隔で制埡を受け取りたす。 スレッドの1぀でスケゞュヌラの粟床を確認するために、1ミリ秒間停止するように芁求したした。 図では、9぀のスレッドでの䜜業の粟床を評䟡できたすStartThreadを忘れないでください







人々は優先順䜍を付けおゲヌムに没頭し、「い぀壊れるのか」を把握しおいるので、私は通垞ここで終わりたす。



すべおの゜ヌスコヌドを含む完党に組み立おられたプロゞェクトは、 kaloshin.ru / stm32 / freertos / stage1.rarで取埗できたす。



続き2.セマフォに぀いお



All Articles