回路とかfirmwareとかのポエムです.
わたしは仕様をかっちり決めてする仕事じゃなくても歓迎します.
だってさぁ、仕様をかっちり決めれる人がその組織に居るのは稀ですから.仕様を決めれるというのはとても偉いことで、諸般の事情の全てを網羅的に理解している聖人が居るということですから、その人さえ居れば「開発フェーズはほぼ終了」と言えてしまう.
現実は、作るべき仕様を誰も思い描いてすらいない状況に放り込まれて「何か考えるからそれを元に考えてみてよ」という身の処し方になります.
微修正で済む要求なら「わかりましたやります」で良いんですが、デバイス変更不可避みたいな要求だと「このversionだと入れれないので次の試作で入れますわ」とかいう交渉になります.あと「PC側でやってもらいましょうかね」というのもよくある.
でもそうゆう仕事をしていると、だんだん仕様が膨れてゆくんですよね.
・LPFを2種切り替えにする →3種類にしてくれ
・サンプリング周波数は3kHz →300Hzと3kHzの2本建て
・制御信号の本数がどんどん増える →MBDやCNの極数が爆増する
いま設計してる装置もご多分に漏れず制御爆発の配線爆発でCPUのpin数が足りなくなりました.MBDも両面基板では済まなくなり4層基板が必須になってしまう面倒な成り行き.
そこでローカルにSUB-CPUを載せて、MAIN-CPUからSUB-CPUをUARTで制御することにしました.UARTなら配線は2本で済みます.いま、MAIN-SUB間の通信を開通させてるところです.
BOX内部の制御ですから、SPIかI2Cを使うのが普通でしょうけど、SPIとかI2Cって信号で軽くhandshakeしているでしょ.あれがかえってめんどくさいので敬遠しちゃいます.SPIの先にSLAVEが存在しないと(PCBを挿さないと)がっつんとDMAがhang-upしちゃったりするので面倒なんですなぁ.だから撃ちっ放しでもOKなUARTが好きなわたしです.
MAIN-CPUからUARTに10BYTEsぐらいのコマンドを送信します.
コマンド1→10mSec→コマンド2→10mSec→コマンド3
みたくバババッと送信します.なお115200bps.
ところがSUB-CPUのUART受信がかなりの頻度でロストするんです.
なんでロストしているのか?
あまり好きじゃないのですけど、STM32のUART受信の作法は、1BYTE受信したら割込みをかけてもらいます.
↓1BYTE受信起動のおまじない
HAL_UART_Receive_IT( &huart, &rxbyte, 1 )
↓受信割込みはこのcallbackに飛んできます.
HAL_UART_RxCpltCallback()
このやり方をあまり好きじゃない理由は、BYTE毎に割込みは忙しすぎる気がするから.
115200bpsで1BYTEに要する時間は100uSecぐらいですから割込み激しいよね.
それはさておき、、、受信callbackでする処理は、今は実験なので、
・とりあえずBYTE毎にbufferに積む
・end delimiter(CR)が来たらechobackする
という簡単動作なのですが、10BYTEsをechobackしてると当然100uSecを超えちゃってロストします.
割込み内でechobackしないでmain()でechobackするようにしてもbufferが上書きされちゃうので死亡.
DMAでechobackすればすぐに返ってくるけど、DMA中に次のDMAを起動するわけにはいかないのでready待ちするのなら、blocking関数でechobackしたって同じじゃんと思うのでDMAは使わない.
などと諸事情があり、受信callbackではコマンドラインをキューに積むだけにして、main()でごゆるりとキューを消化させるようにしました.それで円満に動くようになりました.
あと、UART受信callbackの割込み優先度は高くしといた方がいいですね.
ちなみに、SUB-CPUはSTM32G030F6P6です.小さくていいです.しかしFLASHが32kBしかないので、debug modeだとFLASH占有70%ぐらいになっていて、release modeにしてサイズを半減させてます.これからI2Cを追加するのでまさかの容量不足にならんだろうなぁという予感に怯える.....
かしこ