linux-kernel – 从FIQ中断处理程序访问内核驱动程序数据失败
在ARM FIQ中断上,我们有一些寄存器仅保留用于FIQ,这些是“保存状态”的便捷方式,例如FIQ调用之间的数据传输.
目前我正在从FIQ触发一些GPIO引脚,它正在按预期工作.在设置FIQ处理程序时,我将指针传递给使用ioremap映射的数据寄存器.工作代码如下所示: //Driver initialization: static char* dout0; static char* din0; ... static int driver_probe(struct platform_device *pdev) { struct pt_regs regs; ... dout0 = ioremap(HW_PINCTRL_DOUT0,0xffff); din0 = ioremap(HW_PINCTRL_DIN0,0xffff); ... regs.ARM_r8 = (long) dout0; regs.ARM_r9 = (long) din0; set_fiq_regs(®s); ... //In the FIQ handler: LDR r12,[r8] ORR r12,r12,#0x20 /* set pin 5 high in dout0 register */ STR r12,[r8] 上述代码按预期执行,引脚5在执行FIQ处理程序后设置为高电平. 对于更复杂的操作,我想准备一个结构,它将保存数据指针和其他处理相关的数据,包括更多映射到不同的寄存器 – 并将其传递给FIQ处理程序.但是在将上述代码迁移到此时已经出现了问题. 我修改了上面的代码看起来像这样 //In Driver: struct fiq_processing { char* din0; char* dout0; }; static fiq_processing * pdata; //Pointer to our processing data structure ... static int driver_probe(struct platform_device *pdev) { struct pt_regs regs; pdata = kmalloc(sizeof(*pdata),GFP_KERNEL); //Allocate memory for struct printk("Size of the data struct %d n",sizeof(*pdata)); //I get "8" as the size ... pdata->din0 = ioremap(HW_PINCTRL_DIN0,0xffff); pdata->dout0 = ioremap(HW_PINCTRL_DOUT0,0xffff); ... regs.ARM_r8 = (long) pdata; set_fiq_regs(®s); ... //In the FIQ handler: #define OFFSET_DIN0 0x0 #define OFFSET_DOUT0 0x4 //We know size is 8,so offset for dout is half from that ... LDR r12,[r8,#OFFSET_DOUT0] ORR r12,#OFFSET_DOUT0] /* This will do nothing ? */ 在为结构分配内存并映射寄存器指针后,我将pdata结构的地址传递给FIQ处理程序. 但由于某种原因,现在我的FIQ无法再将输出引脚设置为高电平 – 我无法弄清楚我在这里做错了什么.. 解决方法
情况1
regs.ARM_r8 = (long) dout0; set_fiq_regs(®s); … //In the FIQ handler: LDR r12,[r8] 这里r8中的值是存储器映射的I / O寄存器的地址.取消引用它从正确的位置读取. 案例2 struct fiq_processing { char* din0; char* dout0; }; static fiq_processing * pdata; //Pointer to our processing data structure pdata->din0 = ioremap(HW_PINCTRL_DIN0,0xffff); ... //In the FIQ handler: LDR r12,#OFFSET_DOUT0] /* This will do nothing ? */ 在这种情况下,您已检索到GPIO控制器的地址,并且您正在使用该地址进行ORRing!你需要再次取消引用. LDR r11,#OFFSET_DOUT0] # Get address of controller LDR R12,[R11] # Get current I/O value. ORR r12,#0x20 # Set pin 5 high in dout0 register */ STR r12,[r11] # Write it out. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |