Не удается получить доступ к данным драйвера ядра из обработчика прерываний FIQ
В случае прерываний 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]
Приведенный выше код работает, как и ожидалось,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 ? */
После того как я выделил память для структуры и сопоставил указатели регистров, я передаю адрес для структуры pdata обработчику FIQ. В обработчике FIQ у меня есть смещения дляdin0
а такжеdout0
который я считал0x0
а также0x4
соответственно (вычитается из структуры размером 8).
Но по какой-то причине теперь мой FIQ больше не может устанавливать высокий выходной вывод - я не могу понять, что я делаю здесь неправильно .. Я неправильно рассчитал смещение? ИЛИ это звонокSTR r12, [r8, #OFFSET_DOUT0]
неверно? Фактический FIQ несколько длиннее (он читает состояние ввода, и ввод от него создает некоторые условия), но даже базовый набор битов теперь, похоже, дает сбой.