Module Linux下的初学者设备驱动程序开发

Module Linux下的初学者设备驱动程序开发,module,kernel,driver,device,Module,Kernel,Driver,Device,我是linux驱动程序开发的新手。我读过一些关于这方面的书 我开始喜欢每个人(我想)用“Hello World”的例子,但我想做更多。我在一本书中发现了以下代码: #include <linux/module.h> #include <linux/configfs.h> #include <linux/init.h> #include <linux/tty.h> #include <linux/kd.h> #include <l

我是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);
函数
static int\uu init kbled\u init(void)


如果有人能帮我解决这个问题!如果你想解释或给我一本书的链接来理解这段代码,我也不是一个驱动程序专家,但根据我使用C语言的经验,我可以尝试进行足够的解释,让你更进一步

您询问的第一行是驱动程序对函数的定义,该函数接受为三个参数定义的类型
vc_cons[fg_console].d->port.tty
KDSETLED
,和
*pstatus

(my\u driver->ops->ioctl)
是嵌套在结构
my\u driver
中的结构
ops
中存在的函数

该行已合并
(my_driver->ops->ioctl)(vc_cons[fg_console].d->port.tty,KDSETLED,*pstatus)
; 正在使用上述参数调用该函数

理解
static int\uuuu init kbleds\u init(void)
函数作为一个整体在做什么,需要您查看所包含的各种标题,以了解所使用的数据类型的定义和结构(这样您就可以了解
vc\u cons[fg\u console]
中的
.d
是什么)。该指针有一个端口字段,该字段具有属性
tty
,该属性对应于您将实际向其发送“打开LED”命令的电传打字机。
KDSETLED
是一个对应于“LED开启”的代码,最后一个参数是命令状态指针

其中许多参考是#定义宏和结构,它们定义了内核使用驱动程序在键盘上驱动LED所需的格式,例如本例

希望这对你有所帮助。祝你好运

(my_driver->ops->ioctl) (vc_cons[fg_console].d->port.tty, KDSETLED,
                        *pstatus);