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

如何在Cortex-R5上获取或模拟64位循环计数器?

解决Cortex-R5 PMU 32位循环计数器溢出,实现64位计数的方法

方法一:软件叠加溢出计数(最可靠)

Cortex-R5的PMU支持溢出中断,我们可以利用这个特性维护一个软件层面的溢出计数器,将其与32位硬件计数器组合成64位值:

  • 配置PMU:开启PMCR寄存器的E位(使能PMU),并针对循环计数器(通常是CNT0)设置对应溢出中断使能寄存器(如CNTENS的对应位)。
  • 实现溢出中断服务函数:每次触发溢出中断时,将全局32位溢出计数器(例如uint32_t overflow_cnt)加1。
  • 读取64位计数:需要获取当前计数时,进入临界区(或做原子操作),读取硬件32位计数器值(uint32_t hw_cnt),再结合溢出计数器计算:uint64_t total_cnt = ((uint64_t)overflow_cnt << 32) | hw_cnt;

注意:读取时必须保证原子性,避免在读取hw_cnt和overflow_cnt的间隙发生溢出,导致计数错误。也可利用PMU的锁存寄存器(若支持)先锁存当前计数器值再读取。

方法二:结合系统定时器辅助校准

如果你的SoC带有64位系统定时器(如通用定时器、RTC等),可通过同步校准估算溢出次数:

  • 初始化阶段:同时读取PMU计数器值pmu_init和定时器值timer_init并记录。
  • 读取阶段:读取当前定时器值timer_now,计算差值timer_diff = timer_now - timer_init;根据CPU主频估算这段时间内PMU的溢出次数:overflow_est = (timer_diff * CPU_FREQ) >> 32(假设定时器单位为秒,CPU_FREQ为主频Hz);再读取当前PMU计数器值pmu_now,最终64位计数为:((uint64_t)overflow_est << 32) | pmu_now

这种方法无需依赖PMU中断,但精度受定时器和CPU主频误差影响,适合对精度要求不极高的场景。

方法三:多核PMU交叉验证(仅适用于多核Cortex-R5系统)

如果是双核心Cortex-R5配置,可让一个核心的PMU计数器作为另一个核心的溢出参考:

  • 两个核心同时启动PMU计数,定期同步各自的计数器值。
  • 当其中一个核心的计数器溢出时,通过核间通信通知另一个核心更新溢出计数。
    不过这种方法实现复杂,仅在特殊多核场景下考虑。

内容的提问来源于stack exchange,提问作者David Monniaux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:50:27