LINUX.ORG.RU

Проблема с таймерами ядра.

 ,


0

2

Начал разбираться с таймерами. Есть устройство с линуксом на борту с SPI-клавиатурой. Я хочу по срабатыванию таймера прибивать авторепит у клавиатуры. Вот функция, регистрирующая нажатие:

static void key_press(void)
{
        if (last_scan_code != 0)
        {
                uint8_t i = 0;
                for (; i < NUMBER_OF_KEYS; i++)
                {
                        if (KEYS[i].scan_code == last_scan_code)
                        {
                                init_timer(&my_timer);
                                my_timer.expires = jiffies + delay;
                                my_timer.data = 0;
                                my_timer.function = my_timer_function;
                                add_timer(&my_timer);
                                if (KEYS[i].key == 79) /** по нажатию на кнопку "1" прибиваем авторепит */
                                {
                                        del_timer(&kbd_dev->timer);
                                }
                                else
                                {
                                        input_report_key(kbd_dev, KEYS[i].key, 1);
                                        input_sync(kbd_dev);
                                        snd_squeak(3000, 120000, 240000);
                                        STATUS.last_key = KEYS[i].key;
                                }
                        }

                }
        }
}

А это обработчик таймера:

void my_timer_function(unsigned long data)
{
        printk(KERN_INFO "\nHello from my_timer_function!\n");
        del_timer(&my_timer);
        del_timer(&(kbd_dev->timer));
}

Компилирую модуль, подгружаю его, тыкаю в кнопки. Дальше происходит странное - примерно на каждое 15-20 нажатие вываливается простыня:

14:38:29.800; Pressed 0x39 key {9} {NM:0} {NSC:0} {NVK:0} {MOD:20000000} {REPIT:true} [text:9]
Hello from my_timer_function!

Unable to handle kernel NULL pointer dereference at virtual address 00000004
pgd = c0004000
[00000004] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT
Modules linked in: power adc thermal busmanager dsp kbd squeak
CPU: 0    Not tainted  (2.6.27.8 #6)
PC is at run_timer_softirq+0x154/0x248
LR is at run_timer_softirq+0x1c/0x248
pc : [<c00482f0>]    lr : [<c00481b8>]    psr: 80000093
sp : c0325eb4  ip : c0325ebc  fp : c0325eec
r10: c0344208  r9 : c0344008  r8 : c0344408
r7 : bf002694  r6 : c0324000  r5 : 00000000  r4 : c0343600
r3 : 00000000  r2 : c0325ebc  r1 : bf004078  r0 : c03436b8
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: 0005317f  Table: 83a3c000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc0324260)
Stack: (0xc0325eb4 to 0xc0326000)
5ea0:                                              c0325ebc c0343e08 00000000
5ec0: c3977970 c0343478 00000001 0000000a c0343440 00000001 c0345b70 00000000
5ee0: c0325f18 c0325ef0 c0043390 c00481ac c032c724 00000010 00000000 00000002
5f00: 00000001 c0324000 8001b99c c0325f28 c0325f1c c0043440 c004333c c0325f44
5f20: c0325f2c c0020048 c0043408 ffffffff f4008000 00010000 c0325f9c c0325f48
5f40: c00208b8 c0020010 00000000 0005317f 0005217f 60000013 c0021e10 c0324000
5f60: c0021e10 c033e028 8001b9d0 41069264 8001b99c c0325f9c 600000d3 c0325f90
5f80: c0021e54 c0021e60 60000013 ffffffff c0325fbc c0325fa0 c0021ddc c0021e20
5fa0: c0324000 c033dff0 c001cda8 c0327ce8 c0325fd0 c0325fc0 c027f07c c0021db0
5fc0: c0345ee8 c0325ff4 c0325fd4 c0008960 c027f01c c0008480 c001cda8 00053175
5fe0: c033e08c c001d1ac 00000000 c0325ff8 80008034 c0008720 00000000 00000000
Backtrace:
[<c004819c>] (run_timer_softirq+0x0/0x248) from [<c0043390>] (__do_softirq+0x64/0xcc)
[<c004332c>] (__do_softirq+0x0/0xcc) from [<c0043440>] (irq_exit+0x48/0x64)
[<c00433f8>] (irq_exit+0x0/0x64) from [<c0020048>] (__exception_text_start+0x48/0x60)
[<c0020000>] (__exception_text_start+0x0/0x60) from [<c00208b8>] (__irq_svc+0x38/0xc4)
Exception stack(0xc0325f48 to 0xc0325f90)
5f40:                   00000000 0005317f 0005217f 60000013 c0021e10 c0324000
5f60: c0021e10 c033e028 8001b9d0 41069264 8001b99c c0325f9c 600000d3 c0325f90
5f80: c0021e54 c0021e60 60000013 ffffffff
 r6:00010000 r5:f4008000 r4:ffffffff
[<c0021e10>] (default_idle+0x0/0x58) from [<c0021ddc>] (cpu_idle+0x3c/0x70)
[<c0021da0>] (cpu_idle+0x0/0x70) from [<c027f07c>] (rest_init+0x70/0x84)
 r7:c0327ce8 r6:c001cda8 r5:c033dff0 r4:c0324000
[<c027f00c>] (rest_init+0x0/0x84) from [<c0008960>] (start_kernel+0x250/0x2a8)
 r4:c0345ee8
[<c0008710>] (start_kernel+0x0/0x2a8) from [<80008034>] (0x80008034)
 r6:c001d1ac r5:c033e08c r4:00053175
Code: e5913000 e591700c e5915010 e5823000 (e5832004)
Kernel panic - not syncing: Fatal exception in interrupt

ЧЯДНТ?

★★★★★

Вместо init_timer+add_timer попробуй использовать setup_timer+mod_timer.
Тоже были какие-то проблемы именно с add_timer. В подробности не вдавался.

xydo ★★ ()

а вот эти вот kbd_dev и my_timer и ссылки на них из обработчика прерываний, это всё как-то странно выглядит.

dimon555 ★★★★★ ()
Ответ на: комментарий от xydo

попробуй использовать setup_timer+mod_timer

с mod_timer все заработало. спасибо за помощь!

ymn ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.