質問

I am a newbie on driver development in linux. I've read some books about this.

I started like everyone (I think) with "Hello World" example but I want to make more. I found this code in a book:

#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);

I tried to understand the code, mostly I've done but there are parts I do not understand

for example:

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

and the function static int __init kbleds_init(void)

if someone can help me with this issues! if you want can explain or gimme a link to a book to understand this code

役に立ちましたか?

解決

I'm not a driver expert either, but from my experience with C, I can attempt to explain enough to get you going further.

The first line you ask about is your driver's definition of a function that accepts the types defined for the three arguments vc_cons[fg_console].d->port.tty, KDSETLED, and *pstatus

(my_driver->ops->ioctl) is a function that exists within the struct ops nested within the struct my_driver.

The line combined
(my_driver->ops->ioctl) (vc_cons[fg_console].d->port.tty, KDSETLED,*pstatus); is calling that function with the above mentioned arguments.

Understanding what the static int __init kbleds_init(void) function is doing as a whole will require you to look through the various headers you have included to find out the definitions and structure of the data types you're using (so you can find out what the .d is in vc_cons[fg_console] is). That pointer has a port field that has property tty which corresponds to the teletype that you'll actually send the "turn the LED on" command to. The KDSETLED is a code that corresponds to "LED ON", and the final argument is the command status pointer.

Many of these references are #define macros and structs that define the format that is required by the kernel for you to drive LED's on a keyboard with your driver, for this example.

Hope this helps some. Good luck.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top