Reputation: 25
Someone asked me recently to see what is wrong in the following code and how should I fix it:
// Memory-mapped peripheral
#define STATUS_REG_ADDR 0x12345678 // 32-bit status register
#define DATA_REG_ADDR 0x1234567C // 32-bit data register
// Status register bits
#define BUSY_BIT_MASK 0x00000080 // Busy bit == '1' while peripheral busy
uint32_t get_value()
{
while (((*(uint32_t*)STATUS_REG_ADDR) & BUSY_BIT_MASK) == 1)
;
return *(uint32_t*)DATA_REG_ADDR;
}
I never did something similar before, so I tried to run it in an IDE and I saw that the return statement gives a segmentation fault, but I don't know how to explain it and if there something more wrong.
Upvotes: 2
Views: 291
Reputation: 4115
Problem is in while
loop condition.
Your BUSY_BIT_MASK
is 0x00000080. Anything ANDed with 0x80 will not be equal to 1 as it's LSB is 0. Anything ANDed with 0 is always 0.
You have to modify the condtion as
while (((*(uint32_t*)STATUS_REG_ADDR) & BUSY_BIT_MASK) == BUSY_BIT_MASK)
So that when the flag is set, it will be ANDed with 0x80 and output will be 0x80. (1 AND 1 = 1)
You are getting SegFault because the addresses you are considering are not valid on your computer. You have to take valid addresses. You are trying to access random memory or memory address which may not exist - that is reason for SegFault.
Upvotes: 4