๐ English Abstract
This article provides an in-depth technical guide on diagnosing and resolving FIFO overflow data loss in high-speed parallel sensor data acquisition systems built on the Raspberry Pi RP2040 microcontroller. By combining PIO (Programmable I/O) state machines, Dual ARM Cortex-M0+ cores, and DMA Ring Buffers, we tackle severe bus contention and interrupt latency issues. Readers will gain practical insights into hardware DREQ synchronization, Ping-Pong DMA configuration, and critical ARM Cortex-M Memory Barriers (__dmb) for deterministic, zero-data-loss execution.
๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ RP2040 ๋ง์ดํฌ๋ก์ปจํธ๋กค๋ฌ๋ ๋ ์ฐฝ์ ์ธ PIO(Programmable I/O, ํ๋ก๊ทธ๋๋จธ๋ธ ์ ์ถ๋ ฅ) ํ๋์จ์ด ํ๋ฆฌํ๋ด๊ณผ ๋์ผ ARM Cortex-M0+ ์ฝ์ด๋ฅผ ๋ด์ฅํ์ฌ, ์ ๋น์ฉ์ผ๋ก๋ ๊ณ ์ ์ฌ์์ ๋ณ๋ ฌ ์ผ์ ๋ฐ์ดํฐ ์์ง(Parallel Sensor Data Acquisition) ์์คํ ์ ๊ตฌ์ถํ ์ ์๋ ๋ฐ์ด๋ ํ๋ซํผ์ ๋๋ค. ํ์ง๋ง MHz ๋จ์์ ๋์ ์ํ๋ง ์ฃผํ์๋ ๋ค์ฑ๋ ๋ณ๋ ฌ ๋ฐ์ดํฐ๋ฅผ ์์งํ ๋, PIO RX FIFO ์ค๋ฒํ๋ก์ฐ(Overflow)๋ก ์ธํ ๊ฐํ์ ๋ฐ์ดํฐ ์ ์ค ๋ฌธ์ ๋ ์์คํ ์ ์ฒด์ ์ ๋ขฐ์ฑ์ ๋จ์ด๋จ๋ฆฌ๋ ์ฃผ์ ์์ธ์ด ๋ฉ๋๋ค.
๋ณธ ํฌ์คํ ์์๋ RP2040 ํ๊ฒฝ์์ ์ด๊ณ ์ ๋ฐ์ดํฐ ์ํ๋ง ์ ๋ฐ์ํ๋ ๋ฒ์ค ๊ฒฝํฉ(Bus Contention) ๋ฐ ์ง์ฐ ์๊ฐ(Latency) ๋ฌธ์ ๋ฅผ ์ ๋ฐ ์ง๋จํ๊ณ , DMA ๋ง๋ฒํผ(Ring Buffer) ๊ธฐ์ ๊ณผ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด(Memory Barrier) ๋๊ธฐํ ์ต์ ํ๋ฅผ ํตํด ๋ฐ์ดํฐ ์ ์ค๋ฅ 0%๋ฅผ ๋ฌ์ฑํ๋ ํธ๋ฌ๋ธ์ํ ๊ณผ์ ๋ฐ ์ค๋ฌด ๋ฉ์ปค๋์ฆ์ ์์ธํ ๋ค๋ฃน๋๋ค.
1. ๊ณ ์ ์ผ์ ์์ง ์์คํ ์ ๊ตฌ์กฐ ๋ฐ ๋ฐ์ดํฐ ๋ณ๋ชฉ ์์ธ
RP2040์ PIO๋ ๋ฉ์ธ CPU์ ๊ฐ์ ์์ด ๋ ๋ฆฝ์ ์ธ ํด๋ก ์ฃผ๊ธฐ์ ๋ง์ถฐ GPIO ํ์ ์ ํธ๋ฅผ ์ฝ์ด ๋ค์ผ ์ ์์ต๋๋ค. ์ผ์๋ก๋ถํฐ ์์ ๋ ๋ฐ์ดํฐ๋ ์ํํธ ๋ ์ง์คํฐ(Shift Register)๋ฅผ ๊ฑฐ์ณ RX FIFO(First-In, First-Out)์ ์ ์ฅ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ PIO ๋ด๋ถ์ RX FIFO ๊น์ด๋ ๊ฐ ์ํ ๋จธ์ (State Machine)๋น ๋จ 4์๋(16๋ฐ์ดํธ)์ ๋ถ๊ณผํฉ๋๋ค.
CPU๊ฐ ํด๋ง(Polling) ๋ฐฉ์์ด๋ ์ธํฐ๋ฝํธ(Interrupt, ISR) ๋ฐฉ์์ผ๋ก ์ด FIFO๋ฅผ ๋น์ฐ๋ ค ํ ๊ฒฝ์ฐ, ๋ค์๊ณผ ๊ฐ์ ์ฌ๊ฐํ ์ํคํ ์ฒ์ ๋ณ๋ชฉ์ด ๋ฐ์ํฉ๋๋ค:
- ์ธํฐ๋ฝํธ ์ง์ฐ ์๊ฐ(Interrupt Latency): Cortex-M0+ ์ฝ์ด์ ์ธํฐ๋ฝํธ ์ง์ /์ง์ถ ์ปจํ ์คํธ ์ค์์นญ(Context Switching) ์ค๋ฒํค๋๋ก ์ธํด, ์ด๋น ์์ญ๋ง ๋ฒ ์ด์ ๋ฐ์ํ๋ ์ผ์ ์ ๋ ฅ์ CPU ์ธํฐ๋ฝํธ๋ง์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
- XIP Flash ์ง์ฐ ํ์: ์คํ ์ฝ๋๋ ISR์ด ์ธ๋ถ QSPI Flash(Execute-In-Place)์์ ์คํ๋ ๊ฒฝ์ฐ, ์บ์ ๋ฏธ์ค(Cache Miss) ๋ฐ์ ์ ์์ญ ๋ด์ง ์๋ฐฑ ํด๋ก ์ฃผ๊ธฐ์ ์ง์ฐ์ด ๋ฐ์ํ๋ฉฐ, ๊ทธ ์ฌ์ด RX FIFO๋ ์ฆ์ ์ค๋ฒํ๋ก์ฐ ์ํ(FDEBUG ๋ ์ง์คํฐ์ RXOVER ๋นํธ ์ )์ ์ง๋ฉดํฉ๋๋ค.
- ๋์ผ์ฝ์ด SRAM ๊ฒฝํฉ: Core 0๊ณผ Core 1์ด ๋์ผํ SRAM ๋ฑ ํฌ(Bank)์ ๋์์ ์ ๊ทผํ ๋, AHB ๋ฒ์ค ํฌ๋ก์ค๋ฐ(AHB Bus Crossbar)์์ ์ค์ฌ(Arbitration) ๋๊ธฐ ์๊ฐ์ด ๋ฐ์ํ์ฌ ๋ฐ์ดํฐ ์ด์ก์ด ์ง์ฐ๋ฉ๋๋ค.
2. PIO hardware DREQ ๋ฐ DMA ์ฒด์ด๋ ๋ฉ์ปค๋์ฆ ๋ถ์
FIFO ์ค๋ฒํ๋ก์ฐ๋ฅผ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฐฉ์งํ๊ธฐ ์ํด์๋ CPU์ ๊ฐ์ ์ ์์ ํ ๋ฐฐ์ ํ๊ณ , ํ๋์จ์ด ์์ฒญ ์ ํธ์ธ DREQ(Data Request) ๊ธฐ๋ฐ์ DMA(Direct Memory Access)๋ฅผ ์ ๋ฉด์ ๋ฐฐ์นํด์ผ ํฉ๋๋ค.
PIO ์ํ ๋จธ์ ์ RX FIFO์ ๋ฐ์ดํฐ๊ฐ 1๊ฐ ์ด์ ๋ค์ด์ค๋ ์๊ฐ ํ๋์จ์ด DREQ ์ ํธ(DREQ_PIOx_RXy)๋ฅผ ์ด์ค์
(Assertion)ํฉ๋๋ค. DMA ์ฑ๋์ ์ด DREQ ์ ํธ๋ฅผ ์์ ํ๋ ์ฆ์ ๋ฒ์ค ๋ง์คํฐ๋ก์ SRAM์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ค์ด๋ ํธ ํธ๋์คํผํฉ๋๋ค. ํ์ง๋ง ๋จ์ ๋จ์ผ DMA ๋ฒํผ ์ค์ ์ ๋ฒํผ๊ฐ ๊ฐ๋ ์ฐผ์ ๋ ์ฌ์ค์ (Reconfiguration) ๊ณผ์ ์์ ์ง์ฐ์ด ๋ฐ์ํด ๋ค์ FIFO ์ค๋ฒํ๋ก์ฐ๋ฅผ ์ ๋ฐํฉ๋๋ค.
์ด์ค ๋ฒํผ๋ง(Ping-Pong DMA)๊ณผ DMA ์ฒด์ด๋
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ ๊ฐ์ DMA ์ฑ๋(Channel A, Channel B)์ ์ํธ ์ฐ๊ฒฐํ๋ DMA ์ฒด์ด๋(DMA Chaining) ๋ฐฉ์์ ์ ์ฉํฉ๋๋ค. Channel A๊ฐ ๋ฒํผ 1๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ๋์, ๋ฐ์ดํฐ ์์ง์ด ๋๋๋ฉด ์๋ฃ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์์ํค๋ ๋์์ Channel B๋ฅผ ํ๋์จ์ด์ ์ผ๋ก ์ฆ์ ํธ๋ฆฌ๊ฑฐํ์ฌ ๋ฒํผ 2๋ก ์์ง์ ์ด์ด๊ฐ๋๋ค.
// DMA ์ฒด์ด๋ ๋ฐ DREQ ์ค์ ์์ (RP2040 C/C++ SDK)
int dma_chan_a = dma_claim_unused_channel(true);
int dma_chan_b = dma_claim_unused_channel(true);
dma_channel_config c_a = dma_channel_get_default_config(dma_chan_a);
channel_config_set_read_increment(&c_a, false); // PIO RX FIFO ์ฃผ์ ๊ณ ์
channel_config_set_write_increment(&c_a, true); // SRAM ๋ฒํผ ์ฃผ์ ์ฆ๊ฐ
channel_config_set_dreq(&c_a, pio_get_dreq(pio, sm, false)); // PIO RX DREQ ์ฐ๊ฒฐ
channel_config_set_chain_to(&c_a, dma_chan_b); // ์ฑ๋ A ์๋ฃ ์ ์ฑ๋ B ์๋ ์คํ
dma_channel_configure(
dma_chan_a, &c_a,
buffer_a, // ๋ชฉ์ ์ง ์ฃผ์ (SRAM)
&pio->rxf[sm], // ์์ค ์ฃผ์ (PIO RX FIFO)
BUFFER_SIZE_WORDS, // ์ ์ก ํฌ๊ธฐ
false // ์์ง ์์ํ์ง ์์
);
3. DMA ๋ง๋ฒํผ(Ring Buffer)์ ๋ฉ๋ชจ๋ฆฌ ๋ฑ ํฌ ๋ถํ ์ต์ ํ
์ฒด์ด๋ ๋ฐฉ์ ์ธ์๋, ์ฃผ์ ๋นํธ ๋ง์คํน์ ํ์ฉํ DMA ๋ง๋ฒํผ(Ring Buffer) ๋ชจ๋๋ฅผ ์ค์ ํ๋ฉด ๋จ์ผ DMA ์ฑ๋๋ง์ผ๋ก๋ ์ฐ์๋ ์ํ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ค๋ฒํค๋ ์์ด ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
DMA Ring Buffer ์ค์ ๊ท์น
RP2040์ DMA ์ปจํธ๋กค๋ฌ๋ ์ ๋ ฌ๋(Aligned) ๋ฉ๋ชจ๋ฆฌ ๊ฒฝ๊ณ ๋ด์์ 2^n ๋ฐ์ดํธ ํฌ๊ธฐ์ ๋ง๋ฒํผ๋ฅผ ์ง์ํฉ๋๋ค. channel_config_set_ring() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ธฐ(Write) ์ฃผ์๋ฅผ ์ํํ๋๋ก ์ค์ ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ์ผ๋ผ์ธ๋จผํธ(Memory Alignment): ๋ง๋ฒํผ์ ์์ ์ฃผ์๋ ๋ฐ๋์ ๋ง๋ฒํผ ํฌ๊ธฐ(2^n ๋ฐ์ดํธ)์ ๋ฐฐ์ ์ฃผ์์ ์์นํด์ผ ํฉ๋๋ค. ์:
uint32_t ring_buffer[1024] __attribute__((aligned(4096))); - SRAM ๋ฑ ํฌ ๋ถํ (SRAM Bank Partitioning): RP2040์ 4๊ฐ์ ์ ๊ท SRAM ๋ฑ ํฌ(SRAM0~3, ๊ฐ 64KB)์ 2๊ฐ์ ์คํฌ๋์นํจ๋ ๋ฑ ํฌ(SRAM4~5, ๊ฐ 4KB)๋ฅผ ๊ฐ์ต๋๋ค. DMA ์ฐ๊ธฐ ๋ฒํผ๋ฅผ SRAM0์ ๋ฐฐ์นํ๊ณ , Core 1์ ์คํ ๋ฐ ์ฒ๋ฆฌ ๋ก์ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ SRAM1 ๋ฐ SRAM2์ ๋ถ๋ฆฌ ๋ฐฐ์นํจ์ผ๋ก์จ AHB ๋ฒ์ค ํฌ๋ก์ค๋ฐ์์์ ๊ฒฝํฉ(Bus Contention)์ ์๋ฒฝํ ์ฐจ๋จํฉ๋๋ค.
4. Dual-Core ํ์ดํ๋ผ์ธ๊ณผ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด(__dmb) ํธ๋ฌ๋ธ์ํ
DMA๊ฐ SRAM ๋ง๋ฒํผ๋ก ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๊ณ ์ ์ด์กํ๋ ๋์, ๋ฐ์ดํฐ์ ํ์ฒ๋ฆฌ(FFT, ํํฐ๋ง, ํ๋กํ ์ฝ ํ์ฑ ๋ฑ)๋ Core 1์์ ๋ด๋นํ๊ณ ์ผ์ ์์ง ํต์ ๋ฐ ๋คํธ์ํฌ ์ ์ก์ Core 0์์ ์ฒ๋ฆฌํ๋ ๋์ผ์ฝ์ด ํ์ดํ๋ผ์ธ(Dual-Core Pipeline) ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
์ด๋, Core 1์ด DMA์ ์ฐ๊ธฐ ํฌ์ธํฐ๋ฅผ ์ถ์ ํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด๊ฐ ๋ ๋ฐ์ดํฐ ๊นจ์ง(Data Corruption) ๋ฐ ๊ฐฑ์ ๋ฏธ์ธ์ ํ์์ด ๋น๋ฒํ๊ฒ ๋ฐ์ํฉ๋๋ค. ์ด๋ ์ปดํ์ผ๋ฌ์ ์ต์ ํ ์ค๋ฒ๋ผ์ด๋ฉ ๋ฐ ARM Cortex-M0+์ ํ์ดํ๋ผ์ธ ๋ฐ ๋ฒ์ค ์ธํฐ์ปค๋ฅํธ์์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์์ ์ฌ๋ฐฐ์น(Memory Reordering) ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค.
ํธ๋ฌ๋ธ์ํ : ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด(Memory Barrier)์ ํ์ฐ์ฑ
C ์ธ์ด์ volatile ํค์๋๋ง์ผ๋ก๋ CPU ํ๋์จ์ด ๋จ์ ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ก ์์๋ฅผ ๋ณด์ฅํ ์ ์์ต๋๋ค. DMA๊ฐ SRAM์ ๋ฐ์ดํฐ๋ฅผ ๋ค ์ผ๋๋ผ๋, ์ฝ์ด์ ๋ก์ปฌ ๋ฒ์ค ๋ฒํผ๋ง์ด๋ ๋ ์ง์คํฐ ์บ์ฑ์ผ๋ก ์ธํด ์ฝ์ด๊ฐ ์ต์ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ง ๋ชปํ๊ณ ์ด์ ๊ฐ์ ์ฝ๋ ํ์์ด ๋ฐ์ํฉ๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ARM ์ด์
๋ธ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ๋ช
๋ น์ด๋ฅผ ๋ช
์์ ์ผ๋ก ์ฝ์
ํด์ผ ํฉ๋๋ค.
- __dmb() (Data Memory Barrier): ๋ฐฐ๋ฆฌ์ด ์ด์ ์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ(Read/Write) ์์ ์ด ์๋ฃ๋ ํ, ๋ฐฐ๋ฆฌ์ด ์ดํ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ์คํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. DMA ํฌ์ธํฐ ์ ๋ฐ์ดํธ ํ์ธ ์งํ ๋ฐ๋์ ํธ์ถํด์ผ ํฉ๋๋ค.
- __dsb() (Data Synchronization Barrier): ๋ฐฐ๋ฆฌ์ด ์ด์ ์ ๋ช ๋ น์ด๊ฐ ์์ ํ ์๋ฃ๋ ๋๊น์ง ์ดํ ๋ช ๋ น์ด์ ์คํ์ ์ ์งํฉ๋๋ค.
- SIO Hardware FIFO ์ฌ์ฉ: ์ฝ์ด ๊ฐ ๋๊ธฐํ ํ๋๊ทธ ์ ๋ฌ ์ RP2040 ๋ด์ฅ์ SIO(Single-cycle I/O) ํ๋์จ์ด FIFO๋ฅผ ์ฌ์ฉํ๋ฉด, ์ธํฐ๋ฝํธ ์ค๋ฒํค๋ ์์ด 1ํด๋ก ์ฃผ๊ธฐ ๋ง์ ์ฝ์ด ๊ฐ ๋ฉ์ธ์ง๋ฅผ ์์ ํ๊ฒ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค.
// Core 1: ์ผ์ ๋ฐ์ดํฐ ์์ ๋ฐ ๋๊ธฐํ ๋ฃจํด
void core1_entry() {
uint32_t last_read_idx = 0;
while (1) {
// DMA์ ํ์ฌ ์ฐ๊ธฐ ํฌ์ธํฐ ๋ ์ง์คํฐ ์ง์ ์กฐํ
uint32_t current_dma_write_addr = dma_hw->ch[dma_chan_a].write_addr;
uint32_t current_idx = (current_dma_write_addr - (uint32_t)ring_buffer) / sizeof(uint32_t);
if (current_idx != last_read_idx) {
// [์ค์] ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด ํธ์ถ: DMA๊ฐ SRAM์ ์ด ๋ฐ์ดํฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ์์ฑ(Visibility) ๋ณด์ฅ
__dmb();
// ์ผ์ ๋ฐ์ดํฐ ์์ ์ฒ๋ฆฌ
process_sensor_data(&ring_buffer[last_read_idx]);
// ์ฝ๊ธฐ ์ธ๋ฑ์ค ์
๋ฐ์ดํธ
last_read_idx = (last_read_idx + 1) % RING_BUFFER_SIZE;
}
}
}
5. ์ฃ์ง ์ผ์ด์ค ๋์ ๋ฐ ์ค์ ์ต์ ํ ํ ( Edge Cases)
๊ณ ์ ์์ง ์์คํ ์ ์ฅ์๊ฐ ์๋์ํฌ ๋ ์ง๋ฉดํ ์ ์๋ ์ฃ์ง ์ผ์ด์ค์ ๊ทธ ๋์ฒ๋ฒ์ ๋๋ค.
- Flash Access ์ค๋จ(Stall) ๋ฐฉ์ง: Core 0์ด๋ Core 1์ด Flash ๋ฉ๋ชจ๋ฆฌ์ ์ฐ๊ธฐ(Flash Erase/Program) ์์
์ ์ํํ๋ฉด ์ ์ฒด QSPI ๋ฒ์ค๊ฐ ์ฐจ๋จ๋์ด ๋ ์ฝ์ด ๋ชจ๋ ์ ์ง(Stall)ํฉ๋๋ค. ์ด๋ DMA๋ง ์ ์ ์๋ํ๋ฉฐ, ๋ง๋ฒํผ ์ค๋ฒํ๋ก์ฐ๊ฐ ์๊ธฐ์ง ์๋๋ก Flash ์์
์ ์์ง ๋จ์๋ฅผ ์งง๊ฒ ๋ถํ ํ๊ฑฐ๋ ๊ด๋ จ ์ฝ๋๋ฅผ SRAM์ ์์ฃผ(
__not_in_flash_func)์์ผ์ผ ํฉ๋๋ค. - PIO Clock Divider ์ ๋ฐ ๋ถํ :
pio_sm_set_clkdiv_int_frac()์ ์ด์ฉํ์ฌ ๋ถ์ฃผ๋น๋ฅผ ์ ์ ๋ฐ ์์์ 8๋นํธ ๋จ์๋ก ์ ๋ฐํ๊ฒ ์กฐ์ ํจ์ผ๋ก์จ ์ผ์์ ์ํ๋ง ํ์๊ณผ DMA ์ ์ก ์๋ ๊ฐ์ ๋ฏธ์ธํ ์งํฐ(Jitter)๋ฅผ ์๋ฒฝํ ์ ๊ฑฐํฉ๋๋ค. - PIO FDEBUG ๋ ์ง์คํฐ ๋ชจ๋ํฐ๋ง: ์ฃผ๊ธฐ์ ์ผ๋ก
pio->fdebug๋ ์ง์คํฐ์RXOVER๋นํธ๋ฅผ ๋ชจ๋ํฐ๋งํ์ฌ, HW ๋จ์์ ๋น์ ์์ ์ธ ์ ๋ ฅ ํด๋ก ํญ์ฃผ๋ก ์ธํ ์ค๋ฒํ๋ก์ฐ ๋ฐ์ ์ฌ๋ถ๋ฅผ ์ค์๊ฐ ํ์งํ๋๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ํ์คํฌ๋ฅผ ๋ฐฐ์นํฉ๋๋ค.
6. ๊ฒฐ๋ก ๋ฐ ์์ฝ
RP2040 ๋ง์ดํฌ๋ก์ปจํธ๋กค๋ฌ ํ๊ฒฝ์์ ์ด๊ณ ์ ๋ณ๋ ฌ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ค ์์ด ์์งํ๊ธฐ ์ํด์๋ ๋จ์ํ ์ฝ๋ ์์ฑ์ ๋์ด ํ๋์จ์ด ๋ด ๋ฒ์ค ์ํคํ ์ฒ, PIO DREQ handshaking, DMA ๋ง๋ฒํผ, ๋ฉํฐ์ฝ์ด ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด์ ๋ํ ํตํฉ์ ์ธ ์ดํด๊ฐ ํ์์ ์ ๋๋ค.
| ๋ฌธ์ ์์ธ | ๊ทผ๋ณธ ์์ธ | ์ต์ ํ ํด๊ฒฐ์ฑ |
|---|---|---|
| RX FIFO Overflow | PIO FIFO ๊น์ด ๋ถ์กฑ(4 Words) ๋ฐ CPU ์ง์ฐ | PIO DREQ ๊ธฐ๋ฐ DMA ์ฒด์ด๋ / ๋ง๋ฒํผ ๋์ |
| Bus Contention | DMA์ ๋์ผ ์ฝ์ด๊ฐ ๋์ผ SRAM ๋ฑ ํฌ ๋์ ์ ๊ทผ | SRAM0(DMA ์ ์ฉ) ๋ฐ SRAM1~2(Core ์ ์ฉ) ๋ถํ ๋ฐฐ์น |
| Data Corruption | ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์ฌ๋ฐฐ์น ๋ฐ ๊ฐ์์ฑ(Visibility) ๋ฏธ๋ณด์ฅ | ARM ์ด์
๋ธ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ ๋ฐฐ๋ฆฌ์ด(__dmb()) ์ ์ฉ |
์์์ ์ดํด๋ณธ ํ๋์จ์ด ๋ ๋ฒจ์ ์ต์ ํ ํธ๋ฌ๋ธ์ํ ์ ๋ต์ ์ ์ฉํ๋ฉด, ์ธ๋ถ FPGA๋ ๊ณ ๊ฐ์ DSP ๋์ ์์ด๋ RP2040๋ง์ผ๋ก ์ด๋น ์๋ฐฑ๋ง ๊ฐ์ ๊ณ ์ ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๋จ 1๋ฐ์ดํธ์ ์ ์ค๋ ์์ด ์๋ฒฝํ๊ณ ์์ ์ ์ผ๋ก ์์งํ ์ ์์ต๋๋ค.