LinuxForum.Fans
Тема

Управление индикаторами на клавиатуре

Автор: Helmik 2 сообщений 2785 просмотров
#53131

Здравствуйте всем! Думаю многие читали "The Linux Kernel Module Programming Guide(http://www.citforum.ru/operating_systems/linux/lkmpg/#AEN807)".

Так вот, там меня заинтересовала одна программка, которая заставляет мерцать индикаторы на клавиатуре, а именно - kbleds.c

Ниже приведён её код:

text
/* 
 *  kbleds.c - Мигание индикаторами на клавиатуре.
 */

#include <linux/module.h> #include <linux/config.h> #include <linux/init.h> #include <linux/tty.h> /* определение fg_console, MAX_NR_CONSOLES */ #include <linux/kd.h> /* определение KDSETLED */ #include <linux/console_struct.h> /* определение vc_cons */

MODULE_DESCRIPTION("Пример module illustrating the use of Keyboard LEDs."); MODULE_AUTHOR("Daniele Paolo Scarpazza"); MODULE_LICENSE("GPL");

struct timer_list my_timer; struct tty_driver *my_driver; char kbledstatus = 0;

#define BLINK_DELAY HZ/5 #define ALL_LEDS_ON 0x07 #define RESTORE_LEDS 0xFF

/* * Функция my_timer_func мигает индикаторами * на клавиатуре периодически вызывая * ioctl() драйвера клавиатуры с командой KDSETLED. * Дополнительную информацию, * по командам ioctl виртуального терминала, вы найдете в: * /usr/src/linux/drivers/char/vt_ioctl.c, function vt_ioctl(). * * Дополнительный аргумент команды KDSETLED -- значение 7 * (перевод в режим LED_SHOW_IOCTL -- управление * индикаторами через ioctl), значение 0xFF -- * (любое значение, большее 7, перевод в режим * LED_SHOW_FLAGS -- * отображение фактического состояния клавиатуры). * Дополнительная информация: * /usr/src/linux/drivers/char/keyboard.c, * function setledstate(). * */

static void my_timer_func(unsigned long ptr) { int *pstatus = (int *)ptr;

if (*pstatus == ALL_LEDS_ON) *pstatus = RESTORE_LEDS; else *pstatus = ALL_LEDS_ON;

(my_driver->ioctl) (vc_cons[fg_console].d->vc_tty, NULL, KDSETLED, *pstatus);

my_timer.expires = jiffies + BLINK_DELAY; add_timer(&my_timer); }

static int __init kbleds_init(void) { int i;

printk(KERN_INFO "kbleds: loading\n"); printk(KERN_INFO "kbleds: fgconsole is %x\n", fg_console); for (i = 0; i < MAX_NR_CONSOLES; i++) { if (!vc_cons[i].d) break; printk(KERN_INFO "poet_atkm: console[%i/%i] #%i, tty %lx\n", i, MAX_NR_CONSOLES, vc_cons[i].d->vc_num, (unsigned long)vc_cons[i].d->vc_tty); } printk(KERN_INFO "kbleds: finished scanning consoles\n");

my_driver = vc_cons[fg_console].d->vc_tty->driver; printk(KERN_INFO "kbleds: tty driver magic %x\n", my_driver->magic);

/* * Инициировать таймер */ init_timer(&my_timer); my_timer.function = my_timer_func; my_timer.data = (unsigned long)&kbledstatus; my_timer.expires = jiffies + BLINK_DELAY; add_timer(&my_timer);

return 0; }

static void __exit kbleds_cleanup(void) { printk(KERN_INFO "kbleds: unloading...\n"); del_timer(&my_timer); (my_driver->ioctl) (vc_cons[fg_console].d->vc_tty, NULL, KDSETLED, RESTORE_LEDS); }

module_init(kbleds_init); module_exit(kbleds_cleanup);

Понятное дело, что с тех пор, когда эта программка была написана, много воды утекло и много изменений в ядре произошло. Так вот, предлагаю, кому интересно, попытаться довести до ума данную программку, скомпилировать, загрузить модуль и посмотреть как мерцают наши индикаторы на клавиатуре. Если получится, будет неплохое подспорье для начинающих драйверщиков(коим я и являюсь в данный момент).

Войдите или зарегистрируйтесь, чтобы ответить.