#include <stdio.h>
#define BASE ((struct SMART *)0x12FF60)
struct SMART { int A; int B; int C; int D; };
int main() { int array[4] = {0x11, 0x22, 0x33, 0x44}; int *ip = array; struct SMART *ssp; printf(" int[] : %X\t%X\t%X\t%X\n", array[0], array[1], array[2], array[3]); printf(" *int : %X\t%X\t%X\t%X\n", *(ip+0), *(ip+1), *(ip+2), *(ip+3));
ssp = (struct SMART *)array;
printf("*struct : %X\t%X\t%X\t%X\n", ssp->A, ssp->B, ssp->C, ssp->D);
printf("Address of array : %p\n", array); printf("((struct SMART *)0x12FF60)->A : %X\n", ((struct SMART *)0x12FF60)->A); // 쌩 주소를 주소값으로 인식->*형으로 CASTING printf("((struct SMART *)0x12FF60)->B : %X\n", ((struct SMART *)0x12FF60)->B); printf("((struct SMART *)0x12FF60)->C : %X\n", ((struct SMART *)0x12FF60)->C); printf("((struct SMART *)0x12FF60)->D : %X\n", ((struct SMART *)0x12FF60)->D);
printf("BASE->A : %X\n", BASE->A); printf("BASE->B : %X\n", BASE->B); printf("BASE->C : %X\n", BASE->C); printf("BASE->D : %X\n", BASE->D);
return 0; }
위의 소스에서 구조체 int형 배열 array와 구조체 struct SMART의 포인터 ssp를 선언했는데,
ssp = (struct SMART *)array;
와 같이 형변환하여 ssp에 array의 시작주소를 대입해주었다.
struct SMART { int A; int B; int C; int D; }; int array[4] = {0x11, 0x22, 0x33, 0x44};
구조체 struct SMART는 각 멤버가 모두 int형으로 int형 배열과 같은 크기의 자료형을 가진다. 그러므로, 구조체 포인터 ssp에 배열의 시작주소를 대입하면 구조체 멤버에 접근하는 방식으로(ssp->A) 각 배열요소에 접근할 수 있다.
printf("*struct : %X\t%X\t%X\t%X\n", ssp->A, ssp->B, ssp->C, ssp->D);
여기서 더 나아가서, array의 시작주소를 printf()로 출력하여 알아본 후, printf("Address of array : %p\n", array);
메모리 주소에 구조체의 멤버 포인터 접근 방식으로도 직접 접근이 가능하다. printf("((struct SMART *)0x12FF60)->A : %X\n", ((struct SMART *)0x12FF60)->A);
#define BASE ((struct SMART *)0x12FF60) printf("BASE->A : %X\n", BASE->A); 아니면 위와 같이 array의 시작주소 자체를 define문으로 정의한 후 그 이름으로 구조체멤버에 접근하는 방식으로 접근할 수도 있다.
#define AT91C_BASE_SYS (AT91_CAST(AT91PS_SYS) 0xFFFFF000) // (SYS) Base Address #define AT91C_BASE_AIC (AT91_CAST(AT91PS_AIC) 0xFFFFF000) // (AIC) Base Address #define AT91C_BASE_PDC_DBGU (AT91_CAST(AT91PS_PDC) 0xFFFFF300) // (PDC_DBGU) Base Address #define AT91C_BASE_DBGU (AT91_CAST(AT91PS_DBGU) 0xFFFFF200) // (DBGU) Base Address #define AT91C_BASE_PIOA (AT91_CAST(AT91PS_PIO) 0xFFFFF400) // (PIOA) Base Address #define AT91C_BASE_CKGR (AT91_CAST(AT91PS_CKGR) 0xFFFFFC20) // (CKGR) Base Address #define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address #define AT91C_BASE_RSTC (AT91_CAST(AT91PS_RSTC) 0xFFFFFD00) // (RSTC) Base Address #define AT91C_BASE_RTTC (AT91_CAST(AT91PS_RTTC) 0xFFFFFD20) // (RTTC) Base Address #define AT91C_BASE_PITC (AT91_CAST(AT91PS_PITC) 0xFFFFFD30) // (PITC) Base Address #define AT91C_BASE_WDTC (AT91_CAST(AT91PS_WDTC) 0xFFFFFD40) // (WDTC) Base Address #define AT91C_BASE_VREG (AT91_CAST(AT91PS_VREG) 0xFFFFFD60) // (VREG) Base Address | 위의 코드는 ATMEL사에서 제공하는 <AT91SAM7S256.h> 의 일부 코드인데 모든 주변장치의 시작주소가 define되어 있는것을 확인할 수 있다.
#ifndef __ASSEMBLY__ typedef struct _AT91S_PMC { AT91_REG PMC_SCER; // System Clock Enable Register AT91_REG PMC_SCDR; // System Clock Disable Register AT91_REG PMC_SCSR; // System Clock Status Register AT91_REG Reserved0[1]; // ...... } AT91S_PMC, *AT91PS_PMC;
| 그리고 위 코드와 같이 주변장치의 레지스터를 구조체로 묶어 정의해 놓았는데, 이를 위에서 정리한 방법과 같이 AT91C_BASE_PMC->PMC_SCER 와 같이 (define으로 정의된 메모리 베이스주소)->(구조체 멤버) 와 같은 형식으로 각 레지스터를 사용할 수 있다.
|