Lập trình device driver trên linux

Mục tiêu khóa học:
Sau khóa học "Lập trình Device Driver trên Linux", các bạn sẽ có được cái nhìn tổng thể nhất về cơ chế quản lý thiết bị trên Linux, quy trình xây dựng driver cho các thiết bị từ cơ bản đến nâng cao để xây dựng các driver từ đơn giản như driver cho các cổng GPIO đến driver cho các thiết bị chạy chuẩn USB. Trên Linux, mọi thành phần của hệ thống sẽ đều hết sức rõ ràng giúp bạn nắm vững kiến thức mình đã học, từ đó có thể dễ dàng hơn trong việc tiếp cận trên các nền tảng khác như Android hay thậm chí là Windows. Bên cạnh đó, các bạn còn được giới thiệu về hệ thống udev, hệ thống script quan trọng bậc nhất trong việc tự động quản lý, cấu hình các thiết bị trên Linux.



Nội dung khóa học:

+ Đề cương khóa học xin mời xem tại đây
+ Slide bài giảng tham khảo xin mời download tại đây

+ Lịch khai giảng xin vui lòng xem tại đây
+ Thiết bị thực hành xin vui lòng xem tại đây

USB Driver in Linux


1. Mục đích

- Tìm hiểu cơ chế lập trình kernel module trên Linux

- Minh họa qui trình viết một device driver đơn giản

2. Tiến hành 

2.1. Viết kernel module

Xây dựng một module đơn giản theo đúng khuôn dạng 

Bước 1. Viết mã nguồn (File hello_kernel_module.c)

#include

#include

#include

static int hello_init(void)

{

    printk(KERN_ALERT "Khoi tao thanh cong\n");

return 0;

}

static void hello_exit(void)

{

    printk(KERN_ALERT "Ket thuc thanh cong\n");

}

module_init(hello_init);

module_exit(hello_exit);

Bước 2. Viết Makefile cho kernel module để biên dịch (đặt cùng thư mục file mã nguồn)

obj-m += hello_kernel_module.o

all:

      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Bước 3. Biên dịch bằng lệnh make được file hello_kernel_module.ko

Bước 4. Cài đặt module vào hệ thống (sử dụng lệnh insmod

insmod  hello_kernel_module .ko

           Gỡ kernel module dùng lệnh rmmod

Bước 5. Kiểm tra quá trình cài đặt xem module đã cài đặt thành công hay chưa

(Trên Ubuntu, mở System/Log Viewer xem mục kernel log)

2.2. Viết một device driver đơn giản

Bước 1: Xây dựng device driver đơn giản theo cơ chế kernel module

- Viết mã nguồn (File hello_driver.c) theo đúng khuôn dạng qui định

#include

#include

#include

#include

static ssize_t hello_read(struct file *filp, char *buffer, size_t length, loff_t *offset);

static int Major;

//Cấu trúc để đăng ký các hàm qua driver interface được được qui định theo chuẩn

static struct file_operations fops={

     .owner=THIS_MODULE,

     .read=hello_read,   

};

static int hello_init(void)

{

    //Đăng ký thiết bị kiểu character với major id hệ thống cung cấp

     Major=register_chrdev(0,"KTMT-Device",&fops);   

     if(Major<0)

     {

           printk(KERN_ALERT "Dang ky that bai\n");

     }

     else{

           printk(KERN_ALERT "Dang ky thiet bi thanh cong voi MajorID=%d\n",Major);

     }

return 0;

}

static void hello_exit(void)

{

    //Giải phóng thiết bị đã đăng ký

     unregister_chrdev(Major,"KTMT-Device");       

     printk(KERN_ALERT "Thiet bi da bi ngat khoi he thong\n");

}

//Hàm read được cung cấp qua driver interface

static ssize_t hello_read(struct file *filp, char *buffer, size_t length, loff_t *offset)

{

     return 100; //Hảm read của driver chỉ đơn giản trả về một giá trị

}

module_init(hello_init);

module_exit(hello_exit);

Bước 2. Viết Makefile để biên dịch mã nguồn trên, được file hello_driver.ko

obj-m += hello_driver.o

all:

      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Bước 3: Cài đặt device driver theo cơ chế của Kernel module

Lệnh:     insmod hello_driver.ko

Bước 4: Sử dụng lệnh mknod để tạo ra một device file trong thư mục /dev (giả sử đặt tên device file là KTMT0)

              mknod /dev/KTMT0 c 250 1

(Tạo ra một device file có tên là KTMT0 cho device driver kiểu character có major id là 250)

(Xem major id của kernel module hello_driver dùng lệnh cat /proc/devices)

Đến đây, chúng ta có một thiết bị tên KTMT0 với driver đã viết (cung cấp hàm read). Bước tiếp theo sẽ viết một ứng dụng để giao tiếp thiết bị này.

Bước 5: Viết chương trình để test giao tiếp với driver (hello_driver)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char** argv)

{

     int fd;

     int result,rt;

     fd = open(argv[1], 0);    

     rt=read(fd,&result,sizeof(result));

     printf("\nKet qua nha ve la %d\n",rt);

     close(fd);

     return 0;

}

 - Biên dịch và chạy ứng dụng này, quan sát kết quả do hàm read của driver trả về.