Lesson: do not forget put volatile to your hardware register variables.
// In below code "stat" and "tbr" are registers could be updated by hardware
static void helx_serial_putc(const char c)
{
int done = 0;
if ( c == 0xFF ) {
return;
}
while ( done == 0 ) {
if ( stat->bits.txEmpty ) {
tbr->bits.data = c;
done = 1;
}
}
}
// When "stat" is defined as volatile
volatile union uart_stat *stat = (void *)rUART_STAT;
00000000 :
0: e35000ff cmp r0, #255 ; 0xff
4: 012fff1e bxeq lr
8: e59f3024 ldr r3, [pc, #36] ; 34
c: e5931000 ldr r1, [r3]
10: e59f3020 ldr r3, [pc, #32] ; 38
14: e5933000 ldr r3, [r3]
18: e5d12000 ldrb r2, [r1]
1c: e3120040 tst r2, #64 ; 0x40
20: 0afffffc beq 18
24: e5d32000 ldrb r2, [r3]
28: e7c72010 bfi r2, r0, #0, #8
2c: e5c32000 strb r2, [r3]
30: e12fff1e bx lr
// When "stat" is defined as none volatile,
// dead loop assembly code is generated, see offset 0x28
union uart_stat *stat = (void *)rUART_STAT;
00000000 :
0: e35000ff cmp r0, #255 ; 0xff
4: 012fff1e bxeq lr
8: e59f201c ldr r2, [pc, #28] ; 2c
c: e59f301c ldr r3, [pc, #28] ; 30
10: e5922000 ldr r2, [r2]
14: e5933000 ldr r3, [r3]
18: e5d22000 ldrb r2, [r2]
1c: e3120040 tst r2, #64 ; 0x40
20: 15c30000 strbne r0, [r3]
24: 112fff1e bxne lr
28: eafffffe b 28
No comments:
Post a Comment