2014-01-22 2 views
0

Я новичок в разработке драйверов в Linux. Я прочитал некоторые книги об этом.Начальная разработка драйверов устройств 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

Я тоже не эксперт по драйверу, но из моего опыта работы с 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, которое соответствует телетайпу, который вы действительно отправляете команде «включить светодиод». Код KDSETLED - это код, соответствующий «LED ON», а конечным аргументом является указатель состояния команды.

Многие из этих ссылок - это макросы и структуры #define, которые определяют формат, необходимый ядру, для того, чтобы вы могли управлять светодиодами на клавиатуре с вашим драйвером для этого примера.

Надеюсь, это поможет некоторым. Удачи.

Смежные вопросы