CPU↔주변장치 데이터 전송 방식
CPU와 주변장치 간 데이터를 주고받는 방식은 CPU 개입 정도에 따라 4가지로 분류된다.
| 방식 | CPU 개입 | 특징 |
|---|
| 프로그램 제어 (폴링) | 최대 | CPU가 장치 상태를 직접 반복 확인 |
| 인터럽트 | 중간 | 장치가 준비되면 CPU에 신호, CPU는 그 전까지 다른 작업 가능 |
| DMA | 최소 | CPU 없이 메모리↔장치 직접 전송, 완료 후 인터럽트로 통보 |
| 패킷형 직렬 입출력 | 없음 | 채널 프로세서가 독립적으로 처리, CPU는 시작/완료만 관여 |
- 폴링(Polling) 방식 정의
- 인터럽트 발생 시 MPU가 인터럽트 발생 장치를 직접 순서대로 검사하여 찾는 방법
- 인터럽트 벡터 방식과 달리 장치가 직접 CPU에 알리지 않으며, CPU가 능동적으로 탐색함
| | 폴링 | 인터럽트 벡터 |
|---|
| 발생 장치 식별 | CPU가 순서대로 직접 확인 | 장치가 벡터 주소로 직접 알림 |
| 속도 | 느림 | 빠름 |
| 하드웨어 복잡도 | 단순 | 복잡 |
폴링은 “인터럽트 발생 시 MPU가 발생 장치를 찾는 방법”으로, 인터럽트 자체를 사용하지 않는 방식과 혼동 주의
DMA (Direct Memory Access)
- Peripheral이 CPU를 거치지 않고 직접 메모리를 읽고 쓰는 방법
- Peripheral이 인터럽트를 걸 때마다 CPU가 처리하고 있으면 컨텍스트 스위칭(Context Switching) 비용이 많이 발생함
- 일부 칩셋의 DMA 컨트롤러는 채널(Channel)이란 개념이 존재
- 각 Peripheral 마다 소스/목적지/우선순위를 독립적으로 관리
1
2
3
4
5
| [ 인터럽트 방식 ]
Peripheral → CPU → RAM (CPU가 매번 중간에 개입)
[ DMA 방식 ]
Peripheral → DMA Controller → RAM (CPU는 시작/완료만 관여)
|
DMA에서 CPU의 역할
- DMA 정보를 전달하고, DMA가 사용 중인 메모리의 접근을 제한하고, 데이터를 확인함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| [ CPU의 역할 ]
1. 전송 시작 전 (Setup)
CPU가 DMA 컨트롤러에 설정값을 씀:
- 소스 주소 (어디서 가져올지)
- 목적지 주소 (어디에 쓸지)
- 전송 크기 (몇 바이트)
- 전송 방향 (Peripheral → RAM / RAM → Peripheral)
그리고 DMA 시작 트리거
2. 전송 중
CPU는 다른 작업 수행 (DMA가 버스 점유)
→ DMA가 쓰는 메모리 영역은 접근 회피
3. 전송 완료 후
DMA가 인터럽트로 CPU에 통보
→ CPU가 데이터 처리
|
DMA 제어기 레지스터 4종
DMA 컨트롤러는 CPU 없이 독립적으로 전송을 수행하기 위해 내부에 4가지 레지스터를 가진다.
| 레지스터 | 역할 |
|---|
| 주소 레지스터 | 데이터를 읽거나 쓸 메모리 주소 저장 |
| 카운터 레지스터 | 전송할 데이터 크기(바이트 수) 저장, 전송마다 감소하여 0이 되면 완료 |
| 상태 레지스터 | DMA 동작 상태(전송 중 / 완료 / 오류) 저장 |
| 채널 레지스터 | 어떤 주변장치(채널)와 통신할지 지정 |
DMA의 동작 방식
- DMA는 CPU와 같은 데이터 버스를 사용하기에 동시에 작업하면 충돌이 발생함
- 이를 해결하기 위해 Burst, Cycle-Steal, Transparent 방식이 존재
| 모드 | 버스 점유 방식 | CPU 영향 | 전송 속도 |
|---|
| Burst | 전송 완료까지 독점 | ❌ 버스 완전 차단 | 가장 빠름 |
| Cycle-Steal | 1사이클 전송 후 반환 반복 | ⚠️ 간헐적 지연 | 중간 |
| Transparent | Decode/Execute 구간만 사용 | ✅ 영향 없음 | 가장 느림 |
- Burst : DMA 컨트롤러가 데이터를 한 번에 전송
- Burst는 DMA 컨트롤러가 버스를 쓰는 동안 CPU가 메모리 접근이 불가함
- DMA가 버스 점유 요청
- CPU가 버스 양보 (Bus Release)
- DMA가 전송 완전히 끝날 때까지 버스 독점
- 전송 완료 후 CPU에 버스 반환
- Cycle-Steal : CPU 동작이 1사이클 수행된 후 DMA에게 버스 권한을 양도하는 형태
- CPU 동작이 1사이클 느려짐
1
2
3
| CPU : ──사용──│──양보──│──사용──│──양보──│──사용──
DMA : │─전송1─│ │─전송2─│
↑ 1사이클 훔침 ↑ 1사이클 훔침
|
- Transparent : CPU의 Decode, Execute 명령 동작(메모리 접근이 필요없는 상황)에서만 DMA가 동작
1
2
3
4
| CPU : Fetch──Decode/Execute──Fetch──Decode/Execute──
버스 : ─점유─│ │─점유─│ │
DMA : │───전송───────│ │───전송───────│
↑ CPU 버스 미사용 구간
|
입출력 버퍼링
- 데이터 오버런(Overrun) : CPU가 데이터를 읽기 전에 주변 장치가 해당 데이터를 덮어 씌우는 문제
버퍼링 방식
- Single Buffer : 단일 버퍼에서 CPU와 메모리의 읽기/쓰기가 수행됨
- 버퍼 하나를 두고 읽기/쓰기가 동시에 진행이 안됨
- Double Buffer : 두 개의 버퍼에서 읽기/쓰기를 따로 수행할 수 있음
- CPU의 데이터 처리 속도가 느리면 마찬가지로 버퍼가 가득 참
1
2
3
| Round 1: UART → [버퍼 A 쓰기] CPU ← [버퍼 B 읽기]
Round 2: UART → [버퍼 B 쓰기] CPU ← [버퍼 A 읽기]
Round 3: UART → [버퍼 A 쓰기] CPU ← [버퍼 B 읽기]
|
- Ring Buffer : 순환 형태로 버퍼를 구성. 버퍼가 끝에 도달하면 다시 처음 버퍼로 복귀
- Write 포인터가 Read 포인터를 따라잡으면 버퍼 오버플로우(Buffer Overflow) 발생
- Ring Buffer는 항상 Write와 Read의 거리를 체크해야함
| 방식 | 구조 | 장점 | 단점 |
|---|
| Single | 버퍼 1개 | 단순 | 읽기/쓰기 동시 불가 |
| Double | 버퍼 2개 교대 | 읽기/쓰기 동시 가능 | 생산>소비 시 한계 |
| Ring | 단일 버퍼 순환 | 연속 스트림에 최적 | 오버플로우 관리 필요 |
버퍼 구현 위치
- 버퍼는 하드웨어/소프트웨어 두 계층 모두 구현이 가능하다.
- 하드웨어 버퍼 : 주변장치 내부에 내장 (e.g. FIFO 버퍼)
- UART 하드웨어 자체에 FIFO 버퍼가 내장됨
- FIFO가 가득 차기 전에 CPU나 DMA가 읽어가지 않으면 오버런 발생
- 소프트웨어 버퍼 : 드라이버/애플리케이션 레벨 (e.g. Ring 버퍼)
- RAM에 버퍼를 구성하여 데이터를 보관
- Linux UART 드라이버의 tty 레이어가 내부적으로 Ring Buffer 사용
1
2
3
4
5
| [UART HW 내장 FIFO] ← 하드웨어 버퍼 (수십~수백 바이트)
↓ 인터럽트/DMA
[드라이버 Circular Buffer (RAM)] ← 소프트웨어 버퍼 (수 KB)
↓
[유저 앱 read()]
|
주변 장치 (Peripheral)
- GPIO(General Purpose IO) : 단순 High, Low 동작. 소프트웨어로 SPI,I2C 프로토콜을 구현해 사용 가능(Bit-Banging)
- Bit-Banging은 하드웨어 클럭이 아닌 소프트웨어 클럭이 의존하기 때문에 CPU의 기능 처리 속도에 의존함
- UART(Universal Asynchronous Receiver-Transmitter) : RX-TX 2선식 구조로 비동기식 통신을 수행함
- 하드웨어 프로토콜에 따라 전이중(Full-Duplex, RS-232/422, RS-485 4W), 반이중(Half-Duplex, RS-485 2W) 통신을 수행
- SPI(Serial Peripheral Interface) : MOSI/MISO/SCLK/CS 4선 구성, 전이중(Full-duplex) 동시 송수신 가능, 싱글 마스터 - 멀티 슬레이브 형태로 구축 가능
- I2C(Inter-Integrated Circuit) : SDA/SCL 2선 구성, 하드웨어가 단순한 대신 SPI보다 속도가 느림. 멀티 마스터 - 멀티 슬레이브 형태로 구축 가능
- Timer : 일정 시간 간격으로 인터럽트를 발생시키거나, PWM 신호를 생성
- ADC/DAC : ADC는 아날로그 신호를 디지털로 변환(센서 입력), DAC는 디지털을 아날로그로 변환(오디오 출력 등)
| 인터페이스 | 선 수 | 통신 방식 | 속도 | 주 용도 |
|---|
| GPIO | 1 | 단순 High/Low | - | 버튼, LED, Bit-bang |
| UART | 2 (TX/RX) | 비동기, 전이중,반이중 | 저속 | 디버그 콘솔, GPS |
| SPI | 4 (MOSI/MISO/SCLK/CS) | 동기, 전이중 | 고속 | 플래시, 디스플레이 |
| I2C | 2 (SDA/SCL) | 동기, 반이중 | 중속 | 센서, EEPROM |
| Timer | - | 내부 카운터 | - | PWM, 주기 인터럽트 |
| ADC/DAC | 1 (아날로그) | 변환 | - | 센서, 오디오 |
RS-232 9핀 신호 매핑
RS-232 DB-9 커넥터의 핀 번호와 신호 이름은 시험에 직접 출제된다.
| 핀 | 신호 | 전체 이름 | 방향 |
|---|
| 1 | DCD | Data Carrier Detect | 모뎀→DTE |
| 2 | RXD | Receive Data | 모뎀→DTE |
| 3 | TXD | Transmit Data | DTE→모뎀 |
| 4 | DTR | Data Terminal Ready | DTE→모뎀 |
| 5 | GND | Signal Ground | - |
| 6 | DSR | Data Set Ready | 모뎀→DTE |
| 7 | RTS | Request To Send | DTE→모뎀 |
| 8 | CTS | Clear To Send | 모뎀→DTE |
| 9 | RI | Ring Indicator | 모뎀→DTE |
UART 프레임 구조
UART는 비동기 통신으로 클럭 선이 없으며, Start/Stop 비트로 프레임의 시작과 끝을 식별한다.
1
2
| idle Start D0 D1 D2 D3 D4 D5 D6 D7 Parity Stop idle
High [Low] LSB →→→→→→→→→→→→→→→ MSB [opt] [High] High
|
| 항목 | 내용 |
|---|
| Start 비트 | Low(0) — idle(High)에서 Low 전환 시 프레임 시작 감지 |
| 데이터 | 8비트, LSB → MSB 순서 전송 |
| Parity 비트 | 선택적 (짝수/홀수 패리티 또는 없음) |
| Stop 비트 | High(1), 1비트 또는 2비트 |
| Idle 상태 | High 유지 |
USB (Universal Serial Bus)
| 항목 | 내용 |
|---|
| 최대 디바이스 수 | 127개 (주소 0번은 열거 과정에서 임시 사용, 실사용 불가) |
| 공급 전압 | +5V |
| USB 3.0 속도 | 5Gbps (SuperSpeed) |
| 핫플러그 | ✅ 지원 — 전원이 켜진 상태에서 연결/해제 가능 |
| 연결 방식 | 직렬 포트 |
CAN (Controller Area Network)
- 하나의 통신 버스에서 멀티 마스터 형태로 데이터 통신을 수행
- CAN의 데이터 신호는 다음 규칙을 가짐
- Dominant (논리 0, Active Signal): CAN_H = 3.5V, CAN_L = 1.5V → 차이 2V
- Recessive (논리 1, Passive Signal): CAN_H = 2.5V, CAN_L = 2.5V → 차이 0V
- 여러 개의 노드가 동시에 통신을 수행해도 Wired-AND 규칙에 따라 데이터가 손실 없이 전송됨
- 데이터를 못 보낸 노드는 버스의 데이터를 확인하고 다시 데이터를 송신
1
2
3
4
5
6
7
| [ CAN 네트워크 구조 ]
노드A 노드B 노드C
│ │ │
───┴──────────┴──────────┴─── CAN_H
───┬──────────┬──────────┬─── CAN_L
120Ω 120Ω ← 종단 저항 (반사 방지)
|
| 항목 | 내용 |
|---|
| 토폴로지 | 버스형, 멀티 마스터 |
| 신호 방식 | 차동 신호 (CAN_H / CAN_L) |
| 중재 방식 | 메시지 ID 기반 Wired-AND (낮은 ID = 높은 우선순위) |
| 최대 속도 | 1Mbps (CAN 2.0) / 최대 8Mbps (CAN FD) |
| 노이즈 내성 | 차동 신호로 외부 노이즈에 강함 |
| 주 용도 | 자동차 ECU 통신, 산업 자동화 |
PCIe(PCI-Express)
- PCI : 여러 장치가 병렬 버스를 공유하는 구조
- 각 장치간 버스 충돌과 동시에, 클럭 스큐(Clock Skew)가 발생
- 클럭 스큐 : 각각의 데이터 선이 미묘하게 선 길이가 달라 신호가 동시에 도착하지 않음
- PCIe : 직렬 버스 사용
- Lane : TX 1쌍 + RX 1쌍, 총 4선으로 구성된 차동 직렬 링크
- 세대마다 1 Lane 당 대역폭도 다르다
1
2
3
| [ 1 Lane 구조 ]
장치 A ──TX+/TX-──→──RX+/RX-── 장치 B
장치 A ──RX+/RX-──←──TX+/TX-── 장치 B
|
1
2
3
| [ Transaction Layer ] ← TLP 생성/소비 (실제 데이터)
[ Data Link Layer ] ← 오류 검출/재전송 (DLLP)
[ Physical Layer ] ← 차동 신호 송수신
|
- TLP(Transaction Layer Packet) : 실제 데이터를 다루는 통신 패킷
1
2
3
4
5
6
7
8
9
10
11
12
| [ TLP 구조 ]
┌─────────────────────────────┐
│ Header │
│ - TLP 타입 (읽기/쓰기/완료) │
│ - 목적지 주소 (메모리 위치) │
│ - 전송 크기 │
│ - 요청자 ID │
├─────────────────────────────┤
│ Data Payload (쓰기 시에만) │
├─────────────────────────────┤
│ ECRC (오류 검출) │
└─────────────────────────────┘
|