I have a volatile struct/bitfield for a memory mapped register on an ARM processor. The particular peripheral must be accessed by words.
struct
{
unsigned field1 : 1;
unsigned field2 : 3;
unsigned field3 : 4;
unsigned : 24;
} volatile my_variable __attribute__((section(".bss.my_periph")));
ARM Compiler V5 generates 32-bit accesses. ARM Compiler V6 is smart enough to see that only field2 has changed and generates 8-bit accesses. These 8-bit accesses break the world.
Is there a way to ensure that accesses are done by word?
I expect that something like this would work, but I would rather avoid the union:
union
{
struct
{
unsigned field1 : 1;
unsigned field2 : 3;
unsigned field3 : 4;
unsigned : 24;
} fields;
unsigned word;
} volatile my_variable __attribute__((section(".bss.my_periph")));
I found that the following works to force word-wise reads and writes.
Structure:
union my_type
{
struct
{
unsigned field1 : 1;
unsigned field2 : 3;
unsigned field3 : 4;
unsigned : 24;
} fields;
unsigned word;
} volatile my_variable __attribute__((section(".bss.my_periph")));
Read:
union my_type my_type;
my_type.word = my_variable.word;
return my_type.field2;
Write:
union my_type my_type = {0};
my_type.field3 = 5;
my_variable.word = my_type.word;
Read, Modify, Write:
union my_type my_type;
my_type.word = my_variable.word;
mytype.field2 = 7;
my_variable.word = my_type.word;