linux 共享内存通信实验,ZYNQ DDR读写实验 与 简单的双核共享内存通信(LINUX + BARE METAL)...

/*

*ddr read linux application interface

*/

#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

/*****************************************************************************/

#define TEST_ADDR 0x1F000000

/*****************************************************************************/

/**

* @brief 从实际物理地址读取数据。

* @details 通过 mmap 映射关系,找到对应的实际物理地址对应的虚拟地址,然后读取数据。

* 读取长度,每次最低4字节。

* @param[in] readAddr, unsigned long, 需要操作的物理地址。

* @param[out] buf,unsigned char *, 读取数据的buf地址。

* @param[in] bufLen,unsigned long , buf 参数的容量,4字节为单位,如 unsigned long buf[100],那么最大能接收100个4字节。

* 用于避免因为buf容量不足,导致素组越界之类的软件崩溃问题。

* @return len,unsigned long, 读取的数据长度,字节为单位。如果读取出错,则返回0,如果正确,则返回对应的长度。

*/

static int Devmem_Read(unsigned long readAddr, unsigned long* buf, unsigned long len)

{

int i = 0;

int fd,ret;

int offset_len = 0;

void *map_base, *virt_addr;

off_t addr = readAddr;

unsigned long littleEndianLength = 0;

if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)

{

fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno));

return 0;

}

/* Map one page */ //将内核空间映射到用户空间

map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK);

if(map_base == (void *) -1)

{

fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno));

close(fd);

return 0;

}

for (i = 0; i < len; i++)

{

// 翻页处理

if(offset_len >= MAP_MASK)

{

offset_len = 0;

if(munmap(map_base, MAP_SIZE) == -1)

{

fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno));

close(fd);

return 0;

}

map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~MAP_MASK);

if(map_base == (void *) -1)

{

fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno));

close(fd);

return 0;

}

}

virt_addr = map_base + (addr & MAP_MASK);// 将内核空间映射到用户空间操作

buf[i] = *((unsigned long *) virt_addr);// 读取数据

addr += 4;

offset_len += 4;

}

if(munmap(map_base, MAP_SIZE) == -1)

{

fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", __LINE__, __FILE__, errno, strerror(errno));

close(fd);

return 0;

}

close(fd);

return i;

}

/*

*test sample

*/

int main(void)

{

unsigned long len = 2;

unsigned long readData[1024*1024];//1MB

unsigned long addr = TEST_ADDR;

unsigned long i = 0;

while(1)

{

printf("read data\n");

memset(readData, 0, len);

Devmem_Read(addr, readData, len);// 读取数据

for (i = 0; i < len; i++)

{

printf("address = 0x%08x, data = 0x%08x\n", (addr + i * 4), readData[i]);

}

sleep(1);

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值