5.5.8 · D3 · Coding › Embedded Systems & Real-Time Software › DMA — memory-to-memory, peripheral-to-memory without CPU
Yeh page DMA ka exhaustive drill room hai. Parent note ne formulas banaye; yahan hum unhe har kone mein push karte hain — har transfer direction, tricky zero aur degenerate inputs, limiting cases, ek real-world word problem, aur ek exam-style twist jo ek trap chupaata hai.
Sab kuch parent ke do formulas par tika hai. Chaliye unhe phir se state karte hain taaki koi symbol unexplained na rahe:
Definition Do address-step symbols
Δ S aur Δ D
Har beat par, DMA controller apne source aur destination pointers ko ek fixed amount se update karta hai. Hum un amounts ko naam dete hain:
Δ S = ==per-beat change in source address, bytes mein== ("read pointer har item ke baad kitna jump karta hai").
Δ D = ==per-beat change in destination address, bytes mein== ("write pointer har item ke baad kitna jump karta hai").
Dono ke liye teen legal values: + w (increment — ek item aage chalte hain), 0 (fixed — wahi rehte hain, hardware register ke liye), ya − w (decrement — ek item peeche chalte hain). Hum neeche ke examples mein inme se har ek use karte hain.
Har DMA question jo tumhare saamne aayega, in cells mein se kisi ek mein fit hoga. Neeche ke examples [CELL n] label kiye gaye hain taaki tum dekh sako ki poora space cover hua hai. (Yaad karo upar se: Δ S , Δ D bytes mein per-beat source/destination address steps hain; + w = forward, 0 = fixed, − w = backward.)
Cell
Case class
Kya special hai
Covered by
1
Mem-to-mem , dono addresses increment
Δ S = Δ D = + w
Ex. 1
2
Periph-to-mem , source fixed
Δ S = 0 , Δ D = + w
Ex. 2
3
Mem-to-periph , dest fixed
Δ S = + w , Δ D = 0
Ex. 3
4
Address decrement mode
Δ = − w (backward walk)
Ex. 4
5
Degenerate: N = 0
kuch move nahi hota — kya time = 0?
Ex. 5
6
Degenerate: wait states c > 1
slow peripheral har beat inflate karta hai
Ex. 6
7
Limiting case: width sweep
throughput jab w : 1 → 4
Ex. 7
8
Real-world word problem
audio streaming, must-not-miss deadline
Ex. 8
9
Exam twist
mixed units + "started ≠ done" trap
Ex. 9
Worked example Ex. 1 — DMA se array copy karo
512 words ki ek array copy karo, har word w = 4 bytes, mem-to-mem. Bus clock f = 72 MHz, c = 1 cycle/beat.
Dhundho: total bytes B , transfer time t , aur address deltas Δ S , Δ D .
Forecast: compute karne se pehle andaza lagao — kya t nanoseconds, microseconds, ya milliseconds mein hoga? (72 million/s par 512 tiny beats...)
B = N w = 512 × 4 = 2048 bytes.
Yeh step kyun? Total bytes hamesha count × width hota hai — baad mein throughput sanity-check karne ke liye zaroori hai.
t = f N c = 72 × 1 0 6 512 × 1 ≈ 7.11 μ s .
Yeh step kyun? Har word ke liye ek beat, har beat ke liye ek cycle, toh 72 MHz clock ke 512 cycles.
Δ S = Δ D = + w = + 4 . Read pointer aur write pointer dono har beat mein 4 bytes aage step karte hain.
Yeh step kyun? Mem-to-mem dono buffers ko walk karta hai, kyunki dono sides distinct RAM regions hain jo sequentially fill/empty ho rahi hain.
Neeche ki figure yeh draw karti hai: blue slots source RAM hain, green slots destination RAM, aur har orange arrow ek beat hai jo src[i] ko dst[i] tak le jaata hai. Dhyaan do ki dono index labels lock-step mein advance karte hain — yahi Δ S = Δ D = + 4 visually dikhai deta hai.
Figure 1 — Mem-to-mem: read pointer (blue) aur write pointer (green) dono aage march karte hain, har beat par ek orange arrow.
Verify: Throughput = w f / c = 4 × 72 × 1 0 6 = 288 MB/s. Phir B / throughput = 2048/ ( 288 × 1 0 6 ) ≈ 7.11 μ s — step 2 se match karta hai. ✓ Units: bytes ÷ (bytes/s) = seconds. ✓
Isse memcpy and Block Copy software mein karne se compare karo — CPU yahan ~4 cycles/word burn karega instead of pipeline free karne ke.
Worked example Ex. 2 — ADC samples RAM mein log karo
Ek ADC 12-bit results ko 16-bit (2-byte) RAM slots mein likhta hai, periph-to-mem. N = 2000 samples, f = 48 MHz, c = 1 .
t , throughput, aur deltas dhundho.
Forecast: ADC ka data register ek hardware address hai. Kya Δ S + 2 hoga ya 0 ?
Δ S = 0 , Δ D = + w = + 2 .
Yeh step kyun? Peripheral register (ADC->DR) ek single fixed address hai — naye samples usi jagah appear hote hain. Dekho Memory-Mapped IO . Hum baar baar usi jagah se read karte hain lekin successive RAM slots mein scatter karte hain.
t = f N c = 48 × 1 0 6 2000 ≈ 41.7 μ s .
Yeh step kyun? 2000 beats, har ek 1 cycle, 48 M cycles/s.
Throughput = w f / c = 2 × 48 × 1 0 6 = 96 MB/s.
Yeh step kyun? Har beat 2 bytes carry karta hai; beat rate hai f / c = 48 M/s.
Figure mein, baayi taraf ka single red box ek peripheral register (ADC->DR) hai — har orange arrow usi same box se shuru hota hai (Δ S = 0 ), phir bhi har ek alag green RAM slot mein land karta hai jo daayein move ho raha hai (Δ D = + 2 ). Ek fixed source se yeh fan-out hi periph-to-mem ka poora idea hai.
Figure 2 — Periph-to-mem: saare arrows usi fixed red register se nikalte hain; sirf green destination aage badhta hai.
Verify: B = 2000 × 2 = 4000 bytes. B / throughput = 4000/ ( 96 × 1 0 6 ) ≈ 41.7 μ s ✓. Aur note karo ki N throughput mein appear nahi hua — jaise parent mein promise kiya tha, rate sirf w , f , c par depend karta hai.
Common mistake Classic periph-to-mem trap
Yahan Δ S = + w set karna DMA ko ADC->DR, phir ADC->DR + 2, phir +4... read karaayega... neighbouring registers mein bhatkate hue → silent corruption. Ek peripheral source ko fix karo; sirf RAM destination ko increment karo.
Worked example Ex. 3 — DAC ko waveform stream karo
1024 samples ek RAM buffer se DAC (DAC ) ko push karo, w = 2 , f = 48 MHz, c = 1 .
Forecast: ab kaun sa delta zero hai?
Δ S = + w = + 2 (buffer aage se khaali hota hai), Δ D = 0 (DAC register fixed).
Yeh step kyun? Mem-to-periph, Ex. 2 ka mirror hai — destination single hardware register hai.
t = f N c = 48 × 1 0 6 1024 × 1 ≈ 21.3 μ s .
Yeh step kyun? Full formula explicitly c = 1 ke saath state karo: 1024 beats, har beat par ek cycle, 48 MHz par.
Delivered sample rate: agar DAC ek waqt mein ek item request karta hai, toh DMA hardware request line se rate-matched hota hai — yeh exactly tab deliver karta hai jab DAC ready hota hai.
Yeh step kyun? Hardware-triggered transfers har request par ek beat karte hain; peripheral pace set karta hai, bus nahi.
Figure Ex. 2 ka mirror hai: ab baayin taraf green RAM buffer ke arrows successive slots se nikalte hain (Δ S = + 2 ), saare daayein taraf single red DAC register mein converge karte hain (Δ D = 0 ). Yeh periph-to-mem ke fan-out ka fan-in mirror image hai.
Figure 3 — Mem-to-periph: successive RAM slots (green) ek fixed DAC register (red) mein feed karte hain; source chalta hai, destination frozen.
Verify: B = 1024 × 2 = 2048 bytes. Throughput = 2 × 48 × 1 0 6 = 96 MB/s; 2048/ ( 96 × 1 0 6 ) ≈ 21.3 μ s ✓, step 2 se match karta hai.
Continuous audio ke liye tum isse Circular and Double Buffering ke saath loop karoge taaki buffer refill hota rahe jab DMA doosra half drain kare.
Δ = − w se buffer reverse-copy karo
Kuch controllers address ko backward step kar sakte hain. Ek 64-byte block ka byte order reverse karo, mem-to-mem, w = 1 : source ko aage padhte hain lekin destination ko end se start tak likhte hain. f = 48 MHz, c = 1 .
N , t , aur dono deltas dhundho — sign ke saath.
Forecast: agar write pointer backward move kare, toh kya time bilkul bhi change hoga? (Socho: kya formula direction ki parwaah karta hai?)
N = 64 (har item ek byte, 64 bytes). Δ S = + w = + 1 (start→end padho). Δ D = − w = − 1 (end→start likho).
Yeh step kyun? Reverse karne ka matlab hai destination slot 63 ko source byte 0 milta hai, slot 62 ko byte 1 milta hai, etc. Negative step exactly "har beat ek item backward chalo" hai.
t = f N c = 48 × 1 0 6 64 × 1 ≈ 1.33 μ s .
Yeh step kyun? Timing formula beats count karta hai, direction nahi. Backward step bhi ek beat leta hai, isliye t same size ke forward copy se unchanged hai — direction free hai.
Reversal ki correctness: beat i ke baad, destination address = D 0 − i ⋅ w . Jab i , 0 … 63 run karta hai, hum D 0 se D 0 − 63 tak exactly ek baar har ek ko touch karte hain — koi overlap nahi, koi gap nahi.
Yeh step kyun? Yeh "cover all cases" check hai: decrement ko har slot exactly ek baar visit karna chahiye, warna tum data corrupt ya skip karte ho.
Verify: B = 64 × 1 = 64 bytes. Throughput = 1 × 48 × 1 0 6 = 48 MB/s; 64/ ( 48 × 1 0 6 ) ≈ 1.33 μ s ✓, 64 bytes ke forward copy jaisa — confirming karta hai ki direction timing affect nahi karta.
Common mistake Decrement mode mein sign confusion
Kyun sahi lagta hai: tumne habit se "increment" enable kar diya. Fix: reverse copy ke liye tumhe destination ko high address par start karna aur Δ D = − w set karna hai. Dono mein se sirf ek karna (high start with + w , ya low start with − w ) pointer ko buffer se bahar le jaayega → memory corruption.
Worked example Ex. 5 — Agar count zero ho toh?
Ek programmer transfer setup karta hai lekin ek bug N = 0 chhodta hai. f = 48 MHz, c = 1 , w = 4 .
t kya hai? Kya transfer-complete interrupt phir bhi fire karta hai?
Forecast: kya t = 0 exactly hai, ya koi hidden setup cost hai?
t DMA = f N c = 48 × 1 0 6 0 × 1 = 0 s .
Yeh step kyun? Formula beats count karta hai; zero beats = zero transfer time.
Lekin setup zero nahi hai. Start karne se pehle, CPU ko chaar control registers program karne padte hain — parent ki S.C.A.M. checklist yaad karo: S ource address, C ount, A ddress-increment mode, aur M ode/trigger. Chaar isliye hain kyunki yeh transfer ki chaar independent cheezein hain, aur har ek apne hardware register mein rehti hai. Inhe likhna N ki parwaah kiye bina O ( 1 ) CPU cycles leta hai.
Yeh step kyun? Parent ka t DMA formula explicitly kehta hai "ignoring setup". Degenerate N = 0 expose karta hai ki sirf remaining cost woh fixed four-register overhead hai.
Throughput = w f / c = 4 × 48 × 1 0 6 = 192 MB/s abhi bhi defined hai — lekin yeh ek rate hai, amount nahi. B = 0 ke saath, tum 192 MB/s par kuch nahi move karte, yaani 0 bytes.
Yeh step kyun? Throughput sirf w , f , c hai; yeh kabhi N par depend nahi karta tha, isliye finite rehta hai jab kuch move nahi hota. Yeh clean illustration hai ky N cancel kyun hota hai .
Verify: B = 0 × 4 = 0 bytes; 0/ ( 192 × 1 0 6 ) = 0 s , step 1 ke saath consistent. ✓ Bahut saare controllers N = 0 ko "already complete" treat karte hain aur immediately interrupt fire karte hain — hamesha iske against guard karo.
c > 1 ke saath ek slow peripheral
Ek slow external SPI flash wait states insert karta hai, isliye c = 5 cycles/beat. N = 1000 items padho, w = 1 , f = 24 MHz.
t aur throughput dhundho; ideal c = 1 case se compare karo.
Forecast: agar har beat 5× slow ho, toh kya throughput 5× girta hai?
t = f N c = 24 × 1 0 6 1000 × 5 ≈ 208.3 μ s .
Yeh step kyun? Wait states per beat cycles multiply karte hain, isliye total cycles = N ⋅ c = 5000 .
Throughput = c w f = 5 1 × 24 × 1 0 6 = 4.8 MB/s.
Yeh step kyun? Throughput ke denominator mein c hai — bada c ⇒ proportionally lower rate. Yeh exactly parent ka "not free for the memory subsystem" idea hai.
Ideal c = 1 deta t = 1000/ ( 24 × 1 0 6 ) ≈ 41.7 μ s aur 24 MB/s.
Yeh step kyun? 5 × penalty explicitly dikhata hai: 208.3/41.7 = 5 , 24/4.8 = 5 .
Verify: B = 1000 bytes. B / throughput = 1000/ ( 4.8 × 1 0 6 ) ≈ 208.3 μ s ✓. 5× slowdown identically appear hota hai time mein (×5) aur throughput mein (÷5). ✓
Worked example Ex. 7 — Same bytes, alag width
Tumhe exactly 4096 bytes move karne hain f = 48 MHz, c = 1 par. w = 1 , 2 , 4 try karo. Har baar N = 4096/ w . Har ke liye t dhundho aur limiting behaviour.
Forecast: w double karna — kya t aadha ho jaata hai?
w = 1 ⇒ N = 4096 : t = ( 48 × 1 0 6 ) 4096 ≈ 85.3 μ s .
w = 2 ⇒ N = 2048 : t = ( 48 × 1 0 6 ) 2048 ≈ 42.7 μ s .
w = 4 ⇒ N = 1024 : t = ( 48 × 1 0 6 ) 1024 ≈ 21.3 μ s .
Yeh steps kyun? Fixed B ka matlab hai N = B / w , isliye t = f N c = w f B c — time inversely proportional hai w se. Wider beats, same payload, kam cycles.
Limiting takeaway: jaise w badhta hai, t same factor se ghatta hai — lekin w binaa bound ke nahi badhta. Do hard ceilings isko rokti hain:
Bus width: physical data bus har beat par ek fixed number se zyaada bytes carry nahi kar sakta (typically 4 on a 32-bit bus). 4-byte bus par w = 8 maangna impossible hai — hardware ko anyway do beats chahiye honge, isliye bus width se aage koi gain nahi.
Alignment: tum sirf tab w = 4 use kar sakte ho jab source aur destination dono start addresses 4 ke multiples hon. Ek misaligned buffer controller ko smaller w (aksar w = 1 ) par force karta hai, silently speedup mita deta hai.
Yeh step kyun? Limit infinite speedup nahi hai. Practical rule hai: widest width use karo jo bus aur buffer alignment dono allow karein — usse aage extra "width" kuch nahi kharidta kyunki hardware simply per beat zyaada move nahi kar sakta.
Bar chart teen times dikhata hai jo w badhne par shrink hote hain: red (w = 1 ) sabse lamba hai, green (w = 4 ) uski height ka chautha hissa hai. Gray curved arrow trend annotate karta hai — "wider beats = fewer cycles." Adjacent bars ke beech halving heights se directly padho.
Figure 4 — Fixed 4096-byte payload: transfer time 1/ w ke roop mein girta hai; width ka har doubling bar ko aadha kar deta hai, jab tak bus width / alignment cap na kare.
Verify: t ∝ 1/ w : 85.3/42.7 ≈ 2 , 85.3/21.3 ≈ 4 ✓. Teeno same B = 4096 bytes move karte hain.
Worked example Ex. 8 — Kya DMA 48 kHz stereo audio ke saath keep up karega?
Stereo audio: 48 000 frames/s , har frame = 2 channels × 2 bytes = 4 bytes. Ek DMA buffer ko DAC tak drain karta hai, w = 4 , f = 72 MHz, c = 1 . Tum N = 256 frames ke chunks mein double buffering use karke refill karte ho.
Sawaal: kya har 256-frame DMA agla audio chunk needed hone se pehle finish ho jaata hai?
Forecast: audio data slowly chahiye (human ears); DMA fast move karta hai. Bahut bada margin hona chahiye — lekin kitna?
Deadline — audio 256 frames consume karne ka time: t deadline = 48000 256 ≈ 5.33 ms .
Yeh step kyun? DAC 48000 frames/s khaata hai; 256 frames 256/48000 seconds chalte hain. Yahi hamaara budget hai.
DMA time 256 frames move karne ke liye: t DMA = f N c = 72 × 1 0 6 256 × 1 ≈ 3.56 μ s .
Yeh step kyun? Har frame ke liye ek beat (w = 4 ), 256 beats at 72 MHz, har beat ke liye ek cycle.
Margin = t deadline / t DMA = 5.33 × 1 0 − 3 /3.56 × 1 0 − 6 ≈ 1500 × .
Yeh step kyun? Ratio batata hai ki DMA ~1500× faster finish karta hai jaana chahiye se — CPU ke liye agla buffer compute karne aur ISR fire hone ke liye enormous slack.
Verify: B = 256 × 4 = 1024 bytes per chunk. Throughput = 4 × 72 × 1 0 6 = 288 MB/s; 1024/ ( 288 × 1 0 6 ) ≈ 3.56 μ s ✓. Deadline ≈ 5.33 ms ≫ 3.56 μ s ⇒ easily meets deadline. ✓
Worked example Ex. 9 — Trick question
"Ek DMA N = 5000 items, w = 2 , f = 100 MHz, c = 1 ke bus par copy karne ke liye set hai. dma_start() call karne ke turant baad, CPU buffer[4999] read karta hai. Transfer time t hai. (a) t µs mein dhundho. (b) Kya read valid hai? (c) CPU ko kiska wait karna chahiye?"
Forecast: numbers easy hain — twist (b)/(c) mein hai. Aage padhne se pehle trap spot karo.
(a) t = f N c = 100 × 1 0 6 5000 × 1 = 50 μ s .
Yeh step kyun? 5000 beats, har ek 1 cycle, 100 M cycles/s. Unit dhyaan do: 5000/1 0 8 = 5 × 1 0 − 5 s = 50 μ s .
(b) Nahi — read invalid hai. DMA asynchronous hai; dma_start() sirf ise launch karta hai. Read ke instant par, last item (buffer[4999]) almost certainly abhi tak write nahi hua.
Yeh step kyun? Yeh parent ki "started ≠ done" mistake hai. CPU mover se aage race karta hai aur stale bytes pakad leta hai.
(c) CPU ko transfer-complete interrupt / flag (dekho Interrupts and ISRs ) ka wait karna chahiye — aur , agar data cache exist karta hai, toh buffer region ko pehle invalidate karo taaki fresh RAM re-read kare (Cache Coherency ).
Yeh step kyun? Do independent hazards hain: timing (done ka wait karo) aur coherency (cache stale copies hold kar sakta hai). Dono cover karna yahi twist test karta hai.
Verify: B = 5000 × 2 = 10000 bytes; throughput = 2 × 100 × 1 0 6 = 200 MB/s; 10000/ ( 200 × 1 0 6 ) = 5 × 1 0 − 5 s = 50 μ s ✓.
Recall Kya humne har cell hit kiya?
Mem-to-mem (Ex.1) ::: ✓ dono deltas = +w
Periph-to-mem (Ex.2) ::: ✓ source fixed (0), dest +w
Mem-to-periph (Ex.3) ::: ✓ source +w, dest fixed (0)
Decrement mode (Ex.4) ::: ✓ Δ = − w , timing unchanged
N = 0 degenerate (Ex.5) ::: ✓ t=0 lekin setup (four SCAM regs) ≠ 0
Wait states c > 1 (Ex.6) ::: ✓ t aur throughput mein 5× penalty
Width sweep limit (Ex.7) ::: ✓ t ∝ 1/ w , capped by bus width / alignment
Real-world deadline (Ex.8) ::: ✓ ~1500× margin, audio deadline meet hoti hai
Exam twist (Ex.9) ::: ✓ async + cache coherency traps
Har worked example ke liye: "B-T-T-D" — B ytes compute karo, T ime, T hroughput, phir D eltas check karo (kaun sa address move karta hai, aur kis direction mein: + w , 0 , ya − w ). Agar answer B / throughput se disagree kare, tumne ek unit drop kiya.