// pcie_send_recv.c pcie收发数据.
#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); // 假设设备是 uio0if (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;
}