树莓派4B汇编读取GPIO时无法打开/dev/mem 报error 1b6求助
树莓派4B汇编读取GPIO /dev/mem访问问题解决
核心问题根因
你遇到的编译/运行错误可从以下几个维度排查:
openFile并非Linux系统内置函数,是Stephen Smith所著书籍配套代码中自定义的封装逻辑,必须引入书籍配套的通用辅助代码到工程中才能使用,也可以直接替换为标准Linux系统调用实现打开/dev/mem的逻辑- 树莓派4B的GPIO外设基地址与前代产品不兼容,书籍示例默认适配树莓派3系列,使用的
0x3F200000基地址不适用于4B,4B对应GPIO基地址为0xFE200000,基地址错误会直接导致mmap映射失败,返回对应错误码 - 报错
error 1b6为十六进制编码,转换为十进制为438,对应场景多为无效地址映射请求,优先核对基地址配置 - 访问
/dev/mem需要root权限,即使编译无报错,运行时也需要添加sudo前缀执行二进制文件
可直接运行的代码示例
无需依赖书籍自定义封装,直接使用标准Linux系统调用实现GPIO读取:
/* 树莓派4B GPIO读取汇编示例 */ .equ O_RDWR, 0x0002 .equ O_SYNC, 0x101000 .equ PROT_READ, 0x1 .equ PROT_WRITE, 0x2 .equ MAP_SHARED, 0x01 .equ GPIO_BASE, 0xFE200000 @ 树莓派4B专用GPIO基地址 .equ GPIO_REG_LEN, 0xB4 .global _start _start: @ 打开/dev/mem文件 ldr r0, =devmem_path ldr r1, =(O_RDWR | O_SYNC) mov r2, #0 mov r7, #5 @ open系统调用号 swi 0 mov r4, r0 @ 保存/dev/mem文件描述符 @ 映射GPIO物理地址到进程虚拟地址空间 mov r0, #0 ldr r1, =GPIO_REG_LEN ldr r2, =(PROT_READ | PROT_WRITE) ldr r3, =MAP_SHARED mov r5, #0 ldr r6, =GPIO_BASE mov r7, #192 @ mmap2系统调用号 swi 0 mov r8, r0 @ 保存映射后的虚拟地址首地址 @ 示例:读取GPIO2引脚电平,可修改偏移读取任意引脚 ldr r0, [r8, #0x34] @ GPLEV0寄存器偏移为0x34 mov r1, #1 lsl r1, #2 @ 引脚2对应bit位2 and r0, r1 teq r0, #0 movne r0, #1 @ r0最终存储引脚电平:0为低电平,1为高电平 @ 退出程序,返回电平值可通过echo $?查看 mov r7, #1 swi 0 .data devmem_path: .asciz "/dev/mem"
编译运行指令
- 编译:
gcc -g -nostdlib gpio_read.s -o gpio_read - 运行:
sudo ./gpio_read - 查看返回的引脚电平:
echo $?
适配其他树莓派型号说明
如果需要在其他型号树莓派上运行,只需修改代码中GPIO_BASE常量值即可:
- 树莓派1/Zero系列:
0x20200000 - 树莓派2/3/3B+系列:
0x3F200000 - 直接操作
/dev/mem存在系统稳定性风险,仅建议测试场景使用,生产环境优先选择官方gpiochip驱动接口。
内容的提问来源于stack exchange,提问作者Paul Clements
相关产品推荐
相关产品推荐

