nhmk/示例/7-驱动与用户交互/kbleds.c

82 lines
2.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* kbleds.c - 闪烁键盘LED直到模块被卸载。
*/
#include <linux/init.h>
#include <linux/kd.h> /* 引入 KDSETLED */
#include <linux/module.h>
#include <linux/tty.h> /* 引入 tty_struct */
#include <linux/vt.h> /* 引入 MAX_NR_CONSOLES */
#include <linux/vt_kern.h> /* 引入 fg_console */
#include <linux/console_struct.h> /* 引入 vc_cons */
MODULE_DESCRIPTION("示例模块演示如何使用键盘LED。");
static struct timer_list my_timer;
static struct tty_driver *my_driver;
static unsigned long kbledstatus = 0;
#define BLINK_DELAY HZ / 5
#define ALL_LEDS_ON 0x07
#define RESTORE_LEDS 0xFF
/* 函数 my_timer_func 定期闪烁键盘LED通过在键盘驱动上调用 ioctl() 命令 KDSETLED 实现。
* 要了解更多关于虚拟终端 ioctl 操作的信息请参见文件drivers/tty/vt/vt_ioctl.c, 函数 vt_ioctl()
*
* KDSETLED 的参数交替设置为 7从而使 LED 模式设置为 LED_SHOW_IOCTL所有的 LED 都被点亮)和 0xFF
* (任何大于 7 的值会将 LED 模式切换回 LED_SHOW_FLAGS因此 LED 反映实际的键盘状态)。要了解更多信息,
* 请参见文件drivers/tty/vt/keyboard.c, 函数 setledstate()。
*/
static void my_timer_func(struct timer_list *unused)
{
struct tty_struct *t = vc_cons[fg_console].d->port.tty;
if (kbledstatus == ALL_LEDS_ON)
kbledstatus = RESTORE_LEDS;
else
kbledstatus = ALL_LEDS_ON;
(my_driver->ops->ioctl)(t, KDSETLED, kbledstatus);
my_timer.expires = jiffies + BLINK_DELAY;
add_timer(&my_timer);
}
static int __init kbleds_init(void)
{
int i;
pr_info("kbleds: 正在加载\n");
pr_info("kbleds: 前台控制台为 %x\n", fg_console);
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (!vc_cons[i].d)
break;
pr_info("poet_atkm: 控制台[%i/%i] #%i, tty %p\n", i, MAX_NR_CONSOLES,
vc_cons[i].d->vc_num, (void *)vc_cons[i].d->port.tty);
}
pr_info("kbleds: 扫描控制台完成\n");
my_driver = vc_cons[fg_console].d->port.tty->driver;
pr_info("kbleds: tty 驱动程序名称 %s\n", my_driver->driver_name);
/* 设置 LED 闪烁定时器。 */
timer_setup(&my_timer, my_timer_func, 0);
my_timer.expires = jiffies + BLINK_DELAY;
add_timer(&my_timer);
return 0;
}
static void __exit kbleds_cleanup(void)
{
pr_info("kbleds: 正在卸载...\n");
del_timer(&my_timer);
(my_driver->ops->ioctl)(vc_cons[fg_console].d->port.tty, KDSETLED,
RESTORE_LEDS);
}
module_init(kbleds_init);
module_exit(kbleds_cleanup);
MODULE_LICENSE("GPL");