You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64平台mmap映射硬件缓存的高效数据同步问题

AArch64平台下/dev/mem映射硬件缓冲区的缓存同步问题

在AArch64平台上,我通过C代码使用mmap /dev/mem将硬件缓冲区映射到进程虚拟地址空间。目前遇到的问题是:如果不清理文件系统缓存,mmap无法读取到硬件缓冲区中的真实数据,希望找到比清理缓存更高效的数据同步方式。

已尝试的解决方案

  • 写入mmap区域末尾几个字节标记脏页,再调用fsync()
  • 每次读取前先解除映射再重新映射
  • 使用lseek()和read()替代mmap
  • 调用posix_fadvise(devmem_fd, 0, 0, POSIX_FADV_DONTNEED)
  • 打开文件描述符时添加O_SYNC标志
  • 每次读取前添加超过1秒的延时
  • 打开文件描述符时添加O_DIRECT标志:触发EINVAL(无效参数)错误
  • 在mmap变量前添加volatile关键字
  • 每次读取前调用msync(mmap, SIZE, MS_INVALIDATE)

编译时已使用-O0编译选项,但以上方案均无效,清理缓存前后读取的数据存在差异。

相关代码

// Global State
volatile uint32_t *bramCtrl = NULL;

void init(/* ... */) {
    // ...

    devmem_fd = open("/dev/mem", O_RDWR | O_SYNC );
    if (devmem_fd < 0) {
        std::cerr << "Failed to open /dev/mem" << std::endl;
        exit(1);
    }
    bramCtrl = (volatile uint32_t *)mmap(NULL, BRAM_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, devmem_fd, BRAM_MEMORY_ADDRESS);
    if(MAP_FAILED == bramCtrl){
        printf("Failed to map bram memory\n");
        close(devmem_fd);
        exit(1);
    }

    // ...   
}

std::vector<uint32_t> MEM::readBram(uint32_t offset, uint32_t size) {

    volatile uint32_t* buffer = (volatile uint32_t*)malloc(sizeof(uint32_t)*size);

    std::cout << "Before Dropping Cache:" << std::endl;
    std::copy(bramCtrl, bramCtrl + size, buffer);
    // memcpy(buffer, bramCtrl + offset, sizeof(uint32_t)*size);
    std::vector<uint32_t> r1(buffer,buffer+size);
    for (auto &it : r1) {
        std::cout << "0x" << std::setfill('0') << std::setw(8) << std::hex << it << " "; 
    }
    std::cout << std::endl;

    system("echo 1 > /proc/sys/vm/drop_caches");

    std::cout << "After Dropping Cache:" << std::endl;
    std::copy(bramCtrl, bramCtrl + size, buffer);
    // memcpy(buffer, bramCtrl + offset, sizeof(uint32_t)*size);
    std::vector<uint32_t> r2(buffer, buffer + size);
    for (auto &it : r2) {
        std::cout << "0x" << std::setfill('0') << std::setw(8) << std::hex << it << " "; 
    }
    std::cout << std::endl;
    
    free((uint32_t*)buffer);

    return r2;  
}

实际输出

Before Dropping Cache:
0x6999b2a0 0xf3637cb9 0x6194a0a8 0x711a7d87
After Dropping Cache:
0x721a01a0 0x4b041721 0xab0ab0b0 0xc8be3be3

内容的提问来源于stack exchange,提问作者Sthavir Mundre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:22:47