horatiu11
horatiu11

Reputation: 25

C memory address - what is wrong with the code?

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

Answers (1)

Swanand
Swanand

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

Related Questions