我是linux上驱动程序开发的新手。我读过一些关于这个的书。
我开始像大家一样(我认为)以“Hello World”为例,但我想做更多。我在一本书中找到了这段代码:
#include <linux/module.h>
#include <linux/configfs.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/console_struct.h>
#include <linux/vt_kern.h>
MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs.");
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
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->ops->ioctl) (vc_cons[fg_console].d->port.tty, 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->port.tty);
}
printk(KERN_INFO "kbleds: finished scanning consoles\n");
my_driver = vc_cons[fg_console].d->port.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->ops->ioctl) (vc_cons[fg_console].d->port.tty, KDSETLED,
RESTORE_LEDS);
}
module_init(kbleds_init);
module_exit(kbleds_cleanup);
我试图理解代码,大多数情况下我已经完成了,但有些部分我不明白
例如:
(my_driver->ops->ioctl) (vc_cons[fg_console].d->port.tty, KDSETLED,
*pstatus);
和函数static int __init kbleds_init(void)
如果有人可以帮我解决这个问题!如果你想要解释或给我一个书的链接,以理解这段代码
答案 0 :(得分:1)
我也不是司机专家,但根据我对C的经验,我可以尝试解释一下,让你走得更远。
您询问的第一行是您的驱动程序对函数的定义,该函数接受为三个参数vc_cons[fg_console].d->port.tty
,KDSETLED
和*pstatus
(my_driver->ops->ioctl)
是嵌套在结构ops
中的结构my_driver
中存在的函数。
该行合并了
(my_driver->ops->ioctl) (vc_cons[fg_console].d->port.tty, KDSETLED,*pstatus)
;
用上面提到的参数调用该函数。
了解static int __init kbleds_init(void)
函数的整体功能需要您查看已包含的各种标题,以找出您正在使用的数据类型的定义和结构(这样您就可以了找出.d
中vc_cons[fg_console]
的内容。该指针有一个端口字段,其属性tty
对应于您实际发送&#34;打开LED的电传打字机。命令。 KDSETLED
是对应于&#34; LED ON&#34;的代码,最后一个参数是命令状态指针。
这些引用中的许多都是#define宏和结构,它们定义了内核所需的格式,以便您在驱动程序的键盘上驱动LED,就此示例而言。
希望这会有所帮助。祝你好运。