The short answer is yes, the GCC compiler is capable of detecting some unaligned accesses during compilation for Cortex-M0 and other ARM Cortex-M processors. However, the level of unaligned access detection during compilation depends on the specific compiler version and optimization flags used.
In general, newer versions of GCC have improved unaligned access detection. And using higher optimization levels like -O2 enables more extensive unaligned access checks during compilation. So using GCC version 5 or above with -O2 is recommended for best unaligned code detection on Cortex-M.
Background on Unaligned Accesses
Unaligned accesses refer to memory reads or writes that are not aligned to their natural boundary. For example, a 32-bit integer read from an address that is not 4-byte aligned. Unaligned accesses are generally inefficient and can cause faults or unexpected behavior on some processor architectures like Cortex-M0.
The Cortex-M0 and Cortex-M0+ processors do not support unaligned accesses by default. Any unaligned memory access will cause a hard fault on these CPUs. Other Cortex-M cores like Cortex-M3 and M4 have configurable unaligned support, but unaligned accesses still incur a performance penalty.
Thus it is best practice to avoid unaligned accesses in code for Cortex-M whenever possible. Using compilers that can detect and prevent such accesses during compilation helps enforce proper memory alignment.
Unaligned Access Detection in GCC
The GCC compiler suite for ARM Cortex-M provides some unaligned access detection during compilation. This can help catch alignment issues early during build time rather than relying on runtime faults.
GCC unaligned handling depends on the specific compiler version and optimization flags used. Older GCC versions had limited unaligned detection. But newer releases have enhanced checks using optimization passes like -fstrict-align and -Wstrict-align.
Enabling higher optimization levels improves unaligned handling in GCC. The -O1 level only does basic detection. The -O2, -O3, and -Os levels enable much more extensive unaligned access checks during compilation.
Unaligned Access Detection Examples
Here are some examples to demonstrate GCC unaligned access detection during compilation on Cortex-M0: unsigned int *ptr = (unsigned int*)0x1000; //ptr not 4-byte aligned int val; val = *ptr; //Unaligned read – causes hard fault at runtime //GCC will warn about this with >= -O2 *ptr = 1; //Unaligned write – Fault at runtime //GCC warns this unaligned write with -O2 struct s { char a; int b; }; struct s *sptr = (struct s*)0x1000; //sptr not aligned to struct sptr->b = 1; //Unaligned struct member access //GCC warns about improper struct member alignment
With GCC version 5 or newer and optimization level -O2, both of these examples will generate compile time warnings about unaligned accesses. This helps catch misaligned code early during compilation.
Debugging Align Issues in GCC
When GCC detects an unaligned access, it will print a warning message during compilation on Cortex-M0: warning: unaligned access to 0x1000, expected alignment 4 [-Wunaligned-access]
The warning gives the target address and expected alignment. This points exactly to the unaligned access source line.
To debug align issues, turn on strict alignment checking if supported by your GCC version: gcc -O2 -Wstrict-align -fstrict-align …
This enables the strictest unaligned handling in GCC to catch all possible alignment problems during compilation.
Also make sure to correct any alignment issues flagged by the compiler before moving to runtime testing. This will help avoid hard faults or unexpected behavior.
GCC Versions and Flags for Unaligned Detection
Here are some general guidelines for compiler versions and optimization flags to get the best unaligned access detection with GCC:
- Use GCC 5.0 or newer whenever possible
- Enable optimizations with -O2 or higher
- -Os enables good unaligned checking for size-optimized code
- Avoid -O0 or -O1 as unaligned handling is limited
- Enable strict alignment flags like -Wstrict-align if available
So a compilation command like: gcc -O2 -Wstrict-align -fstrict-align test.c -o test
Will rigorously check for unaligned accesses during compilation on Cortex-M0. This applies to the ARM GCC toolchains like GNU Arm Embedded Toolchain, Arm Compiler 6, etc.
Unaligned Access Prevention
Detecting unaligned accesses during compilation is the first step. But the compiler can also rewrite code to prevent such accesses automatically in some cases.
GCC may use alignment safe access functions like __unaligned_read32() to read 32-bit values properly. Or pad structs to maintain member alignment.
Manual rewriting can also enforce alignment, for example by packing all struct members to their natural boundaries. Padding variables in arrays can enforce alignment.
Inline assembly can be used to directly generate aligned loads and stores. But compiler-driven methods are preferred for ease of maintenance.
Runtime Unaligned Detection
Compiler-based checking during build helps find alignment issues early. But runtime detection is also useful as a failsafe.
For Cortex-M0, any unaligned access will fault. So runtime detection occurs by default. The fault handler can report unaligned access source addresses.
Other Cortex-M cores like Cortex-M3/M4 allow aligned access. For these, the Memory Protection Unit (MPU) can be configured to generate a fault on unaligned access. MPU fault handling and reporting provides runtime detection.
Some compilers like Arm Compiler 6 also support inserting explicit runtime alignment checks that will catch any accesses the compiler cannot prove as aligned.
Conclusion
In summary, the GCC compiler provides useful unaligned access detection during compilation for Cortex-M processors. This is supported by using GCC version 5 or newer with mid to high optimization levels like -O2.
Compiler-based checking combined with runtime fault handling provides robust unaligned handling. Catching misalignment early during build and runtime reduces defects and faults in Cortex-M applications.