1555|0

2015

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

双核通信通过共享内存交换数据ARM端程序的学习 [复制链接]

#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\n");
                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;
}


 
点赞 关注

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表