树莓派4/Pi400下BCM2835_st_read()返回零的问题求助
解决bcm2835_st_read()返回0的问题
问题概述
- 设备:RPi4、Pi400
- 系统:Raspbian "Bullseye"
- bcm2835版本:1.71
- 已安装Libcap并完成程序名权限配置
- 编译命令:
gcc -Wall -o "%e" "%f" -pthread $(pkg-config gtk+-3.0 --cflags --libs) -export-dynamic -l bcm2835 -l png -DBCM2835_HAVE_LIBCAP - 异常现象:GPIO、
bcm2835_delay功能正常,但两次调用bcm2835_st_read()均返回0
排查与修复步骤
1. 适配BCM2711芯片的定时器地址
RPi4/Pi400搭载的BCM2711芯片,系统定时器基地址与旧款BCM2835不同(旧款为0x20003000,BCM2711为0xFE003000)。bcm2835 1.71版本可能未自动识别BCM2711:
- 检查
bcm2835.h文件,确认是否定义了BCM2711宏,且系统定时器基地址设置为0xFE003000。 - 编译时强制添加
-DBCM2711宏,修改编译命令为:gcc -Wall -o "%e" "%f" -pthread $(pkg-config gtk+-3.0 --cflags --libs) -export-dynamic -l bcm2835 -l png -DBCM2835_HAVE_LIBCAP -DBCM2711
2. 验证Libcap权限配置
确保程序已正确获取RAWIO权限:
- 执行命令重新赋予权限:
sudo setcap cap_sys_rawio+ep ./你的测试程序名 - 运行程序前,用
getcap ./你的测试程序名检查是否输出./你的测试程序名 = cap_sys_rawio+ep,确认权限生效。
3. 直接映射读取定时器寄存器
如果库函数仍失效,可绕过bcm2835_st_read(),直接读取BCM2711的系统定时器:
#include <stdio.h> #include <stdint.h> #include <bcm2835.h> #define BCM2711_ST_BASE 0xFE003000 #define ST_CLO (*(volatile uint32_t*)(BCM2711_ST_BASE + 0x04)) // 低32位计数值 int main() { if (!bcm2835_init()) { fprintf(stderr, "bcm2835初始化失败\n"); return 1; } uint32_t t1 = ST_CLO; bcm2835_delay(100); uint32_t t2 = ST_CLO; printf("第一次读取:%u,第二次读取:%u,时间差:%u\n", t1, t2, t2 - t1); bcm2835_close(); return 0; }
编译运行该代码,验证是否能获取有效定时器值。
4. 升级bcm2835库版本
1.71版本对BCM2711的适配存在已知问题,升级到最新稳定版(如1.73+):
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.73.tar.gz tar zxvf bcm2835-1.73.tar.gz cd bcm2835-1.73 ./configure make sudo make install
重新编译测试代码后再运行。
内容的提问来源于stack exchange,提问作者mick bell
相关产品推荐
相关产品推荐

