驱动模板编程总结

驱动模板

  • xxx.c –> 应用层驱动封装函数
  • xxx.h –> 应用层驱动封装函数头文件
  • test.c –> 测试驱动所有的应用层代码
  • xxxDrv.c –> 内核层驱动实现文件
  • xxxDrv.h –> 内核层驱动实现文件函数头文件
  • Makefile –> 编译管理
  • 一个外设的驱动程序模板一般都需要这几个文件

具体展开讲:

  • xxxDrv.c –> 内核层驱动实现文件
/*设备驱动模块加载函数*/
static int __init key_init(void) 
{
    int ret;

    printk("key_init\n");
    devNo = MKDEV(251, 2); //通过主设备号(251)和次设备号(2)生成一个dev_t的设备号 
    ret = register_chrdev_region(devNo, 1, "key"); //用来向系统申请设备号
    if (ret < 0) {
        printk("Register char device faikey, ret = %d\n", ret);
        goto err;
    }

    cdev_init(&keyDev, &key_ops);  //用来初始化cdev的成员,并建立cdev和file_operations之间的连接
    keyDev.owner = THIS_MODULE;

    ret = cdev_add(&keyDev, devNo, 1);  //向系统添加一个cdev,完成字符设备的注册
    if (ret < 0) {
        printk("Add dev faikey\n");
        unregister_chrdev_region(devNo, 1);
        goto err;
    }
    printk("Hello device init success\n");
    //实现具体的硬件初始化!
    s3c2410_gpio_cfgpin(S3C2410_GPF(KEY0), S3C2410_GPIO_INPUT);
    s3c2410_gpio_cfgpin(S3C2410_GPF(KEY1), S3C2410_GPIO_INPUT);
    s3c2410_gpio_cfgpin(S3C2410_GPF(KEY2), S3C2410_GPIO_INPUT);
    s3c2410_gpio_cfgpin(S3C2410_GPF(KEY3), S3C2410_GPIO_INPUT);
err:
    return 0;
}

/*备驱动模块卸载函数*/
static void __exit key_exit(void) 
{
    printk("key_exit\n");
    cdev_del(&keyDev);     //从系统中删除一个cdev,完成字符设备的注销
    unregister_chrdev_region(devNo, 1);  //向系统申请,删除设备号,释放被占用的设备号
}

// 相关的几个设备驱动函数
static ssize_t key_read (struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
    return size;
}

static ssize_t key_write (struct file *filp, const char __user *buf, size_t size, loff_t *offset)
{
    return 0;
}

static int key_open(struct inode *inode, struct file *filp)
{
    printk("Open driver\n");
    return 0;
}

static int key_release (struct inode *inode, struct file *filp)
{
    printk("Close driver\n");
    return 0;
}

static long key_ioctl (struct file *filp, unsigned int cmd, unsigned long param)
{
    printk("ioctl driver\n");
    return 0;
}

// 配置key_ops结构体!
static struct file_operations key_ops = {
    .owner   = THIS_MODULE,
    .read    = key_read,
    .write   = key_write,
    .open    = key_open,
    .release = key_release,
    .llseek  = key_lseek,
    .unlocked_ioctl = key_ioctl,
};

// 内核调用相关函数
module_init(key_init);
module_exit(key_exit);
  • xxx.c –> 应用层驱动封装函数
// 设备初始化
int keyInit(void)
{
    int ret;
    keyFd = open("/dev/key", O_RDWR, 0666);  // 打开相关设备文件
    if (keyFd < 0) {
        printf("Open key device faikey\n");
        return -1;
    }

    /* 执行相应的其他初始化操作 */

    return 0;
}

// 设备复位,和设备初始化相对应!
void keyDeInit(void)
{
    /* 一系列相关的反初始化操作 */
    close(keyFd);     // 关闭设备文件
}

/*
* 其他的一系列相关应用层函数
*/
  • test.c –> 测试驱动所有的应用层代码
int main(void)
{
    /*
    *   相关的具体功能逻辑实现
    */
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页