2
最速のポーリングループ-1 CPUサイクルをトリミングするにはどうすればよいですか?
ARM Cortex M3(STM32F101と同様)のリアルタイムアプリケーションでは、内部ペリフェラルのレジスタのビットをゼロになるまでポーリングし、ループをできるだけタイトにします。ビットバンディングを使用して適切なビットにアクセスします。(動作する)Cコードは while (*(volatile uint32_t*)kMyBit != 0); そのコードは、オンチップ実行可能RAMにコピーされます。手動で最適化した後²、ポーリングループは次のようになり、6サイクルに設定しました。 0x00600200 681A LDR r2,[r3,#0x00] 0x00600202 2A00 CMP r2,#0x00 0x00600204 D1FC BNE 0x00600200 ポーリングの不確実性をどのようにして下げることができますか?5サイクルのループは私の目標に適合します。ゼロになった後、同じビットを15.5サイクルにできるだけ近づけてサンプリングします。 私の仕様では、少なくとも6.5 CPUクロックサイクルの低パルスを確実に検出することを求めています。持続時間が12.5サイクル未満の場合、確実に短いと分類します。そして、それが18.5サイクル以上続く限り、確実に分類します。パルスには、CPUクロックとの位相関係が定義されていません。これは、私の唯一の正確なタイミング基準です。これには、最大で5クロックのポーリングループが必要です。実際、私は5クロックサイクルでポーリングできる数十年前の8ビットCPUで実行されるコードをエミュレートしており、それが仕様になっています。 ループの前にNOPを挿入することでコードアライメントをオフセットしようとしましたが、多くのバリエーションで試しましたが、変化は見られませんでした。 CMPとLDRを反転させようとしましたが、それでも6サイクルが得られます。 0x00600200 681A LDR r2,[r3,#0x00] ; we loop here 0x00600202 2A00 CMP r2,#0x00 0x00600204 681A LDR r2,[r3,#0x00] 0x00600206 D1FC BNE 0x00600202 これは8サイクルです 0x00600200 681A LDR …