0

実行しているいくつかのタスクでいくつかの問題が発生しています。私には3つのタスクがあります。1つはLCD更新タスクで、他の2つはモータードライバータスクです。また、両方のモータードライバータスクにメッセージを投稿する2つのISRがあります。ポインタを安全に渡す限り、私は構造体を作成することを考えていました。

  typedef struct message{
  enum BUTTON_1 = 0, BUTTON_2 = 1, NO_BUTTON = 3; //button ISR to increase motor drive  
  int timestamp; //A timestamp for the RPM of the motors
  }

今、共有メモリの問題が発生しているので、私は考えていました:

  struct message* update_msg = (struct message*)malloc(sizeof(struct message)); //from here I dont know how to creat an object that fills the space allocated.

次に、キューを介して構造体へのポインタを送信します。

  OSTASKQPOST((void *)(st_size)
  ....
  )

最後に、最後のタスクがメッセージを取得し、メンバー変数を使用して必要な処理を実行した後、メモリの割り当てを解除する必要があります。

  free(st_size)

このようなものはもっともらしいでしょうか?

4

1 に答える 1

2

これは、スレッド間でデータを通信する「スレッド間通信 101」方式です。それはうまくいきます。32 ビット幅のキューを想定すると、構造体アドレスまたはオブジェクト インスタンスをポストすると、メッセージ サイズが大きくなるにつれて (データを値で直接ポストするよりも) すぐに勝ち始めます。

他にもメカニズムがあります。RAM が限られており、メモリ スペースが速度よりも重要な ARM 組み込みプロジェクトでは、255 個のグローバル メッセージ インスタンスの配列をプールとして使用する傾向があります (「無効なインデックス」用に 255 などの 1 つの値を予約しておくと便利です)。 . つまり、各メッセージは 1 バイトだけで参照でき、各メッセージ内の 2 バイトを使用して、リストにリンクしたりリストからリンクしたりできます。リンク リストのヘッド バイト、ミューテックス、およびセマフォは、スレッド間通信用のブロッキング キューを作成します。余分なストレージ スペースは必要ありません。すべてのメッセージは、起動時に「プール」キューにリンクされ、ポップされ、スレッド間でキューに入れられ、アプリ スレッドによってプールに解放されます。

ハードウェアからデータを受信する ISR は、malloc を呼び出したり、ミューテックスを取得したり、セマフォでメッセージ インデックスを待機したりすることはできません。ロックのない、バイト インデックスの循環キューだけの別のキュー クラスを使用します。起動時にいくつかのメッセージをプッシュします。割り込みハンドラーは、この「ISRpool」からメッセージをデキューし、ハードウェアからメッセージを入力し、int (ビットフィールド!) を設定して ISR を識別し、メッセージ インデックスを「ISRout」循環キューにプッシュし、セマフォを通知して、 OS。セマフォで待機しているスレッドが起動し、ISRout にデータがあることを認識し、データをポップして、その ISR からのメッセージを処理するスレッドにキューに入れます。その「ISRhandler」スレッドは、データが到着したときに ISR が常にメッセージを準備できるように、ISRpool にメッセージを「補充」する役割も果たします。この単純な共有 '

同様の方法で、tx ISR のメッセージは、ISR が取得する循環キューにプッシュされます (ハードウェアがアイドル状態であるかどうかを確認するために割り込みが一時的に無効になり、ハードウェア FIFO が tx 割り込みを再びオフにするために「プライミング」を必要とする)。 . 「使用済み」の tx メッセージは、rx ISRpool にダンプされます。入力用に再利用することもできます。

プーリング スキームには、すぐにはわからない利点がいくつかあります。1 つは「malloc なし、フリーなし」です。メッセージは確かに漏洩する可能性がありますが、すぐに気付きます。「モニター/デバッガー」が実行する UART からのターミナル プロンプトは「223>」です。数字はプール レベルです。この数値が下がって元に戻らない場合は、リークしていることがわかります。これは、Valgrind でアプリを実行できない場合に非常に重要です:)

于 2012-04-27T00:17:06.647 に答える