For peripheral register, we usually define bitfield data struct for
its elements, and define a global variable which use a pointer point
to the base address.
but sometimes peripheral register can only be read, write by 32 bit
format, so we need avoid compiler to generate bit field access instruction.
below is a example:
Code:
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint32_t;
typedef struct UART_CFG_REG
{
volatile uint32_t a : 16;
volatile uint32_t b : 8;
uint32_t c : 8;
} UART_CFG_REG_T;
#define FUART_CFG_REG (*((UART_CFG_REG_T *)0x40010000))
int main(void) {
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
FUART_CFG_REG.a = 0x1234;
FUART_CFG_REG.b = 0x1;
return EXIT_SUCCESS;
}
compiler generate bit field instruction as below:
00300004 <main>:
300004: fc 00 push25 $r6,#0 ! {$r6, $fp, $gp, $lp}
300006: 3e 0f ff e4 addi.gp $r0,#-28
30000a: 49 00 00 45 jal 300094 <puts>
30000e: 46 04 00 10 sethi $r0,#0x40010
300012: 44 10 12 34 movi $r1,#0x1234
300016: ac 40
shi333 $r1,[$r0+#0x0] 300018: 84 21 movi55 $r1,#0x1
30001a: ae 42
sbi333 $r1,[$r0+#0x2] 30001c: 84 00 movi55 $r0,#0x0
30001e: fc 80 pop25 $r6,#0 ! {$r6, $fp, $gp, $lp}
to avoid the half word, byte access, we add a compiler option:
-fstrict-volatile-bitfields as below:
Attachment:
bitfield-option.png [ 63.45 KiB | Viewed 15318 times ]
compiler generate word access instrction as below:
00300004 <main>:
300004: fc 00 push25 $r6,#0 ! {$r6, $fp, $gp, $lp}
300006: 3e 0f ff dc addi.gp $r0,#-36
30000a: 49 00 00 51 jal 3000ac <puts>
30000e: 46 14 00 10 sethi $r1,#0x40010
300012: b4 01 lwi450 $r0,[$r1]
300014: 92 10 srli45 $r0,#0x10
300016: 40 00 40 08 slli $r0,$r0,#0x10
30001a: 58 00 12 34 ori $r0,$r0,#0x1234
30001e: b6 01
swi450 $r0,[$r1] 300020: b4 41 lwi450 $r2,[$r1]
300022: 46 0f f0 0f sethi $r0,#0xff00f
300026: 50 00 0f ff addi $r0,$r0,#0xfff
30002a: fe 16 and33 $r0,$r2
30002c: 44 21 00 00 movi $r2,#0x10000
300030: fe 17 or33 $r0,$r2
300032: b6 01
swi450 $r0,[$r1] 300034: 84 00 movi55 $r0,#0x0
300036: fc 80 pop25 $r6,#0 ! {$r6, $fp, $gp, $lp}