1 说明
由于开发需要,需要通过memory传输数据,所以使用devmem 方式读写数据,操作linux 内存数据。devmem的方式是提供给驱动开发人员,在应用层能够侦测内存地址中的数据变化,以此来检测驱动中对内存或者相关配置的正确性验证。
2 开发环境
软件环境: ubuntu 虚拟机、arm-xilinx 交叉编译工具链
硬件环境: ZYNQ7010
3 内存地址说明
基本上的内存物理地址都可以访问,但是如果需要ZYNQ的PS 和PL 都能读写数据,需要查看芯片的datasheet,确定哪个地址可以互相读写数据。
通过《ug585-Zynq-7000-TRM.pdf》 的 29章表格“Table 29‐1: Initial OCM/DDR Address Map” 可以得到地址分配。
表3-1 ZYNQ7010 芯片地址分配
从表格3-1得知,DDR的物理地址对应为 0x0010_0000 - 3FFF_FFFF
4 devmem 工具
工具的原理也比较简单,就是应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。
代码如下:
/**
* @addtogroup module_devmem
* @{
*/
/**
* @file
* @brief 内存管理工具,仿照标准linux devmem 工具进行改良,可以自由读写linux内存数据。
* @details 驱动接口。
* @version 1.1.0
* @author sky.houfei
* @date 2019-8-6
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//*****************************************************************************
#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
__LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
#define MAP_SIZE 4096UL //映射的内存区大小(一般为一个叶框大小)
#define MAP_MASK (MAP_SIZE - 1) //MAP_MASK = 0XFFF
//*****************************************************************************
/**
* @brief 直接写入到内存实际的物理地址。
* @details 通过 mmap 映射关系,找到对应的内存实际物理地址对应的虚拟地址,然后写入数据。
* 写入长度,每次最低4字节
* @param[in] writeAddr, unsigned long, 需要操