1. 程式人生 > >linux 字元裝置框架使用 初級

linux 字元裝置框架使用 初級

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>

struct cdev g_tecdev;
dev_t  g_devnu;
struct class *g_cls;

int my_cdev_open(struct inode * node, struct file *filp)
{
    printk("open \n");
    return 0;
}

int my_cdev_release (struct inode *node, struct file *filp)
{
    printk("release\n");
    return 0;
}

ssize_t my_cdev_read(struct file *filp, char __user *buff, size_t len, loff_t * offset)
{
    printk("read\n");

    return 0;
}

struct file_operations  tedevops={
    .owner = THIS_MODULE,
    .open = my_cdev_open,
    .release = my_cdev_release,
    .read = my_cdev_read
};

static int __init  test_init(void)
{
   struct device *dev=NULL;
   
   //動態分配裝置號
   if(alloc_chrdev_region(&g_devnu,0,2,"testcdev") < 0)
   {
       printk("alloc dev nunber is error\n");
       return -1;
   }
   
   //初始化字元裝置描述符
   cdev_init(&g_tecdev,&tedevops);
   g_tecdev.owner = THIS_MODULE;

   //以下兩個函式功能為在/dev/下自動穿件 testcdev裝置檔案
   g_cls = class_create(THIS_MODULE,"testcdev");
   if(NULL == g_cls)
       goto out;
   if(NULL == (dev=device_create(g_cls,NULL,g_devnu,NULL,"testcdev")))
       goto out;

   //註冊字元裝置	
   if(cdev_add(&g_tecdev,g_devnu,2) < 0)
   {
        printk("cdev add error\n");
        goto out;
   }
    return 0;
out:
    unregister_chrdev_region(g_devnu,2);
    if(dev)
      device_destroy(g_cls,g_devnu);
    if(g_cls)
      class_destroy(g_cls);
    return -1;
}
static void __exit test_exit(void)
{
    device_destroy(g_cls,g_devnu);
    class_destroy(g_cls);
    cdev_del(&g_tecdev);
    unregister_chrdev_region(g_devnu,2);
    return;
}   

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");