2014-03-03 3 views
0

다음과 같은 문제가 있습니다. 좀 더 효율적인 방법으로 컨트롤러 메모리의 일부를 매핑하는 데 도움이되는 몇 가지 기본 구조체를 정의하려고합니다.익명으로 선언하는 방법

typedef struct 
{ 
    ICR1_t  ICR1_dByte; /* 0x46 - 0x47 */ 
    OCR1B_t  OCR1B_dByte; /* 0x4A - 0x4B */ 
    OCR1A_t  OCR1A_dByte; /* 0x48 - 0x49 */ 
    TCNT1_t  TCNT1_dByte; /* 0x4C - 0x4D */ 
    TCCR1B_t TCCR1B_Byte; /* 0x4E */ 
    TCCR1A_t TCCR1A_Byte; /* 0x4F */ 
    uint8_t  Filler[8];  /* 0x50-0x57 */ 
    TIFR1_t  TIFR1_Byte; /* 0x58 */ 
    TIMSK1_t TIMSK1_Byte; /* 0x59 */ 
}Timer1_str; 

사용 정의 : 내가 당신에게 예를 제시하자 TIMER1_START_ADDRESS이

(uint8_t *)&ICR1 

으로 정의된다

#define TIMER1str (*(volatile Timer1_str *)(TIMER1_START_ADDRESS)) 

이 (ICR1 기본 정의의 일부, 일부 주소, 그건 신경 쓰지 마라)

그래서 나의 특별한 질문은 0x50-0x 아래에있는 메모리의 간격을 채우는 방법이다. 57 주소? 현재 솔루션에서 변수 "필러는"모든 자동차 보수 도구에서 볼 수 있습니다, 그래서 필드 호출 할 수 있습니다 :

TIMER1str.Filler[0] = 0xAA; 

내가 그 필러의 구현을 숨길하고자합니다. 내 첫번째 생각은 다음과 같이 익명 조합 등이 필러 구현하는 것이 었습니다 :

... 
    TCCR1A_t TCCR1A_Byte; /* 0x4F */ 
    union { Filler[8]; };  /* 0x50-0x57 as anonymous */ 
    TIFR1_t  TIFR1_Byte; /* 0x58 */ 
.... 

을하지만이 솔루션은

어떻게 멤버를 구성 숨길 수 ... 작동하지 않습니다? 메모리를 설정해야하지만 액세스 할 수 없어야합니다.

답변

0

C는이 기능을 지원하지 않습니다. 익명의 중첩 구조체와 공용체는 멤버를 숨기지 않고 포함하는 클래스의 멤버 인 것처럼 멤버에 액세스 할 수 있습니다. 즉 컴파일러에 의해 지원되는 경우

하나의 가능성은 C++ 컴파일을 사용하는 것입니다 : 당신은 AVR을 코딩하는 것처럼

struct Timer1_str 
{ 
    public : 
     ICR1_t  ICR1_dByte; /* 0x46 - 0x47 */ 
     OCR1B_t  OCR1B_dByte; /* 0x4A - 0x4B */ 
     OCR1A_t  OCR1A_dByte; /* 0x48 - 0x49 */ 
     TCNT1_t  TCNT1_dByte; /* 0x4C - 0x4D */ 
     TCCR1B_t TCCR1B_Byte; /* 0x4E */ 
     TCCR1A_t TCCR1A_Byte; /* 0x4F */ 
    private : 
     uint8_t  Filler[8];  /* 0x50-0x57 */ 
    public : 
     TIFR1_t  TIFR1_Byte; /* 0x58 */ 
     TIMSK1_t TIMSK1_Byte; /* 0x59 */ 
} ; 
+0

모든 Cpp 컴파일러는 구조의 데이터가 입력 순서대로 직접 위치한다는 것을 보장합니까? – Tomas

+0

@ user2759473 : 좋은 질문입니다. 예, 그렇습니다. 그러나 포장 및 정렬은 다를 수 있습니다. 컴파일러의 패킹 지시문을 사용하는 것이 좋습니다. 결국 칩 또는 컴파일러 벤더는 주변 레지스터 액세스를 정의하는 헤더를 거의 확실하게 제공 할 것이며 duskwulf가 지적했듯이 이는 아마도 더 나은 솔루션 일 것입니다. – Clifford

2

것 같습니다.

이 작업을 수행하지 마십시오. 컴파일러에서 제공하는 이러한 레지스터의 정의를 사용하십시오.

작성된 것처럼 코드는 Timer1_str 구조가 시스템 메모리의 일부 위치에 링커가 결정하도록 지정합니다. 추가 지원이 없으면이 구조는 SRAM에 매핑되어 특수 효과가 발생하지 않으므로이 코드는 작동하지 않습니다. 링커를 사용하여이 구조를 적절한 주소에 매핑해도 (가능할 수도 있고 가능하지 않을 수도 있음) 컴파일러에서 작업하도록 생성 된 코드는 INOUT 명령어를 사용할 수 없기 때문에 차선책입니다. 이러한 레지스터를 조작합니다. 이러한 명령어를 생성하려면 컴파일 할 때 쓰여지는 주소를 알아야합니다. 또한 컴파일러는 이러한 레지스터에 적절하게 액세스하지 않는 코드를 생성 할 수 있습니다. 예를 들어 잘못된 순서로 TCNT에 쓰기를 생성 할 수 있습니다.

+0

+1 ... 예를 들어 AVR libc에는 [] (http://www.nongnu.org/avr-libc/user-manual/group__avr__io.html) – Clifford

+0

안녕하세요, 사실 AVR 용으로 언급 한 것은 맞습니다. 그러나 AVR 개발자가 우리에게 제공하는 솔루션에 대한 래퍼였습니다. 실제로이 질문은 일부 주소를 "건너 뛸"수있는 다른 구조체 내부의 익명화 된 공용체/배열을 정의하는 실제적인 접근에 훨씬 더 중점을 두었습니다. – Tomas