개념
메모리와 주변장치 또는 메모리와 메모리 사이에서 CPU 점유없이 높은 전송 속도를 가진 데이터 전송 컨트롤러
(CPU가 개입하기에는 데이터 양이 너무 많거나 전송 주기가 너무 빈번하여 CPU 효율을 떨어뜨릴 때 사용하는 하드웨어 오버로드 방지 엔진)
메모리 : SRAM, Flash 등, 언제든지 Read/Write 가능하므로 DMA 요청 신호없이 바로 전송 가능
비메모리 주변 장치 : RX FIFO 데이터가 차거나 TX FFO가 빌 떄만 전송 가능, DMA에 "지금 데이터 송/수신" 신호를 보내야 한다.
Handshake Interface(DMA 요청 신호)
: 데이터를 옮길 때 "나 준비됐어!" <-> "데이터 가져갈게!" 하고 주변장치와 DMA가 주고받는 신호(signal)
종류
일반적으로 H/W Handshake 세팅
H/W Handshake : CPU 개입 없이 주변장치
Peripheral <-- H/W 신호선 --> DMAC <-- IRQ --> CPU
S/W Handshake : H/W 신호선이 없는 특수한 디바이스에 CPU가 직접 레지스터를 세팅하여 DMA 발생
CPU -- (레지스토 쓰기 ReqSrcReg = 1) --> DMAC <-- 전송 --> Peripheral
특징
mcu가 독립된 복수의 채널 설정 가능하다면 동시에 여러 주변장치가 DMA 사용할 수 있다.
또한 각 채널 별 독립 우선 순위 지정
대표적인 사용 상황
사용 원칙 : CPU는 제어/연산(Business Logic)에 집중하고, 단순한 메모리 복사 작업은 DMA에게 전담
1. 대용량 연속 데이터 전송 (High Throughout)
2. 높은 주기/연속 센서 데이터 수집 (High Rate Sampling)
3. 가변 길이의 비동기 통신 수신 (Uart Circular RX)
4.오디오/음성 입출력 (I2S/SAI Interface)
모드 (MH1903 경우)
Normal 모드 :
한번 지정된 길이만큼 전송이 끝나면 DMA가 멈추고 완료 인터럽트 발생
그리고 나서 CPU가 인터럽트를 처리하고 다음 전송 메모리 주소와 크기를 DMA에 세팅 뒤 재시작
Multi-block 모드 :
대용량 데이터를 여러 개의 블록 전송 정보(LLI)를 메모리에 연결한다. 그 후 하나 블록 전송이 끝나면 DMA H/W가 CPU 개입 없이 스스로 다음 설정값을 즉각 읽어와 즉각 전송을 이어간다. CPU 개입없이 연속적으로 데이터 전송 가능.
Multi-block 사용 이유
예시)
만약 LCD 프레임버퍼 480 X 320 해상도, RGB565 bit = 307.2KB나 SPI Flash 전체 이미지 1MB를 DMA로 전송해야 한다고 가정
Single-Block 방식을 사용 시 문제점
307.2KB를 전송하려면 단일 레지스터의 한계인 8KB씩 나누어 약 38번의 DMA 인터럽트를 CPU가 수동으로 받아서 주소(SAR/DAR)와 BLOCK_TS를 재설정하고 다시 Enable 해주어야 합니다. 이 과정에서 CPU 잦은 개입과 Context Switching 오버헤드가 발생합니다.
Multi-Block 전송 방식을 사용 시
DMAC 내부의 Linked List (LLP - Linked List Pointer) 기능이나 연속적인 블록 체이닝 기법을 활용합니다.
- CPU가 메모리 상에 다음 전송할 Descriptor 목록(다음 주소, 전송 크기 등)을 미리 구조체 배열로 만들어 둡니다.
- DMA 컨트롤러가 첫 번째 블록 16KB 전송이 끝나면, CPU 개입 없이 하드웨어 스스로 LLP 레지스터가 가리키는 다음 Descriptor를 읽어와서 연속으로 남은 데이터들을 이송합니다.
- 최종적으로 전체 데이터($307.2\text{ KB}$) 이송이 모두 끝난 시점에 CPU에 인터럽트를 딱 1번만 보냅니다.
3. 실무 요약
- Single-Block 범위 (16KB 이하): 센서 패킷, 단발성 통신 버퍼, 소형 데이터 복사 $\rightarrow$ 단일 DMA 설정으로 충분
- Multi-Block 범위 16KB 22,528 Byte , 0x5800 초과): LCD 디스플레이 프레임 버퍼, 오디오 스트리밍, 대용량 SPI/QSPI Flash 읽기/쓰기
- Multi-Block (Linked List Descriptor) 전송 활용 필수
용어
전송데이터 블록 사이즈(Block Transfer Size) : DMA 전송으로 옮길수 있는 총 데이터 개수
버스트 데이터 블록 사이즈(Burst Size) : DMA 요청 1번당 연속으로 쓸 데이터 개수
데이터 폭(Data WIDTH) : 한번에 컨트롤 가능한 데이터 폭
전송 이벤트 시퀀스
DMA 초기화 --> DMA 채널 선택 --> SRC/DST 주소 지정 -->
Data Width, Burst Size, Block Size 설정 \ Interrupt Mask 설정 (Block Complete 인터럽트 Enable)
전송 시작
Memory-to-Memory: DMA Channel Enable 즉시 전송 시작 \ Memory-to-Peripheral: 주변장치(UART/SPI)의 DMA TX/RX Enable 후 Handshake H/W 시 H/W 신호 대기
전송 완료
DMA가 백그라운드에서 Bus 점유하여 데이터 이송 \ 지정한 Block Size 이송 완료 시 DMAC가 CPU에 Interrupt 발생 \
ISR(인터럽트 서비스 루틴) 진입
Clear Register에 '1' 써서 플래그 지움
다음 작업 수행
인터럽트 예제 코드
void DMA0_IRQHandler(void)
{
if (DMA_GetITStatus(DMA_Channel_0, DMA_IT_BlockTransferComplete))
{
DMA_ClearITPendingBit(DMA_Channel_0, DMA_IT_BlockTransferComplete);
DCMITFC++;
}
else if (DMA_GetITStatus(DMA_Channel_0,DMA_IT_Error))
{
DMA_ClearITPendingBit(DMA_Channel_0,DMA_IT_Error);
printf("DMA_IT_Error\r\n");
}
}
'MCU 통신 > 이론' 카테고리의 다른 글
| ISO/IEC 15693 (0) | 2026.07.05 |
|---|---|
| [RF-NFC] EMV(PayPass) VS MIFARE VS FELICA (0) | 2025.04.22 |
| SPI (0) | 2024.07.07 |
| NEC Protocol (0) | 2024.06.27 |
| RS485 모드버스 이론 (0) | 2024.06.27 |