Bird
Raised Fist0
Embedded Cprogramming~20 mins

Peripheral-to-memory transfer 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
What is the output of this DMA transfer status check?
Consider this embedded C code snippet that checks the status of a DMA peripheral-to-memory transfer. What will be printed?
Embedded C
#include <stdio.h>
#include <stdint.h>

#define DMA_TRANSFER_COMPLETE 1

volatile uint8_t DMA_Status = DMA_TRANSFER_COMPLETE;

int main() {
    if (DMA_Status == DMA_TRANSFER_COMPLETE) {
        printf("Transfer Complete\n");
    } else {
        printf("Transfer Incomplete\n");
    }
    return 0;
}
ACompilation error
BTransfer Incomplete
CTransfer Complete
DNo output
Attempts:
2 left
💡 Hint
Look at the value of DMA_Status and the condition in the if statement.
🧠 Conceptual
intermediate
1:30remaining
Which statement best describes peripheral-to-memory DMA transfer?
In embedded systems, what does a peripheral-to-memory DMA transfer do?
AIt moves data from a peripheral device directly into system memory without CPU intervention.
BIt moves data from system memory to a peripheral device using CPU instructions.
CIt copies data between two peripheral devices using CPU interrupts.
DIt requires the CPU to manually read and write each data byte between peripheral and memory.
Attempts:
2 left
💡 Hint
Think about what DMA stands for and its purpose.
🔧 Debug
advanced
2:30remaining
What error does this DMA transfer code cause?
Examine the following code snippet for a peripheral-to-memory DMA transfer. What error will occur when compiling or running this code?
Embedded C
void start_dma_transfer(uint32_t *peripheral_reg, uint32_t *memory_buffer, uint32_t length) {
    for (int i = 0; i < length; i++) {
        memory_buffer[i] = *peripheral_reg;
    }
}

int main() {
    uint32_t peripheral_data = 0x12345678;
    uint32_t buffer[5] = {0};
    start_dma_transfer(&peripheral_data, buffer, 5);
    return 0;
}
ABuffer overflow due to accessing memory_buffer[length] index
BCompilation error because of missing semicolon
CRuntime segmentation fault due to null pointer dereference
DNo error, code runs correctly
Attempts:
2 left
💡 Hint
Check the loop boundary condition carefully.
📝 Syntax
advanced
2:00remaining
Which option correctly initializes a DMA peripheral-to-memory transfer in C?
Given the following incomplete code to configure a DMA transfer, which option correctly completes the initialization without syntax errors?
Embedded C
typedef struct {
    uint32_t CCR;
    uint32_t CNDTR;
    uint32_t CPAR;
    uint32_t CMAR;
} DMA_Channel_TypeDef;

void dma_init(DMA_Channel_TypeDef *dma_channel, uint32_t peripheral_addr, uint32_t memory_addr, uint32_t length) {
    dma_channel->CPAR = peripheral_addr;
    dma_channel->CMAR = memory_addr;
    dma_channel->CNDTR = length;
    // Configure control register
    dma_channel->CCR = 
A0x00000001;; // Double semicolon causes syntax error
B0x00000001 // Enable DMA channel (missing semicolon)
C0x00000001 = dma_channel->CCR; // Invalid assignment
D0x00000001; // Enable DMA channel
Attempts:
2 left
💡 Hint
Remember to end statements with a semicolon in C.
🚀 Application
expert
3:00remaining
How many bytes are transferred in this peripheral-to-memory DMA example?
Consider this embedded C code configuring a DMA transfer from a peripheral to memory. How many bytes will be transferred?
Embedded C
#define DMA_BUFFER_SIZE 8

uint16_t dma_buffer[DMA_BUFFER_SIZE];

void configure_dma() {
    DMA_Channel_TypeDef dma_channel;
    dma_channel.CPAR = (uint32_t)&PERIPHERAL_DATA_REGISTER;
    dma_channel.CMAR = (uint32_t)dma_buffer;
    dma_channel.CNDTR = DMA_BUFFER_SIZE;
    dma_channel.CCR = 0x00000001; // Enable DMA channel
}

int main() {
    configure_dma();
    return 0;
}
A32 bytes
B16 bytes
C8 bytes
D64 bytes
Attempts:
2 left
💡 Hint
Consider the data type size and the number of elements transferred.

Practice

(1/5)
1. What is the main purpose of peripheral-to-memory transfer in embedded systems?
easy
A. To execute arithmetic operations on peripheral data
B. To send data from memory back to the peripheral device
C. To move data directly from a peripheral device to memory without CPU intervention
D. To reset the peripheral device after data transfer

Solution

  1. Step 1: Understand peripheral-to-memory transfer

    This transfer moves data directly from a peripheral device to memory, bypassing the CPU to improve efficiency.
  2. Step 2: Identify the main purpose

    The main goal is to reduce CPU load by letting hardware handle data movement.
  3. Final Answer:

    To move data directly from a peripheral device to memory without CPU intervention -> Option C
  4. Quick Check:

    Peripheral-to-memory transfer = direct data move without CPU [OK]
Hint: Peripheral-to-memory means data moves without CPU help [OK]
Common Mistakes:
  • Confusing peripheral-to-memory with memory-to-peripheral transfer
  • Thinking CPU processes data during transfer
  • Assuming transfer resets the device
2. Which of the following is the correct way to enable DMA for peripheral-to-memory transfer in embedded C?
easy
A. DMA_Channel->CCR = DMA_CCR_EN << 1;
B. DMA_Channel->CCR |= DMA_CCR_EN;
C. DMA_Channel->CCR &= ~DMA_CCR_EN;
D. DMA_Channel->CCR = 0;

Solution

  1. Step 1: Understand DMA enable bit setting

    To enable DMA channel, the enable bit (DMA_CCR_EN) must be set using bitwise OR to preserve other bits.
  2. Step 2: Analyze options

    DMA_Channel->CCR |= DMA_CCR_EN; sets the enable bit correctly with |=. DMA_Channel->CCR = 0; clears all bits, disabling DMA. DMA_Channel->CCR &= ~DMA_CCR_EN; clears the enable bit. DMA_Channel->CCR = DMA_CCR_EN << 1; shifts enable bit incorrectly.
  3. Final Answer:

    DMA_Channel->CCR |= DMA_CCR_EN; -> Option B
  4. Quick Check:

    Enable DMA by setting bit with |= [OK]
Hint: Use |= to set enable bit without clearing others [OK]
Common Mistakes:
  • Using = instead of |= clears other bits
  • Clearing enable bit instead of setting it
  • Shifting bits incorrectly
3. Given the following code snippet, what will be the value of memory_buffer[0] after DMA transfer completes?
uint8_t peripheral_data = 0x55;
uint8_t memory_buffer[1] = {0x00};
// DMA configured to transfer 1 byte from &peripheral_data to memory_buffer
// DMA transfer completes here
medium
A. 0x55
B. 0x00
C. 0xFF
D. Undefined (random value)

Solution

  1. Step 1: Understand DMA transfer setup

    DMA is set to transfer 1 byte from peripheral_data (0x55) to memory_buffer.
  2. Step 2: Determine memory_buffer[0] after transfer

    After transfer, memory_buffer[0] will hold the value 0x55 copied from peripheral_data.
  3. Final Answer:

    0x55 -> Option A
  4. Quick Check:

    DMA copies 0x55 to memory_buffer[0] [OK]
Hint: DMA copies source byte to destination buffer [OK]
Common Mistakes:
  • Assuming memory_buffer stays unchanged
  • Confusing peripheral_data value
  • Thinking DMA sets memory to 0xFF
4. Identify the error in this DMA peripheral-to-memory transfer setup code snippet:
DMA_Channel->CPAR = (uint32_t)&memory_buffer;
DMA_Channel->CMAR = (uint32_t)&peripheral_data;
DMA_Channel->CNDTR = 4;
DMA_Channel->CCR &= ~DMA_CCR_EN;
DMA_Channel->CCR |= DMA_CCR_EN;
medium
A. The DMA channel is enabled before setting transfer length
B. The DMA channel is enabled without disabling first
C. The transfer length (CNDTR) is set after enabling DMA
D. The peripheral address and memory address are swapped

Solution

  1. Step 1: Recall DMA register roles

    CPAR holds peripheral (source) address, CMAR holds memory (destination) address for peripheral-to-memory transfer.
  2. Step 2: Check the code assignments

    The code sets CPAR = &memory_buffer (should be peripheral), CMAR = &peripheral_data (should be memory). Addresses are swapped.
  3. Final Answer:

    The peripheral address and memory address are swapped -> Option D
  4. Quick Check:

    CPAR=peripheral, CMAR=memory [OK]
Hint: Peripheral address = CPAR, Memory address = CMAR [OK]
Common Mistakes:
  • Swapping peripheral and memory addresses
  • Enabling DMA before setting parameters
  • Not disabling DMA before re-enabling
5. You want to transfer 8 bytes from a UART peripheral data register to a memory buffer using DMA. Which sequence correctly sets up the DMA for peripheral-to-memory transfer?
hard
A. Set DMA peripheral address to UART data register; set memory address to buffer; set transfer length to 8; enable DMA channel
B. Set DMA memory address to UART data register; set peripheral address to buffer; set transfer length to 8; enable DMA channel
C. Set DMA peripheral address to buffer; set memory address to UART data register; set transfer length to 8; enable DMA channel
D. Set DMA transfer length to 8; enable DMA channel; set peripheral and memory addresses afterwards

Solution

  1. Step 1: Identify source and destination

    Source is UART data register (peripheral), destination is memory buffer.
  2. Step 2: Set DMA registers correctly

    Peripheral address register (CPAR) must point to UART data register, memory address register (CMAR) to buffer, transfer length to 8 bytes, then enable DMA channel.
  3. Final Answer:

    Set DMA peripheral address to UART data register; set memory address to buffer; set transfer length to 8; enable DMA channel -> Option A
  4. Quick Check:

    Peripheral = source, Memory = destination, length set before enable [OK]
Hint: Peripheral address = source, memory address = destination [OK]
Common Mistakes:
  • Swapping peripheral and memory addresses
  • Enabling DMA before setting addresses and length
  • Setting transfer length after enabling DMA
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