Здравствуйте всем! Думаю многие читали "The Linux Kernel Module Programming Guide(http://www.citforum.ru/operating_systems/linux/lkmpg/#AEN807)".
Так вот, там меня заинтересовала одна программка, которая заставляет мерцать индикаторы на клавиатуре, а именно - kbleds.c
Ниже приведён её код:
/*
* 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);
Понятное дело, что с тех пор, когда эта программка была написана, много воды утекло и много изменений в ядре произошло. Так вот, предлагаю, кому интересно, попытаться довести до ума данную программку, скомпилировать, загрузить модуль и посмотреть как мерцают наши индикаторы на клавиатуре. Если получится, будет неплохое подспорье для начинающих драйверщиков(коим я и являюсь в данный момент).