Bird
Raised Fist0
Embedded Cprogramming~20 mins

DMA controller concept in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
DMA Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
DMA Transfer Completion Flag Check

What is the output of this embedded C code snippet simulating a DMA transfer completion flag check?

Embedded C
#include <stdio.h>

#define DMA_FLAG_TC (1 << 1)  // Transfer complete flag

unsigned int DMA_StatusRegister = 0;

void simulate_dma_transfer() {
    DMA_StatusRegister |= DMA_FLAG_TC;  // Set transfer complete flag
}

int main() {
    simulate_dma_transfer();
    if (DMA_StatusRegister & DMA_FLAG_TC) {
        printf("DMA Transfer Completed\n");
    } else {
        printf("DMA Transfer Not Completed\n");
    }
    return 0;
}
ADMA Transfer Not Completed
BCompilation error due to undefined DMA_FLAG_TC
CDMA Transfer Completed
DRuntime error due to invalid memory access
Attempts:
2 left
💡 Hint

Check how the DMA status register flag is set and tested using bitwise AND.

🧠 Conceptual
intermediate
1:30remaining
DMA Controller Purpose

What is the primary purpose of a DMA controller in embedded systems?

ATo transfer data between peripherals and memory without CPU intervention
BTo manage interrupts from multiple devices
CTo increase the CPU clock speed automatically
DTo allow the CPU to directly access external memory faster
Attempts:
2 left
💡 Hint

Think about how DMA helps reduce CPU workload during data transfer.

🔧 Debug
advanced
2:30remaining
DMA Transfer Size Configuration Bug

Identify the error in this DMA transfer size configuration code snippet.

Embedded C
typedef struct {
    unsigned int CCR;
    unsigned int CNDTR;
    unsigned int CPAR;
    unsigned int CMAR;
} DMA_Channel_TypeDef;

DMA_Channel_TypeDef DMA1_Channel1;

void configure_dma_transfer(unsigned int size) {
    DMA1_Channel1.CNDTR = size;
    DMA1_Channel1.CCR |= (1 << 0); // Enable DMA channel
}

int main() {
    configure_dma_transfer(0);
    if (DMA1_Channel1.CNDTR == 0) {
        // Start transfer
        // ...
        return 1;
    }
    return 0;
}
ADMA transfer size is zero, so no data will be transferred
BDMA channel is not enabled due to missing bit set in CCR
CDMA1_Channel1 is not initialized, causing undefined behavior
DDMA transfer size should be set after enabling the channel
Attempts:
2 left
💡 Hint

Check the value assigned to the transfer size and its effect on the transfer.

📝 Syntax
advanced
1:30remaining
DMA Interrupt Handler Syntax

Which option shows the correct syntax for a DMA interrupt handler function in embedded C?

Avoid DMA1_Channel1_IRQHandler(void) -> void { /* handler code */ }
Bint DMA1_Channel1_IRQHandler() { /* handler code */ }
Cvoid DMA1_Channel1_IRQHandler() { /* handler code */ }
Dvoid DMA1_Channel1_IRQHandler(void) { /* handler code */ }
Attempts:
2 left
💡 Hint

Consider the standard C syntax for interrupt handlers in embedded systems.

🚀 Application
expert
3:00remaining
DMA Circular Mode Behavior

Given a DMA configured in circular mode to transfer 4 bytes repeatedly from a peripheral to memory, what will be the value of the transfer count register (CNDTR) after 10 transfers?

Embedded C
typedef struct {
    unsigned int CCR;
    unsigned int CNDTR;
    unsigned int CPAR;
    unsigned int CMAR;
} DMA_Channel_TypeDef;

DMA_Channel_TypeDef DMA1_Channel1 = {0};

void configure_dma_circular(unsigned int size) {
    DMA1_Channel1.CNDTR = size;
    DMA1_Channel1.CCR |= (1 << 5); // Circular mode enable
    DMA1_Channel1.CCR |= (1 << 0); // Enable DMA channel
}

void simulate_transfer() {
    DMA1_Channel1.CNDTR--;
    if (DMA1_Channel1.CNDTR == 0) {
        DMA1_Channel1.CNDTR = 4; // Reload in circular mode
    }
}

int main() {
    configure_dma_circular(4);
    for (int i = 0; i < 10; i++) {
        simulate_transfer();
    }
    return DMA1_Channel1.CNDTR;
}
A4
B2
C0
D6
Attempts:
2 left
💡 Hint

Count how the CNDTR value changes each transfer and resets after reaching zero.

Practice

(1/5)
1. What is the main purpose of a DMA controller in embedded systems?
easy
A. To transfer data between memory and peripherals without CPU involvement
B. To execute arithmetic operations faster
C. To manage power consumption of the CPU
D. To handle interrupts from external devices

Solution

  1. Step 1: Understand DMA controller role

    A DMA controller is designed to move data automatically without CPU intervention.
  2. Step 2: Compare options with DMA function

    Only To transfer data between memory and peripherals without CPU involvement describes data transfer without CPU involvement, which matches DMA's purpose.
  3. Final Answer:

    To transfer data between memory and peripherals without CPU involvement -> Option A
  4. Quick Check:

    DMA = data transfer without CPU [OK]
Hint: DMA moves data automatically, freeing CPU [OK]
Common Mistakes:
  • Confusing DMA with CPU arithmetic operations
  • Thinking DMA manages power or interrupts
  • Assuming DMA executes code
2. Which of the following is the correct way to start a DMA transfer in embedded C?
easy
A. dma_start(source, destination, size);
B. start_dma(source, destination, size);
C. DMA_Transfer(source, destination, size);
D. dma_transfer(source, destination, size);

Solution

  1. Step 1: Identify common DMA function naming

    In embedded C, functions often use lowercase with underscores, like dma_transfer.
  2. Step 2: Check syntax correctness

    dma_transfer(source, destination, size); uses a plausible function name and correct parameter order: source, destination, size.
  3. Final Answer:

    dma_transfer(source, destination, size); -> Option D
  4. Quick Check:

    Correct DMA function syntax = dma_transfer(...) [OK]
Hint: DMA functions usually use lowercase with underscores [OK]
Common Mistakes:
  • Using incorrect function names with uppercase letters
  • Wrong parameter order
  • Assuming DMA functions start with 'start_' prefix
3. Given this code snippet, what will be the value of buffer[0] after DMA transfer?
char source[3] = {10, 20, 30};
char buffer[3] = {0, 0, 0};
dma_transfer(source, buffer, 3);
medium
A. 20
B. 0
C. 10
D. 30

Solution

  1. Step 1: Understand dma_transfer behavior

    The function copies data from source to buffer for the given size (3 bytes).
  2. Step 2: Check first element after transfer

    buffer[0] will be assigned source[0], which is 10.
  3. Final Answer:

    10 -> Option C
  4. Quick Check:

    buffer[0] = source[0] = 10 [OK]
Hint: DMA copies source to destination byte-by-byte [OK]
Common Mistakes:
  • Assuming buffer remains zero
  • Mixing up source and destination
  • Using wrong index for buffer
4. Identify the error in this DMA setup code:
uint8_t src[5] = {1,2,3,4,5};
uint8_t dst[5];
dma_transfer(dst, src, 5);
medium
A. Arrays must be declared as volatile
B. Source and destination parameters are swapped
C. Size parameter should be 4, not 5
D. DMA transfer function missing return type

Solution

  1. Step 1: Check parameter order in dma_transfer

    Correct order is source first, then destination.
  2. Step 2: Analyze given code

    Code calls dma_transfer(dst, src, 5), swapping source and destination.
  3. Final Answer:

    Source and destination parameters are swapped -> Option B
  4. Quick Check:

    Correct order = source, destination [OK]
Hint: Source comes before destination in DMA calls [OK]
Common Mistakes:
  • Mixing source and destination arguments
  • Incorrect size parameter
  • Assuming volatile needed for arrays
5. You want to transfer a large array of 1000 integers from memory to a peripheral using DMA. Which approach is best to optimize CPU usage?
hard
A. Split the transfer into multiple smaller DMA transfers of 100 integers each
B. Use a single DMA transfer for all 1000 integers at once
C. Copy data manually using a CPU loop instead of DMA
D. Disable DMA and use interrupts for each integer transfer

Solution

  1. Step 1: Consider CPU load and DMA transfer size

    Very large DMA transfers may block bus or cause latency; splitting reduces impact.
  2. Step 2: Evaluate options for CPU efficiency

    Splitting into smaller chunks allows CPU to handle other tasks between transfers.
  3. Final Answer:

    Split the transfer into multiple smaller DMA transfers of 100 integers each -> Option A
  4. Quick Check:

    Smaller DMA chunks optimize CPU usage [OK]
Hint: Split large DMA transfers to keep CPU responsive [OK]
Common Mistakes:
  • Assuming one big DMA transfer is always best
  • Using CPU loops wastes CPU time
  • Disabling DMA loses its benefits
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard