一部のソフトウェアを gcc-toolchain から armcc-toolchain に移植しています (プロセッサは同じ (Cortex-A9) のままです)。C コードでは memcpy が使用されます。armcc は、memcpy への呼び出しを __aeabi_memcpy への呼び出しに置き換えます。FAQ では、__aeabi_memcpy について次のように述べています ( ARM コンパイラは memcpy() をどのように処理しますか? )。
多くの場合、memcpy() への呼び出しをコンパイルするときに、ARM C コンパイラは代わりに、特化され最適化されたライブラリ関数への呼び出しを生成します。RVCT 2.1 以降、これらの特殊な関数は ARM アーキテクチャ用の ABI (AEABI) の一部であり、次のものが含まれます。
__aeabi_memcpy
This function is the same as ANSI C memcpy, except that the return value is void.
しかし、私のすべてのケースで memcpy への呼び出しが正常に機能する gcc とは対照的に、armcc では、memcpy への呼び出しはそれぞれ __aeabi_memcpy で継続的にアライメント例外を生成します。一方、memcpy の呼び出しは、送信元アドレスと宛先アドレスが 4 バイトで整列されていない呼び出しを処理できることがわかりましたが、両方とも 4 バイトで整列されていない場合に限ります。例えば:
volatile uint32_t len = 10;
uint8_t* src = (uint8_t*)0x06000002; // 2-byte aligned
uint8_t* dst = (uint8_t*)(0x06000002 + 20); // 2-byte aligned
memcpy(dst, src, len);
動作します。しかし、例えば:
volatile uint32_t len = 10;
uint8_t* src = (uint8_t*)0x06000002; // 2-byte aligned
uint8_t* dst = (uint8_t*)(0x06000002 + 22); // 4-byte aligned
memcpy(dst, src, len);
アライメント例外が発生します。タイプ uint8_t* のポインターを使用しているため、コンパイラーに、アドレスが任意のアライメントを持つことができることを明示的に伝えます。しかし、明らかに、この __aeabi_memcpy はアライメントのすべての組み合わせを処理できるわけではありません。この問題を解決するにはどうすればよいですか (できれば、既存のコードで memcpy のすべての呼び出しを変更せずに、ユーザー固有のバージョンの memcpy を使用します)。手伝ってくれてありがとう。