2012-12-14 5 views
0

나는 16 비트 마이크로 컨트롤러 용 C 코드를 작성 중이다. 대상에서 응용 프로그램을 디버깅하면 결국 AddressError ISR이 발생합니다. 데이터 시트를 읽었을 때 홀수 메모리 주소에 정렬 된 16 비트 값을 읽거나 쓰려고하면 이런 일이 발생할 수 있다고합니다. 나는 그것이 의미하는 바를 이해한다고 생각하지만 그것은 옳은 것처럼 보이지 않습니다. 이런 구조체를 만들면 다음과 같은 것을 의미하지는 않습니다 :16 비트 아키텍처에서 주소 오류의 원인은 무엇입니까?

struct foo{ 
    uint8_t thing1; 
    uint16_t thing2; 
}; 

나는 결코 오류없이 thing2를 읽거나 쓸 수 없습니까? 그렇지 않다면, 컴파일러는 자동적으로 1과 2 사이의 8 비트를 덧붙여서 두 번째가 짝수 주소에 올바르게 정렬되도록 할 것입니까? 그렇다면 주소 오류는 어떻게 발생합니까?

+4

질문에 세부 정보를 추가해야 할 수도 있습니다. 그러나 컴파일러의 정렬을 검사하여 16 비트로 정렬되는지 확인하십시오. 정렬을 사용하면 위의 구조체가 작동합니다. – PeterJ

+0

프로세서 설명서를 확인하여 합법적 인 주소를 확인하십시오. 그런 다음 링커 명령 파일을 확인하십시오. – anishsane

답변

0

대부분의 작은 풋 프린트 프로세서는 2 개 이상의 사이클에서 정렬되지 않은 메모리 읽기를 완료해야하고 프로세서의 전체적인 복잡성을 증가시켜야하므로 제한된 메모리 동작 만 허용합니다.

스택 변수와 구조체 멤버가 모두 형식의 기본 너비 (또는 4 또는 8 바이트 중 작은 값)로 정렬되기 때문에이 값은 C 코드에 자주 표시되지 않습니다. 이 속성은 팩키지으로 오버라이드 될 수 있고, 구조체에 대한 포인터를 정렬되지 않은 주소에 재 할당 할 수 있습니다. 따라서 주소 불일치 예외를 쉽게 익힐 수 있습니다.

예를 들면. Intel 8086은 비 정렬 주소에서 16 비트 읽기를 지원했지만 세그먼트 교차 경계 (오프셋 0xffff에 있음)에 액세스 할 때 주소 생성 예외 옵션을 사용할 수있었습니다.

0

아마도 기본 구조 정렬을 변경해야합니다. 코드 또는 컴파일러 옵션에서 pragma를 사용할 수 있습니다. GCC의 경우는이 인스턴스화하는 방법을 따라 -fpack - 구조체 [= N]

0

입니다 :

struct foo{ 
    uint8_t thing1; 
    uint16_t thing2; 
}; 

도 해결에 정렬 될 수 있지만, 컴파일러는 영리가 아닌 경우 충분한 추가 패딩이 없을 것 이상한 주소에있는 물건 2를 수반하는 물건 2 사이에 따라서 오류. 컴파일러가 데이터를 정렬 할 수 있도록 멤버 순서를 변경하거나 컴파일러 설명서 (아마도 일부 전처리 지시문)를 검색하십시오.

관련 문제