Menulis Linux Device Driver – IOCTL

Pada bahasan sebelumnya, kita pelajari bagaimana menambahkan file operation seperti open, read, write, close bagi setiap aplikasi yang mengakses char driver yang kita buat. Selain file operation tersebut, ada satu lagi tipe file operation yaitu IOCTL.

IOCTL adalah system call untuk device driver tertentu, yang berfungsi untuk mengirim

informasi dari satu process ke kernel. Ini berbeda dengan system call Linux secara umum (sys_exit, sys_fork, sys_read, dll) sehingga tidak dapat dipanggil dengan Linux system call biasa.

Sama seperti file operation yang lain, untuk mendefinisikan sebuah antarmuka IOCTL pada sebuah device driver, kita cukup mendeklarasikannya pada entry file operations seperti berikut.

static struct file_operations foo_fops = {
        .owner = THIS_MODULE,
        .ioctl = foo_ioctl, // antarmuka IOCTL
        .write = foo_write,
        .read = foo_read,
        .open = foo_open,
        .release = foo_close,
};

Lalu bagaimana cara menggunakannya? Sama seperti file operation yang lain, kita gunakan IOCTL setelah kita dapatkan file handler dari perintah open device driver. Akan tetapi berbeda dari perintah file operation yang lain, IOCLT memerlukan antarmuka di user space yang biasanya tersedia pada file header yang wajib dikompile oleh user application dan device driver, contoh sebagai berikut:

#define IOCTL_FOO01 _IOR(MAJOR_NUM, 0, int)

IOCTL number didefinisikan dengan macro _IOR( atau _IO, _IOR, _IOW, _IOWR). MAJOR_NUM adalah Major number dari device driver yang dibuat, angka 0 adalah identifier dari IOCTL_FOO01, dan int adalah tipe parameter yang akan dikirim dari process ke kernel.

Sekarang kita punya tiga file, yaitu: device driver code, header file dan aplikasi tester.

/* file.h - header file mendefinisikan MAJOR dan IOCTL */

#include <linux/ioctl.h>

#define DEVICE_NAME "foo"
#define MAJOR_NUM 100

#define IOCTL_FOO01 _IOR(MAJOR_NUM, 0, int)

File.c – device driver code:

/* file.c - device driver code, mengimplementasikan IOCTL */

static int device_ioctl(struct inode *inode, struct file *filp,
                        unsigned int ioctl_num, unsigned long ioctl_param)
{
       unsigned int temp = 0;

       switch (ioctl_num) {
       case IOCTL_FOO01:
              printk(KERN_ALERT "Anda memanggil IOCTL %dn", ioctl_num);
              if (copy_from_user(&temp, (unsigned long *)ioctl_param, sizeof(temp))) {
                      return -EFAULT;
              }
              printk(KERN_ALERT "Anda mengirim angka %dn", temp);
              break;
       default:
              printk(KERN_INFO "Invalid IOCTL n");
              break;
       }
       return 0;
}

File ioctl.c

void ioctl_test(int fd, unsigned int val)
{
       int rv;
       rv = ioctl(fd, IOCTL_FOO01, val);
       if (rv < 0) {
               printf("IOCTL_FOO01 Gagal!");
               exit(1);
       }
}

Demikian pembahasan kita tentang IOCTL.

Pos ini dipublikasikan di Embedded dan tag , , , . Tandai permalink.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s