详解DMA传输中`memcpy`与指针赋值的本质区别:为什么直接赋值指针会失败?


在嵌入式开发和驱动程序编写中,DMA(直接内存访问)传输的正确性直接关系到系统稳定性。许多开发者会遇到这样的困惑:为什么使用memcpy的DMA传输正常,而直接赋值指针却会导致错误? 本文将通过底层原理分析和代码实验,揭示这一现象的根本原因。


一、两种写法的直观对比

1. 正确写法:memcpy拷贝数据

/* 正确写法 */
__u8 *pBuff = malloc(mats_sz); // 预先分配缓冲区
memcpy(pBuff, (__u8*)rd_rio_transfer.user_mmap_handle[0], mats_sz);

2. 错误写法:直接指针赋值

/* 错误写法 */
__u8 *pBuff = NULL;
pBuff = (__u8*)rd_rio_transfer.user_mmap_handle[0]; // 直接赋值指针

二、底层原理深度分析

1. 内存地址的本质差异

关键概念:
  • 虚拟地址 (Virtual Address):CPU看到的地址空间
  • 物理地址 (Physical Address):实际内存硬件的地址
  • DMA地址 (Bus Address):外设看到的地址
内存操作对比:
操作类型 地址类型 内存区域属性
malloc分配 虚拟地址(可能非物理连续) Cacheable, 可写
user_mmap_handle 用户空间映射的虚拟地址 可能带特殊属性
DMA传输目标地址 物理地址或IOVA(IO虚拟地址) Non-cacheable

实验验证
在Linux内核中打印地址类型:

printk("user_mmap_handle virt: %p, phys: %llx\n", 
       rd_rio_transfer.user_mmap_handle[0],
       virt_to_phys(rd_rio_transfer.user_mmap_handle[0]));

2. 缓存一致性陷阱

DMA传输的关键时序:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值