You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:54:26