1.驱动编写后是一个C文件,通过make命令对其进行编译,生成 .KO文件,这个文件就是可执行的驱动文件,通过使用insmod xx.ko即可执行此驱动文件。如下为一个完整的驱动程序C文件。(用的是讯为开发板教程文件)

#include <linux/init.h>
#include <linux/module.h>

/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>

#define DRIVER_NAME "hello_ctl"

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");

static int hello_probe(struct platform_device *pdv){
    
    printk(KERN_EMERG "\tinitialized\n");
    
    return 0;
}

static int hello_remove(struct platform_device *pdv){
    
    return 0;
}

static void hello_shutdown(struct platform_device *pdv){
    
    ;
}

static int hello_suspend(struct platform_device *pdv){
    
    return 0;
}

static int hello_resume(struct platform_device *pdv){
    
    return 0;
}

struct platform_driver hello_driver = {
    .probe = hello_probe,
    .remove = hello_remove,
    .shutdown = hello_shutdown,
    .suspend = hello_suspend,
    .resume = hello_resume,
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
    }
};

static int hello_init(void)
{
    int DriverState;
    
    printk(KERN_EMERG "HELLO WORLD enter!\n");
    DriverState = platform_driver_register(&hello_driver);
    
    printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_EMERG "HELLO WORLD exit!\n");
    
    platform_driver_register(&hello_driver);    
}

module_init(hello_init);
module_exit(hello_exit);

2.程序运行步骤如下 :注册驱动  insmod 命令->module_init(hello_init)函数->static int hello_init(void),

->platform_driver_register(&hello_driver)->hello_probe函数;

删除驱动 :rmmod命令->module_exit(hello_exit)->static void hello_exit(void)->platform_driver_register(&hello_driver);

3.上面的操作只能注册驱动,如何让应用来调用驱动呢?这就得注册设备节点,有了设备节点,应用程序就能像打开文件一样打开节点,然后对其操控。完整程序如下:

#include <linux/init.h>
#include <linux/module.h>

/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
/*注册杂项设备头文件*/
#include <linux/miscdevice.h>
/*注册设备节点的文件结构体*/
#include <linux/fs.h>

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl123"
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");

static long hello_ioctl( struct file *files, unsigned int cmd, unsigned long arg){

printk("cmd is %d,arg is %d\n",cmd,arg);
    return 0;
}

static int hello_release(struct inode *inode, struct file *file){
    printk(KERN_EMERG "hello release\n");
    return 0;
}

static int hello_open(struct inode *inode, struct file *file){
    printk(KERN_EMERG "hello open\n");
    return 0;
}

static struct file_operations hello_ops = {
    .owner = THIS_MODULE,
    .open = hello_open,
    .release = hello_release,
    .unlocked_ioctl = hello_ioctl,
};

static  struct miscdevice hello_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &hello_ops,
};

static int hello_probe(struct platform_device *pdv){
    
    printk(KERN_EMERG "\tinitialized\n");
    misc_register(&hello_dev);
    
    return 0;
}

static int hello_remove(struct platform_device *pdv){
    
    printk(KERN_EMERG "\tremove\n");
    misc_deregister(&hello_dev);
    return 0;
}

static void hello_shutdown(struct platform_device *pdv){
    
    ;
}

static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
    
    return 0;
}

static int hello_resume(struct platform_device *pdv){
    
    return 0;
}

struct platform_driver hello_driver = {
    .probe = hello_probe,
    .remove = hello_remove,
    .shutdown = hello_shutdown,
    .suspend = hello_suspend,
    .resume = hello_resume,
    .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
    }
};

static int hello_init(void)
{
    int DriverState;
    
    printk(KERN_EMERG "HELLO WORLD enter!\n");
    DriverState = platform_driver_register(&hello_driver);
    
    printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_EMERG "HELLO WORLD exit!\n");
    
    platform_driver_unregister(&hello_driver);    
}

module_init(hello_init);
module_exit(hello_exit);
4.注册设备节点的过程如下:

insmod 命令->module_init(hello_init)函数->static int hello_init(void),

->platform_driver_register(&hello_driver)->hello_probe函数-> misc_register(&hello_dev);

就是在hello_probe函数增加了misc_register(&hello_dev);注册成功可在dev目录下看到hello_dev结构体中定义的设备节点名。

5.设备节点怎么用呢?代码如下:

#include <stdio.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

main(){
    int fd;
    char *hello_node = "/dev/hello_ctl123";
    
/*O_RDWR只读打开,O_NDELAY非阻塞方式*/    
    if((fd = open(hello_node,O_RDWR|O_NDELAY))<0){
        printf("APP open %s failed",hello_node);
    }
    else{
        printf("APP open %s success",hello_node);
        ioctl(fd,1,6);
    }
    
    close(fd);
}

6.运行上面的程序,open函数打开设备节点,ioctl函数操作设备节点,open函数和ioctl函数通过结构体

static struct file_operations hello_ops = {
    .owner = THIS_MODULE,
    .open = hello_open,
    .release = hello_release,
    .unlocked_ioctl = hello_ioctl,
};

映射到驱动程序的hello_open,hello_ioctl函数。而close(fd)就会映射hello_release函数。

注:以上程序源码都是用的讯为开发板程序代码。

Linux驱动编写入门-新解相关推荐

  1. linux驱动编写(入门)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在我离职之前,工作内容几乎不涉及到驱动方面的知识.我所要做的内容就是把客户对设备的请求拆分成一 ...

  2. Linux驱动快速入门

    本公众号分享的所有技术仅用于学习交流,请勿用于其他非法活动,如果错漏,欢迎留言指正 应用层:<LUNIX环境高级编程第二版> <Linux程序设计(第四版)> 内核层:< ...

  3. linux驱动编写--2--应用程序控制led闪烁

    本系列教程的上一篇:  linux驱动编写--1--点亮led 目标:编写一个驱动程序,实现上一篇没写的 "接口".并编写一个测试程序,透过驱动来控制led闪烁. 硬件:micro ...

  4. linux驱动编写(虚拟字符设备编写)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关 ...

  5. linux驱动编写(设备树)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对于linux的开发者来说,设备树其实比较熟悉.但是为什么要有设备树,很多人不了解,其实本质来说 ...

  6. linux驱动编写(看门狗)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 看门狗是linux驱动的一个重要环节.某些特殊的设备,有时候需要放在一些环境恶劣的地方,比如电信 ...

  7. linux驱动编写(platform总线和网卡驱动)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 对于linux驱动来说,一般的架构还是按照bus-host-device的形式来进行的.比如就拿 ...

  8. disk磁盘管理与Linux驱动编写

    磁盘管理 一.关于硬盘接口 安装linux red hat系统,到分区时发现硬盘驱动器设备 /dev/sda            #sata接口设备名 /dev/sda1#sda对应的物理分区 /d ...

  9. linux 驱动编写(sd卡驱动)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 随着sd卡的流行,sd卡在嵌入式设备上使用的场景也越来越多.那下面我们可以看一下,linux驱动 ...

最新文章

  1. PyTorch 常用代码段示例整理
  2. 23种设计模式C++源码与UML实现--访问者模式
  3. spring boot 中json数据处理
  4. 用ASP.NET 2.0设计网络在线投票系统
  5. ListView与Button共存问题
  6. dynamic的一些使用心得
  7. 用MATLAB解决实际数学问题,用matlab解决一道数学问题
  8. Keras Datasets 国内下载镜像
  9. 网站运营直通车——7天精通SEO
  10. 190325每日一句
  11. html登陆滑动验证,js实现登录时的滑动验证【原创】
  12. 谷歌浏览器离线安装包下载
  13. 服务器ie浏览器总是未响应怎么办,电脑ie浏览器老是无响应怎么办
  14. ubuntu18.04修改ip地址
  15. [转]PCI与PCIe
  16. 软件测试员工作经验分享
  17. (官网)虚幻3--基础游戏快速入门
  18. 什么是JDK、JRE
  19. Java基础题36:(多选题)下列有关于变量的命名正确的是 A.可以由字母、数字、下划线、”$”组成; 头
  20. 【深度之眼Python基础+数据科学入门训练营】第四章 组合数据类型

热门文章

  1. 转载:2014 Top Security Tools as Voted by ToolsWatch.org Readers
  2. 有源与无源晶振的区别
  3. .NET Framework各个版本(3.0 - 3.5)
  4. 谁先量子计算机谁就,G、IBM、中科院,比一比谁先实现量子计算霸权?
  5. Linux命令之top命令查看服务器CPU与内存占用
  6. 【开发工具】 我居然可以使用Office Tool Plus 安装上Office 真的是太不可思议了
  7. 十进制转32位二进制(Java)
  8. 数据库系统(PostgreSQL)
  9. markdown写公式的角标与下标
  10. mouseover和mouseout区别