2016-12-02 1 views
2

누군가가 다음 코드에서 어떤 문제가 있는지보기 위해 최근에 나에게 물었다 방법은 내가 해결해야C 메모리 주소 - 코드에 어떤 문제가 있습니까?

// 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; 
} 

내가 전에 비슷한 일을 결코하지 않았다, 그래서 나는 IDE에서 그것을 실행하려고 나는 그 보았다 return 문은 세분화 오류를 제공하지만 설명하는 방법과 더 잘못된 것이있는지를 알지 못합니다.

+0

실행중인 모든 컴퓨터에서 해당 주소를 읽을 수 있습니까? (아키텍처에 특정한 이유로 인해서 하드 코딩 된 주소입니까?) 또한 해당 비트가 설정되어 있으면 'x & 0x80'이 (가) '0x80'이 아니며,이 비트가 지워지면 '0'이되지 않습니까? (그리고 결코 '1'과 동일하지 않습니다.) – e0k

+0

그래서 며칠 전에 얻은 도전과 같았습니다. 그리고 나는 정말로 그것을 대답하는 방법을 몰랐다. 그래서, 나는 아마도 그러한 코드를 가지고 왜 일반적으로 무엇이 잘못 되었는가, 그리고 왜 그런지 묻고있다. – horatiu11

+1

[mcve] – sigjuice

답변

4

문제는 루프 상태 인 while입니다.

BUSY_BIT_MASK은 0x00000080입니다. 이 LSB가 0과 AND 연산 0 뭐든지 항상 0

하다의로 0x80으로와 AND로 아무것도 1로 동일하지 않습니다 당신은

while (((*(uint32_t*)STATUS_REG_ADDR) & BUSY_BIT_MASK) == BUSY_BIT_MASK) 

로 condtion을 수정해야 그래서 플래그가 설정 될 때, 그것은 0x80과 ANDed 될 것이고 출력은 0x80이 될 것입니다. (1 AND 1 = 1)

고려중인 주소가 컴퓨터에서 유효하지 않기 때문에 SegFault가 표시됩니다. 유효한 주소를 가져야합니다. 임의의 메모리 또는 존재하지 않을 수도있는 메모리 주소에 액세스하려고합니다. 이것이 SegFault의 이유입니다.

+0

답장을 보내 주셔서 감사합니다. 나는 지금 무슨 일이 일어나고 있는지 이해한다. – horatiu11

관련 문제