jul*_*mme 5 arm interrupt linux-device-driver linux-kernel embedded-linux
在ARM FIQ中断上,我们有一些寄存器仅保留用于FIQ,这些是"保存状态"的便捷方式,例如FIQ调用之间的数据传输.
目前我正在GPIO从FIQ 触发一些引脚,它正在按预期工作.在设置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]
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期执行,在pin 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, r12, #0x20 /* set pin 5 high in dout0 register */
STR r12, [r8, #OFFSET_DOUT0] /* This will do nothing ? */
Run Code Online (Sandbox Code Playgroud)
在为结构分配内存并映射寄存器指针后,我将pdata结构的地址传递给FIQ处理程序.在FIQ处理程序中,我有din0和我的偏移dout0,我认为是0x0和0x4(从结构大小8中扣除).
但由于某种原因,现在我的FIQ无法再将输出引脚设置为高电平 - 我无法弄清楚我在这里做错了什么..我在那里计算错误的偏差吗?或者电话STR r12, [r8, #OFFSET_DOUT0]不正确?实际的FIQ更长一些(它读取输入状态,并从中输入创建一些条件),但即使是基本位设置似乎也失败了..
regs.ARM_r8 = (long) dout0;
set_fiq_regs(®s);
Run Code Online (Sandbox Code Playgroud)
...
//In the FIQ handler:
LDR r12, [r8]
ORR r12, r12, #0x20 /* set pin 5 high in dout0 register */
STR r12, [r8]
Run Code Online (Sandbox Code Playgroud)
这里的值r8是存储器映射的I/O寄存器的地址.取消引用它从正确的位置读取.
struct fiq_processing {
char* din0;
char* dout0;
};
static fiq_processing * pdata; //Pointer to our processing data structure
pdata->din0 = ioremap(HW_PINCTRL_DIN0, 0xffff);
pdata->dout0 = ioremap(HW_PINCTRL_DOUT0, 0xffff);
...
//In the FIQ handler:
LDR r12, [r8, #OFFSET_DOUT0]
ORR r12, r12, #0x20 /* set pin 5 high in dout0 register */
STR r12, [r8, #OFFSET_DOUT0] /* This will do nothing ? */
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您已检索到GPIO控制器的地址,并且您正在ORR使用该地址!你需要再次取消引用.
LDR r11, [r8, #OFFSET_DOUT0] # Get address of controller
LDR R12, [R11] # Get current I/O value.
ORR r12, r12, #0x20 # Set pin 5 high in dout0 register */
STR r12, [r11] # Write it out.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1094 次 |
| 最近记录: |