임베디드 스터디 - 메모리 초기화
임베디드 스터디 - 메모리 초기화
칩 셀렉트 로직 (CS)
- CPU 내장 RAM 외에도 추가 외장 SDRAM을 사용할 경우, MMIO를 통해 메모리 주소 설정
- CS가 메모리 주소 범위를 바탕으로 디코더 동작, 메모리 선택
1
2
3
4
5
6
CPU 주소버스 상위 비트 → 디코더 → CS0 (NOR Flash)
→ CS1 (SDRAM)
→ CS2 (주변장치)
0x0000_0000 ~ 0x00FF_FFFF → CS0 활성 → NOR Flash
0x2000_0000 ~ 0x20FF_FFFF → CS1 활성 → SDRAM
메모리 컨트롤러
- 각 메모리마다 동작 타이밍이 다르기에, 별도의 관리가 필요
- 메모리 컨트롤러는 스타트업 코드 실행 시 클럭 설정(PLL) 이후 실행
- 각 메모리의 타이밍 파라미터 설정 필요
- CPU는 읽기/쓰기 요청만, 이후 타이밍 처리는 메모리 컨트롤러가 처리함
1
2
3
4
5
6
CPU → "0x2000_0000 읽어줘"
↓
메모리 컨트롤러
(RAS → 대기 → CAS → 대기 → 데이터 캡처)
↓
CPU ← 데이터 반환
링커스크립트 (.ld)
- 빌드 과정에서 컴파일된 파일의 메모리 주소를 배정하는 코드
- MEMORY : 어떤 메모리가 어떤 주소에 얼마나 있는지 선언
- SECTIONS : 각 섹션(.text, .data, .bss)을 어느 메모리에 배치할 지 지정
- 만약 링커스크립트의 주소와 실제 메모리의 주소가 안맞다면, HardFault 예외, 최악은 알 수 없는 동작을 수행하는 경우도 발생한다.
- 보드 스펙시트나 MCU 스펙시트를 바탕으로 링커스크립트를 생성해야한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS {
.text : {
*(.text*) /* 모든 오브젝트의 .text 섹션 */
} > FLASH /* Flash에 배치 */
.data : {
*(.data*)
} > RAM AT > FLASH /* RAM에 올라가지만, 초기값은 Flash에 저장 */
.bss : {
*(.bss*)
} > RAM /* RAM에만 배치, Flash 공간 불필요 */
}
링커스크립트 기본 문법
- MEMORY : 메모리 선언
- 속성은 총 세 가지
r= 읽기w= 쓰기x= 실행 가능
1
2
3
4
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
- SECTIONS : 각 섹션의 메모리 지정
*: 와일드카드 문법.- 섹션 앞
*: 모든.o(오브젝트 파일)을 지정 - 섹션 뒤
*: 모든 서브섹션
- 섹션 앞
>: 실행 위치AT >: 초기값 위치
1
2
3
4
5
SECTIONS {
.data : {
*(.data*)
} > RAM AT > FLASH
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.