私はGPIOの直接制御を使用して何かをコーディングしていますが、http://elinux.org/RPi_Low-level_peripherals#GPIO_hardware_hackingのような、このための優れたリソースがいくつかあります。このプロセスにはopen( "/ dev / mem")が含まれ、次にmmap操作が目的の物理アドレスを仮想アドレス空間に効果的にマッピングします。次に、このhttp://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdfのセクション6を読み、I / Oがどのように制御されるかを確認します。
ピンの機能(入力、出力、またはさまざまな特殊機能)に変更するには、GPFSELx I / Oレジスタのこれらの3ビットフィールドを変更します(000 =入力、001 =出力敵インスタンス)。これらの変更操作は、通常の読み込みと保存を伴う操作にコンパイルされます(たとえば、GPIO0を入力に変更するには:*(regptr)&=〜7;これは、次のようにコンパイルされます
ldr r2, [r3, #0] ; r = *ptr (load r2 from I/O register)
bic r2, r2, #7 ; r2 &= ~7
str r2, [r3, #0] ; *ptr = r2 (store r2 to I/O register)
問題はこれです。ロードとストアの間に割り込みが発生し、別のプロセスまたはISRが同じI / Oレジスタを変更すると、ストア操作(r2への古い読み取りに基づく)が他の操作の影響を元に戻します。したがって、これらのI / Oレジスタを変更するには、アトミックな(ロックされた)読み取り/変更/書き込み操作を行う必要があります。私が見た例では、ロックされた操作を使用していません。
これらのI / Oレジスタは通常、何かを設定するときにのみ変更されるため、問題が発生する可能性はほとんどありませんが、「決してない」より「常にない」の方が常に優れています。また、オープンコレクター出力をエミュレートするためにビットバッシングしているアプリケーションがある場合、(私が知る限り)これには、出力を0にプログラミングしてから、出力(低)または入力(オフ/高)。したがって、その場合、これらのI / Oレジスタに頻繁に変更が加えられ、安全でない変更が問題を引き起こす可能性がはるかに高くなります。
それで、おそらくこれを行うためにここで使用できるARMの「比較して設定」または同様の操作があるでしょう、誰でも私にそれを指摘できますか、そしてそれをCコードから実行する方法は?
[注、I / Oを出力としてプログラムし、それを0から1に、またはその逆に変更するだけの場合、特別なことは必要ありません。書き込みを行うI / Oレジスタがあるため、選択したビットを1に設定し、別のビットを0にクリアします。この操作に読み取り/書き込みは必要ないため、割り込みによる危険はありません。
/dev/mem
ているので、あなたのコードはユーザースペースコードのようです。最近のOSでは、ユーザー空間コードのレジスタ値を変更する割り込みに注意する必要があるとは思いません。Linuxは割り込みハンドラーがその仕事を終えたときにすべてのレジスターを復元するので、これはカーネル空間コードでも問題ではないと私は信じています。