DMA: CPU 없이 데이터를 옮기는 일꾼
메모리와 주변장치 사이의 복사를 하드웨어가 대신합니다. ADC 샘플링, UART 수신, SPI 디스플레이 전송이 빨라지는 원리.
UART로 1000바이트를 받으면 인터럽트가 1000번 걸립니다. DMA를 쓰면 "UART 데이터 레지스터에서 이 버퍼로 1000바이트를 옮겨라"라고 한 번 설정하고, 끝났을 때 인터럽트 한 번만 받습니다.
설정하는 값
- 출발지와 목적지 주소: 예)
&USART1->DR→rx_buf - 전송 개수: 1000
- 증가 여부: 주변장치 주소는 고정, 메모리 주소는 1씩 증가
- 데이터 크기: 바이트, 하프워드, 워드
- 트리거: 어떤 주변장치 이벤트마다 한 번씩 옮길지
- 모드: 한 번(normal) 또는 끝나면 처음으로 돌아가 반복(circular)
자주 쓰는 조합
| 조합 | 효과 |
|---|---|
| 타이머 → ADC → DMA | 정확한 주기로 샘플을 버퍼에 쌓음 |
| UART 수신 + 순환 DMA + IDLE 인터럽트 | 길이를 모르는 패킷 수신 |
| 메모리 → SPI | 디스플레이 화면 전송 |
주의할 점
- DMA가 쓰는 중인 버퍼를 CPU가 읽으면 반쯤 바뀐 데이터를 봅니다. 절반 완료 인터럽트로 버퍼를 둘로 나눠 쓰는 더블 버퍼링을 씁니다.
- 캐시가 있는 코어(M7)에서는 캐시 정리와 무효화가 필요합니다.