私は物事を複雑にしていますか?
私は、8051マイクロからUARTを介して周辺機器と通信するようにコードを設計しています。周辺機器はホストからのコマンドに応答し、一度に1つのコマンドにしか応答できません。これは単純な送受信プロトコルです。(tx1、rx1、tx2、rx2、tx3、rx3)各TXメッセージはCRで終了し、各応答は>で終了します。最後のメッセージへの応答を受信するまで、新しいメッセージを送信できません。そのオプションを有効にすると、応答は最初に元のTXメッセージをエコー印刷することもできます(ただし、これによりトラフィックが増加します)
メッセージの例は次のとおりです。
- TX:こんにちは
- RX:ワールド!>
またはエコーオプション付き...
- TX:こんにちは
- RX:こんにちは\ rWorld!>
オプション AgetHelloなどの関数は、送信と受信の両方で構成されます。並列ISRルーチンは、着信バイトを収集し、「>」文字を受信するとフラグをスローします。
char* getHello(char * buf){
sendMsg("Hello\r");
delay(10ms); //wait a little bit
//wait for receive to come in or timeout to occur
while(!receiveFlag || !timeoutFlag); //thrown by ISR
receiveMsg(buf);
//parse the message and do some other stuff
return buf;
}
長所:
- すべてが1つの関数に含まれています。
- デバッグが簡単
短所:
- この関数はブロックされており、ペリフェラルが応答しない場合はハングする可能性があるため、タイムアウトを実装する必要があります。
- メッセージは順不同で受信できません。直列である必要があります(つまり、tx1、rx1、tx2、rx2、tx3、rx3)
オプションB 並列アプローチが採用されています。2つの別々の関数が作成されます。1つはメッセージを送信するためのもので、もう1つはISRからの応答を受信したときに頂点に達するものです。
void sendHello(){
sendMsg("Hello\r");
//do some other stuff if needed
}
char* receiveMsg(char * buf){
//figure out from echo print what the tx message was
//use a switch statement to decide which response parser to call
switch(txMessage){ //pseudo code
case "Hello":
receiveMsg(buf);
//parse the message and do some other stuff
break;
}
return buf;
}
長所:
- 解析方法を理解するためにtxメッセージのエコー印刷に依存しているため、順序が狂って戻ってくる並列メッセージを処理できます。(すなわち、tx1、tx2、tx3、rx1、rx2、rx3)
短所:
- デバッグが非常に難しい
- 複数のスレッドを生成します
- たくさんの余分なコード
- メッセージは間違いなく順番に戻ってくるので、それだけの価値はありません
現在、オプションBを行っていますが、プロジェクトを続けるうちに、これが非常に複雑になっているように感じ始めます。私はあなたたちがどう思うか興味があります。
ありがとう!