我正在尝试在以下片上系统中读取CP15协处理器
Cortex A7 - ARMv7-A
在我的片段下方
void main (void)
{
unsigned int reg_value = 0;
asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(reg_value) );
printf("reg_value: %d", reg_value);
}
Run Code Online (Sandbox Code Playgroud)
我不知道这是否是读取协处理器寄存器的正确方法,但其编译完成且没有错误.问题出现在执行期间(代码在root中执行):
Illegal instruction
Run Code Online (Sandbox Code Playgroud)
如果我使用gdb,我会得到以下结果:
0x000086a0 <+16>: str r3, [r11, #-40] ; 0x28
=> 0x000086a4 <+20>: mrc 15, 0, r3, cr0, cr0, {0}
0x000086a8 <+24>: str r3, [r11, #-40] ; 0x28
Run Code Online (Sandbox Code Playgroud)
为什么我无法读取协处理器寄存器?我的代码出了什么问题?
您似乎正在尝试使用指令访问 MIDR:Main ID Register(来自 ARMARMv7 B4.1.105)
MRC p15, 0, <Rt>, c0, c0, 0 ; Read MIDR into Rt
Run Code Online (Sandbox Code Playgroud)
但是,当您在 Linux 中执行应用程序时,您处于用户模式 (PL0),并且 ARMARMv7 在 MIDR 的使用约束中指定:
只能从 PL1 或更高版本访问。
因此只能在 PL1、PL2、PL3 处访问。要访问它,您需要创建一个在 PL1 上运行的驱动程序,该驱动程序将读取 MIDR。然后,在您的应用程序中,打开此驱动程序以使用 IOCTL 等方式获取数据。
您还可以尝试使用来自 PL0 的 SVC 调用来访问内核模式 (PL1),但这意味着修改您的内核 SVC 处理程序。