DSP

关于双核通信通过共享内存交换数据ARM端程序的学习

2019-07-13 12:35发布

#include #include #include #include #include #include #include #include "../shared/protocol.h" static int map_addr(int *fd, off_t phy_addr, size_t length, void **map_base, void **virt_addr); int main(int argc, char **argv) { int fd = -1; void *map_base = NULL; char *dest = NULL; off_t phy_addr = SHARED_BUFFER_ADDR; /*这个地址可以在protocol.h中查到*/ size_t length = SHARED_BUFFER_SIZE; /*protocol.h中的内容:*/ ---------- #ifndef _PROTOCOL_H_ #define _PROTOCOL_H_ /* Memory Map (see ../dsp/c6748.cmd and linux boot arguments) * * 1180_0000 - 1184_0000 4_0000 ( 256 KB) SHDSPL2RAM * 8000_0000 - 8002_0000 2_0000 ( 128 KB) SHRAM * C000_0000 - C7FF_FFFF 800_0000 ( 128 MB) External Memory (DDR2) * ------------------------------------------------------------------------ * C000_0000 - C1FF_FFFF 200_0000 ( 32 MB) Linux * C200_0000 - C2FF_FFFF 100_0000 ( 16 MB) -------- * C300_0000 - C37F_FFFF 80_0000 ( 8 MB) DSP_PROG (code, data) * C380_0000 - C3FF_FFFF 80_0000 ( 8 MB) -------- * C400_0000 - C7FF_FFFF 400_0000 ( 64 MB) Linux */ #define SHARED_BUFFER_ADDR 0xC2000000 #define SHARED_BUFFER_SIZE 0x1000 #endif ---------- /*从上面可以看出实际上所谓的共享内存是板子上DDR2上的一段地址*/ if (map_addr(&fd, phy_addr, length, &map_base, (void **)&dest) < 0) { fprintf(stderr, "fail to map dest "); close(fd); return -1; } while(1) { char src[] = "helloworld"; memcpy(dest, src, sizeof(src)); sleep(1); } munmap(map_base, length); close(fd); return 0; } static int map_addr(int *fd, off_t phy_addr, size_t length, void **map_base, void **virt_addr) { if ((*fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) return -1; /*/dev/mem是物理内存的全映射,包括整个处理器的地址空间,具体包含地址总线上的所有可寻址空间和IO空 间,但要保证这些物理地址是有效的,可以从这些地址上访问到数据。理论上可以映射0-0xffffffff的地址空间。*/ off_t off_page = phy_addr & ~(sysconf(_SC_PAGE_SIZE) - 1); /*sysconf(_SC_PAGE_SIZE)可以得到一页的大小,一般是4096k,因为映射的地址必须的是一页大小的整数倍, 所以可以通过将0x111取反后做与运算,从而将0-3位清零。假如phy_addr是0xE8000020,经过运算之后就是0xE8000000*/ *map_base = mmap(NULL, length + phy_addr - off_page, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, off_page); /*NULL表示不指定地址,内核根据需要分配地址,可以增加程序的可移植性 PROT_READ:表示页可读取 PROT_WRITE:表示页可写 MAP_SHARED:表示与所有其他映射这个对象的进程共享映射空间 */ if (*map_base == (void *) -1) { close(*fd); return -1; } *virt_addr = *map_base + phy_addr - off_page; return 0; }