gpt4 book ai didi

c - 如何使用 Arm Assembly/C 确定 Raspberry Pi 板版本?

转载 作者:太空狗 更新时间:2023-10-29 15:31:44 25 4
gpt4 key购买 nike

我正在为 Raspberry Pi 设备开发测试内核。为此,我需要设置 UART,以便我们可以将数据写入设备并能够检索需要由内核处理的数据。我希望测试内核能够在多个 Raspberry Pi 设备上运行。但是有一个小问题:

不同版本的 UART 地址不同。例如树莓派 1 线 UART GPIO 的地址为:

0x20200000

但是 RPi 2 和 RPi 3 线上的 UART GPIO 地址是:

0x3F200000

当然,这意味着需要两个单独的 UART_INIT 函数:1 个用于 RPi 1 线路设备,1 个用于 RPi 2 及更高版本。

这是 UART 处理代码的示例。此代码修改自 osdev 提供的代码:

void uart_init_rpi1()
{
// Disable UART0.
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_CR, 0x00000000);
// Setup the GPIO pin 14 && 15.

// Disable pull up/down for all GPIO pins & delay for 150 cycles.
mmio_write(PD_GPPUD_RPI1, 0x00000000);
delay(150);

// Disable pull up/down for pin 14,15 & delay for 150 cycles.
mmio_write(PD_GPPUDCLK0_RPI1, (1 << 14) | (1 << 15));
delay(150);

// Write 0 to GPPUDCLK0 to make it take effect.
mmio_write(PD_GPPUDCLK0_RPI1, 0x00000000);

// Clear pending interrupts.
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_ICR, 0x7FF);

// Set integer & fractional part of baud rate.
// Divider = UART_CLOCK/(16 * Baud)
// Fraction part register = (Fractional part * 64) + 0.5
// UART_CLOCK = 3000000; Baud = 115200.

// Divider = 3000000 / (16 * 115200) = 1.627 = ~1.
// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_IBRD, 1);
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_FBRD, 40);

// Enable FIFO & 8 bit data transmissio (1 stop bit, no parity).
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));

// Mask all interrupts.
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | (1 << 6) |
(1 << 7) | (1 << 8) | (1 << 9) | (1 << 10));

// Enable UART0, receive & transfer part of UART.
mmio_write(PD_UART_INTERNAL_VALUES_RPI1->UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
}

在 RPi 2 和 RPi 3 线上有一个类似的辅助函数用于处理 UART INIT。有两个独立的 UART INIT 函数很好,并不是真正的问题。问题是能够区分电路板类型。如果有办法确定当前使用的电路板,它会为我省去很多麻烦。不能,意味着我需要为 RPi 1 板、RPi 2-3 板和任何其他类似 RPi 的板(例如 ODROID OC-2)制作一个单独的测试内核。如果不知何故,有一种方法可以确定板类型,我可以将其用作条件并在启动时加载正确的 UART 值,这意味着只需要一个单一的内核文件。一种可行的方法是基于处理器进行测试,这在每个 RPi 修订版和替代板之间都是独一无二的。在 x86 平台上,您可以使用 _RTDSC,但我相当确定在非 x86/x86-64 处理器上不存在此类替代方案。

所以,我要问的问题是:有没有一种方法,无论是在汇编语言还是 C 语言中,都可以检查用户/代码在哪种类型的板上运行?由于我正在构建操作系统内核,因此我无法访问非编译器 C 库,因此 C 代码必须遵从可变汇编指令。

最佳答案

由于每一代 pi 使用与 arm 不同的 cpu 核心(特定的 armv6,然后是 armv7,然后是 armv8),您可以轻松地从 cpu id 寄存器中检测到它们。

.globl GETCPUID
GETCPUID:
mrc p15,0,r0,c0,c0,0
bx lr

不同的核返回不同的值

PI3 0x410FD034
PI2 0x410FC075
PI1/Zero 0x410FB767

从那里你可以设置你的外设基地

if((id&0xFFFFFFFF)==0x410FB767) PBASE=0x20000000;
else PBASE=0x3F000000;

关于c - 如何使用 Arm Assembly/C 确定 Raspberry Pi 板版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42094455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com