程序控制IO vs DMA:代码流程大对比

文章摘要

DMA(直接内存访问)与程序控制IO的主要区别在于CPU参与程度。程序控制IO(如轮询串口数据)需要CPU持续检查状态并逐字节搬运数据(代码示例展示忙等待过程),效率低下。而DMA模式下(如硬盘数据读取),CPU仅需配置源/目标地址和长度(伪代码示例),启动后DMA控制器自动完成传输,CPU可处理其他任务。实际应用中,操作系统的read()等接口可能隐藏DMA细节,嵌入式开发(如STM32)则通过HAL库直接调用DMA功能。核心优势在于DMA解放了CPU资源,提升系统并发性能。
(字数:150)


一、没有DMA(程序控制IO/轮询IO)代码例子

读取串口(UART)数据为例,很多单片机/嵌入式系统都用这种方式。

1. 伪代码流程

#define UART_DATA_REG   (*(volatile unsigned char*)0x4000) // 假设串口数据寄存器地址
#define UART_STATUS_REG (*(volatile unsigned char*)0x4001) // 假设串口状态寄存器地址
#define UART_RX_READY   0x01 // 数据准备好标志

void read_uart_data(char* buffer, int length) {
    for(int i = 0; i < length; i++) {
        // 轮询等待数据准备好
        while((UART_STATUS_REG & UART_RX_READY) == 0) {
            // CPU一直在这里忙等,不能干别的事
        }
        // 读取数据
        buffer[i] = UART_DATA_REG;
    }
}

说明:

  • CPU每次都要检查状态寄存器,数据准备好才读。
  • 这就是“老板亲自一趟一趟搬快递”,CPU全程参与。

二、有DMA的伪代码例子

读取硬盘数据到内存为例(实际代码通常在驱动层,这里简化说明流程)。

1. 伪代码流程

// 假设有DMA控制器的寄存器
#define DMA_SRC_ADDR   (*(volatile unsigned int*)0x5000)
#define DMA_DST_ADDR   (*(volatile unsigned int*)0x5004)
#define DMA_LENGTH     (*(volatile unsigned int*)0x5008)
#define DMA_CONTROL    (*(volatile unsigned int*)0x500C)
#define DMA_START      0x01

void dma_read_from_device(unsigned int device_addr, char* buffer, int length) {
    // 1. 设置DMA源地址(外设缓冲区)
    DMA_SRC_ADDR = device_addr;
    // 2. 设置DMA目标地址(内存)
    DMA_DST_ADDR = (unsigned int)buffer;
    // 3. 设置传输长度
    DMA_LENGTH = length;
    // 4. 启动DMA
    DMA_CONTROL = DMA_START;
    // 5. CPU可以去干别的事,等DMA完成后会触发中断
}

说明:

  • CPU只负责配置DMA,启动后就不用管了。
  • DMA控制器自动搬运数据,搬完后通过中断通知CPU。

三、对比总结

方式代码特点CPU状态
程序控制IO轮询+逐字节搬运全程参与
DMA方式配置DMA,自动搬运可做其他任务

四、现实中的应用层代码

在操作系统中,应用层代码通常看不到DMA的细节,比如用read()读取文件,底层可能用DMA,也可能不用,取决于驱动实现。

// 应用层代码
int fd = open("/dev/ttyS0", O_RDONLY);
char buf[100];
read(fd, buf, 100); // 你看不到底层是轮询还是DMA

五、嵌入式开发中DMA的常见用法(STM32为例)

// STM32 HAL库伪代码
HAL_UART_Receive_DMA(&huart1, buffer, length);
// 启动DMA接收,CPU不用管,接收完成后会回调中断函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你一身傲骨怎能输

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值