【问题标题】:Access Raspberry Pi 4 system timer访问树莓派 4 系统定时器
【发布时间】:2021-07-27 01:46:24
【问题描述】:

我无法读取 Raspberry Pi 4 系统计时器。 我的理解是 LO 32 位应该在地址 0x7e003004。 我的读数总是返回-1。 以下是我的尝试:

int fd;
unsigned char* start;
uint32_t* t4lo;

fd = open("/dev/mem", O_RDONLY);
if (fd == -1)
{
perror("open /dev/mem");
exit(1);
}
start = (unsigned char*)mmap(0, getpagesize(), PROT_READ, MAP_SHARED,
fd, 0x7e003000);
t4lo = (unsigned int *)(start + 0x04);
...
uint32_t Rpi::readTimer(void)
{
    return *t4lo;
}

我应该检查 start 的值,但 gdb 告诉我这是合理的,所以我认为这不是问题。

(gdb) p t4lo
$4 = (uint32_t *) 0xb6f3a004

gdb 不允许我访问 *t4lo。有什么想法吗?

编辑:clock_gettime() 满足了我的需求,但我仍然很好奇。

【问题讨论】:

标签: embedded-linux hardware raspberry-pi4


【解决方案1】:

仔细看看https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0.pdf 第 5 页的图 1 显示地址因查看对象而异。如果您从左侧的 0x7c00_0000 开始,然后向右移动,很明显它显示在处理器的 0xfc00_0000 处。所以把定时器基地址改成0xfe00_3000就解决了这个问题。

秘密隐藏在第 1.2.4 节中:

So a peripheral described in this document as being at legacy address 0x7Enn_nnnn
is available in the 35-bit address space at 0x4_7Enn_nnnn, and visible to the ARM
at 0x0_FEnn_nnnn if Low Peripheral mode is enabled.

【讨论】:

    【解决方案2】:

    BCM2711 ARM 外设的地址是总线地址,与大多数系统中的物理地址不同。 DMA(直接内存访问)控制器很容易使用总线地址。 mmap 创建一个从物理地址到虚拟地址而不是总线地址的新映射。所以你不能使用参数为 0x7e003000 的 mmap 函数。 丰富的答案是正确的。

    因此将定时器基地址更改为 0xfe00_3000 解决了问题。

    另外,你的程序运行在用户空间,你只能直接使用虚拟地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多