3

多くの ARM プロセッサには、I/O や RAM でさまざまな形式の読み取り-変更-書き込み操作を可能にする特別な機能が含まれています。ただし、Cortex-M3 および Cortex-M0 デバイスのスペクトル全体で一貫して機能する単一のアプローチはないようです。

MaskedSet32(uint32_t *target, uint32_t mask, uint32_t newval)Cortex-M3 デバイスを対象としていたとき、ロードリンク/比較排他を使用して 32 ビット数値の一部を割り込みセーフな方法でアトミックに変更するようなメソッドをいくつか書きました。ただし、Cortex M0 はこれらの命令を提供しません。コードで割り込み状態を保存し、割り込みを無効にし、読み取り-変更-書き込みを実行し、割り込みを再度有効にすることもできますが、それは少しぎこちないようです。一部の Cortex プロセッサはビット バンディングまたはその他の機能を提供するため、1 つのアトミック メモリ操作を使用して 1 つのビットをアトミックに設定するなどの処理を実行できますが、異なるプロセッサでは処理が異なるようです。さらに、どの抽象化が最高の移植性を可能にするかはわかりません。

MaskedSet32RAM 内のものについては、速度が重要でない場合、最適なアプローチは, Increment, BottomPegI32(のアトミック バージョン)などのサブルーチンを用意することだと思い*dest = (*dest < limit) ? limit : *dest;ます。このようなアプローチは I/O でも使用できますが、一部のプロセッサが提供する特殊なハードウェアを利用しないのは残念なことに思えます。たとえば、Freescale KL-25 は次のような操作を実行できます。

MaskedSet32(&IOWhatever, 0x0F00, 0x0500); // Update bits 8-11 with a value of 0101

特定の I/O アドレスに 5 の値を書き込むことによって。I/O アドレスと他の 2 つのパラメーターをロードしてから、サブルーチンを呼び出して、I/O アドレスと定数をロードし5、単一のメモリ ストアを実行することによって実行できることを実行するのは無駄に思えます。

私が目にするプロセッサ用のデモ コードの多くは、通常のブール演算子を使用しているだけですが、

IoWhatever = (IoWhatever & ~0x0F00) | 0x0500;

メインラインコードが別の部分を書き込んでいる間に、割り込みが I/O アドレスの一部に書き込もうとする状況で。一般的な慣例としてアトミック操作を使用する方がより安全なアプローチのように思えますが、コードをできるだけ停止させないような方法で使用したいと考えています。

uint32_t*アドレス (にキャストされる)、フィールド オフセット、フィールド幅、および新しいデータを受け取る SetIoBitField マクロを定義する必要があります。 (定数に基づいて事前に計算されたマスクを使用)、インラインのロードリンク/ストア排他ループ (同様)、またはプロセッサ固有の特別な I/O 空間への書き込み、または定義して使用する必要がありますそのようなプリミティブを持ち、他のプロセッサで MaskedSet32 を使用するプロセッサでのみそのようなマクロ [ビットフィールドをサポートしていないプロセッサでの I/O ビット割り当てはとにかく異なる傾向があることを理解する]、またはどのアプローチが最も明確で最も移植可能に見えるでしょうか?

4

2 に答える 2

2

標準的で明白なアプローチは、ARM 世代番号に従って条件付きでコンパイルされるようにコードを記述することです。

#if ARM_GEN >= 3
   (use advanced ARM primitives)
#else
   (use clunkier ways to accomplish the same things)
#endif

whereARM_GENはビルドによって定義されます。コードベースが密接にコミュニケーションをとっていない人々によって作業される場合、シンボルが定義されていない場合にコンパイル時に警告またはエラーを提供することは悪い考えではありません:

#ifndef ARM_GEN
 #error Define ARM_GEN as 1, 2, 3, ... 9 of the ARM architecture (ARM3, ARM9, etc.)
#endif
于 2013-03-11T17:51:23.757 に答える
0

プリプロセッサを使用して実装を選択することは、問題を解決するための優れたアプローチです。それでも、この場合、割り込みを無効化/有効化することは、同時実行の問題を処理するための最適な設計パターンではない可能性があります。

お気づきのように、すべての MCU がマスクされた書き込みをアトミックな方法で実行するためのサポートを提供するわけではありません。また、この特定のサポートを使用すると、移植性のないコードが作成されます。ファームウェア設計者として、私は標準化されたパターンを使用するのが好きなので、システムの同じメモリ アドレスで同時実行を削除することが本当に不可能な場合は、mutex や FIFO を使用する必要があります。

システムのレイアウトを変更して、同時実行を回避できると思います。最新のチップには低コストで大量のバイトがあるため、メモリの同時実行はまったく不要です。IO ポートの同時実行は非常に一般的な問題であり、ほとんどの MCU メーカーは IO ステータスを読み取ることなく単一のポート ビットをセット (またはクリア) するためのハードウェア サポートを実装しており、ソフトウェアの同時実行処理の必要性を排除しています。

于 2013-03-11T19:01:55.710 に答える