1

組み込み C を使用して、GPRS 端末用のアプリケーションを作成しようとしています。私の主な問題は、AT コマンドの操作です。シリアル回線を使って AT コマンドを送りますが、ネットワーク指向のコマンドだと応答に時間がかかることがあり、プロセッサが何もせずに待機する時間が長くなります。アイデアは、別のスレッドのように、これを同じ方法で並列に待機させることです。私のシステムはスレッドをサポートしていないため、その方法を知っている人はいますか? 5ミリ秒ごとに呼び出される割り込みがあるため、いくつかのタイマーを使用することを考えていましたが、応答を待機する必要がある秒数がわかりません。割り込みで文字列を比較して、すべてのメッセージが受信されたかどうかを確認すると、非常に非効率的ですよね?

4

3 に答える 3

2

各 mainLoopCycle で packetHandler を呼び出すだけです。
このハンドラーは、シリアル ポートから新しい文字が利用可能かどうかを確認します。

メッセージが完全な場合 (CR LF が検出された場合)、packetHandler は応答メッセージをビットごとに作成し、messageReceive 関数を呼び出します。それ以外の場合は、単に mainLoop に戻ります。

int main()
{
  init();
  for (;;)
  {
     packetHandler();
  }
}

char msgBuffer[80];
int pos=0;
void packetHandler()
{
  char ch;
  while ( isCharAvailable() )
  {
    ch=getChar();
    msgBuffer[pos++] = ch;
    if ( ch == '\n' ) 
    {
       messageReceived(msgBuffer);
       pos=0;
    }
  }
}
于 2012-11-07T09:23:58.747 に答える
2

割り込みを使用するか、データが利用可能になったときに割り込みを行うようにシリアル インターフェイスを構成するか、FreeRTOSなどの RTOS を使用して 2 つのスレッドを実行し、1 つはメイン コード用、もう 1 つはブロックしてシリアル データを待機することができます。

更新: あなたのコメントに基づいて、データのサイズがわからないと言いますが、データを終了するバイトの割り込みハンドラー チェックで問題ありません。これは単純で一般的な例です。 MCU:

void on_serial_char()
{     
  //disable interrupts
  disable_interrupts();

  //read byte
  byte = serial.read();

  //check if it's the terminating byte
  if (byte == END) {
      //set the flag here
      MESSAGE_COMPLETE = 1;
  }

  //add byte to buffer
  buf[length++] = byte;

  //enable interrupts
  enable_interrupts();      
}

メインループでそのフラグを確認します。

...
if (MESSAGE_COMPLETE) {
    //process data
    ...

    //you may want to clear the flag here
    MESSAGE_COMPLETE = 0;

    //send next command
    ...
}    
于 2012-11-07T09:08:02.583 に答える
0

ハードウェアドライバーにかなり近いようです。その場合、最適な方法は DMA を使用することです。MCU がサポートしている場合は、DMA ハードウェアからのフラグを使用して、受信したデータの解析をいつ開始するかを決定します。

2 番目に最適なオプションは、rx 割り込みを使用し、受信したすべてのバイトを循環バッファーなどの単純な FIFO に格納し、それらを受信したらフラグを設定することです。着信データ用に 1 つのバッファーと、受信した最新の有効なデータ用に 1 つのバッファーが必要になる場合があります。

于 2012-11-07T09:40:35.757 に答える