The Arm compiler normally uses a base register plus the immediate offset field to compile struct members or specific array element accesses. The immediate offset is available in the load or store instructions.
In the Arm instruction set,
STR word and byte instructions have a 4KB range, but
STRH instructions have a smaller immediate offset of 256 bytes.
Equivalent 16-bit Thumb instructions are much more restricted.
STR have a range of 32 words,
STRH have a range of 32 halfwords, and
STRB have a range of 32 bytes. However, 32-bit Thumb instructions offer a significant range improvement. Because of the range restrictions, it is important to group related peripheral registers near to each other if possible. The compiler is generally good at minimizing the number of instructions required to access array elements or structure members. To perform these accesses, the compiler uses base registers.
You can choose between using one large C
array for the whole I/O space and smaller per-peripheral structs. For the two methods, there is little difference in terms of code efficiency. Using a large
struct might help if:
- For word and byte accesses, your code works with a base pointer with a 4KB range.
- Entire I/O space is <4KB.
But arguably it is more elegant to have one
struct per peripheral. Smaller, per-peripheral
structs are more maintainable.