Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 220 of 9363. Microcontroller Fundamentals and Bare-Metal CFree lesson

Prioritizing Multiple DMA Channels for Resource Contention

Assign static or dynamic priority levels to different DMA streams to manage bus access during simultaneous transfer requests.

In this lesson, you will learn how to configure DMA channel priority levels to ensure critical data movements take precedence when multiple peripherals compete for the system bus.

The Problem: Bus Contention

As you know from our work with the system bus matrix, your microcontroller has multiple "masters" (like the CPU and DMA) competing for access to the same memory or peripherals. If two DMA channels request a data transfer at the exact same moment, the DMA controller must act as an arbiter. Without an explicit priority system, the controller might allow a low-importance transfer—like filling a log buffer—to block a high-importance one, such as real-time audio sampling or motor control data.

Static vs. Dynamic Priority

Most DMA controllers allow you to resolve this "resource contention" using two primary strategies:

  1. Static Priority: You assign a fixed hardware priority level to each channel (e.g., Very High, High, Medium, Low). If two requests hit simultaneously, the controller always grants access to the channel with the higher level. This is the most common approach for deterministic systems.
  2. Round-Robin (Dynamic): If you set channels to the same priority, the DMA controller cycles through them. After one channel completes a transfer, the controller gives the next turn to the other channel. This prevents "starvation," ensuring that no single slow peripheral hogs the bus.

Implementation Logic

In your configuration code, you typically define these settings during the channel initialization phase. For example, if you are working with an ARM-based DMA controller:

// Configuring channel priority for a high-speed peripheral
DMA_ChannelConfig.Priority = DMA_PRIORITY_VERY_HIGH; 
DMA_Init(DMA_Channel1, &DMA_ChannelConfig);

// Configuring background logging to a lower priority
DMA_ChannelConfig.Priority = DMA_PRIORITY_LOW;
DMA_Init(DMA_Channel2, &DMA_ChannelConfig);

When DMA_Channel1 triggers, the bus matrix immediately grants it access, effectively stalling the lower-priority requests until the channel finishes its current burst or block transfer. By carefully assigning these levels, you ensure that your time-sensitive tasks maintain the throughput required for stable system performance, effectively managing bus traffic like a traffic light at a busy intersection.

Key Takeaway: Use static priority levels to guarantee bus access for time-critical DMA streams and round-robin scheduling to prevent starvation among equally important background data tasks.