pcie收发数据.使用用户空间io. uIO

// pcie_send_recv.c pcie收发数据.//使用用户空间io. uIO
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#define BAR_SIZE (1024 * 1024)  // 1MB,根据设备调整,每次存1mb数据.

int main() {
    int fd = open("/dev/uio0", O_RDWR);  // 假设设备是 uio0
    if (fd < 0) {
        perror("open /dev/uio0");
        exit(EXIT_FAILURE);
    }
//设备映射到一个内存地址.  fd是这个设备. 返回的bar是指向映射区域的指针,后续通过它访问硬件寄存器
    void *bar = mmap(NULL, BAR_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (bar == MAP_FAILED            ) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }
//用于声明变量可能被程序外部因素意外修改,强制编译器每次直接从内存地址读取最新值,而非使用寄存器中的缓存值。其核心机制是防止编译器优化误判,确保对硬件映射寄存器、多线程共享变量等易变数据的访问准确性。在嵌入式开发中,volatile还被用于处理中断服务程序或外部硬件触发的变量修改,确保程序响应实时状态变化。
    volatile uint32_t *reg = (volatile uint32_t *)bar;

    // 模拟:向设备寄存器写入数据("发送")
    printf("Sending data to PCIe device...\n");
    reg[0] = 0x12345678;  // 写入控制寄存器或数据缓冲区
    reg[1] = 0xABCDEF00;  // 写入更多数据

    // 模拟:从设备寄存器读取数据("接收")
    printf("Receiving data from PCIe device...\n");
    uint32_t recv0 = reg[2];
    uint32_t recv1 = reg[3];

    printf("Received: 0x%08x, 0x%08x\n", recv0, recv1);

    munmap(bar, BAR_SIZE);
    close(fd);
    return 0;
}

posted on 2025-12-25 11:12  张博的博客  阅读(1)  评论(0)    收藏  举报

导航