Ubuntu x64下C++操作内存映射PCI-DIO卡的技术疑问
PCI-DIO卡内存映射写入的疑问与技术指引
设备与环境信息
端口地址定义
Type OFFSET Size IO_PORT(N)_DATA 0x40 + 0xN0 8 bit
最低有效位(LSB)为data0,最高有效位(MSB)为data7。
lspci设备详情
............... NUMA node:0 Region 0: Memory at 92202000 (32bit non-prefetchable) [size=4k] Region 1: Memory at 92200000 (32bit non-prefetchable) [size=8k] ...............
测试代码
// my simple code to write 1 to lower half and 0 to upper half of port 0 #include <stdio.h> int main(){ volatile unsigned int& DIO_CARD = *((volatile unsigned int*)0x92202000); volatile unsigned int& DIO_PORT0 = *(&DIO_CARD + 0x40 + 0x00); DIO_PORT0 &= 0x0F; return 0; }
疑问与解答
疑问1:BAR是否应位于Region 1?如何区分需使用的内存区域?部分设备有多达4个内存区域。
- 无法仅通过lspci输出直接确定哪个Region对应DIO功能的BAR,核心依据是设备官方文档:
- 手册会明确标注每个BAR对应的功能(比如哪些BAR对应DIO端口、哪些对应配置寄存器等)。
- 从大小看,两个Region都能容纳你的端口偏移范围,但必须以手册为准。
- 无文档时可尝试验证:
- 先映射Region 0,写入测试值后用万用表测量端口电平,看是否符合预期;
- 若无效,再尝试Region 1重复测试;
- 操作前务必确认设备读写时序,避免损坏硬件。
- 多BAR设备的区分逻辑一致:每个BAR对应一组功能模块,部分BAR可能用于中断、DMA配置等扩展功能,不能随意猜测。
疑问2:我的机器是64位,为何基地址仅为32位?
- 这是PCI设备的正常行为:
- 很多老款PCI/PCIe设备硬件设计仅支持32位地址空间,未实现64位地址支持;
- 64位系统完全兼容32位PCI地址映射,系统会将32位BAR地址映射到64位地址空间的低32位区域,不影响设备工作;
- 若设备支持64位地址,lspci输出会标注
64bit,例如Region X: Memory at xxxxxxxx (64bit, prefetchable)。
内容的提问来源于stack exchange,提问作者user1538798
相关产品推荐
相关产品推荐

