ARMマイコンでは、命令実行を効率化する為にCPU内部ハードウェアレベルで、命令実行の入れ替えを行っている。
従って、命令を記述した順番に命令実行やデータアクセスが必ずしも実行されない。特に、IOレジスタ操作などで実行順番が重要な場合には注意が必要。
尚、このような効率化はARMマイコンに限らず最近の高性能CPUでは当たり前に使われている技術。
ARMにはこのような事象に対処する為に、下記の命令を備えている。
下記、ルネサスのサンプルプログラムから抜粋。
/******************************************************************************* * Outline : initializing Cortex-M3 settings * Function Name: init_cm3 * Description : Initialize Cortex-M3 settings of RZ/T1. Copy the Cortex-M3 code * Arguments : none * Return Value : none *******************************************************************************/ void init_cm3( void ) { volatile unsigned char *p_org; volatile unsigned int psize; unsigned char *p; /* Copy the Cortex-M3 program code */ p =(unsigned char *)( 0x04000000+0x0 );// M3 RAM start address for Cortex-R4 p_org = __section_begin("CM3_SECTION"); psize = __section_size("CM3_SECTION"); memcpy(p, (char *)p_org, psize); asm("dsb"); // Ensuring data-changing /* Release the Software reset 2 (Cortex-M3) */ R_RST_WriteEnable(); asm("isb"); // Ensuring instruction-changing SYSTEM.SWRR2.LONG = 0x00000000; // Release Software reset 2 asm("isb"); R_RST_WriteDisable(); }
__DSB()
__ISB()
などのようにコンパイラ組み込み関数を利用しても記述できる。(#include <intrinsics.h>
が必要)DSB
命令などを使わずに、該当レジスタのダミーリードで記述してある例もある。(多少、命令の処理速度が速くなる為と思われる)