zoukankan      html  css  js  c++  java
  • 驱动学习1:第一个驱动入门

    Linux驱动程序,首先应该知道它是linux的内核模块。

    Linux内核模块是使得复杂而庞大的linux内核条理清晰、可裁剪、高兼容性的重要特性。

    Linux内核模块的特点:

    1,  模块本身不被编译进内核镜像,能够控制内核的大小。

    2,  模块可以在需要的时候中被动态加载,一旦加载完成就和内核其它部分完全一样。

    下面便是linux内核模块的helloworld程序,结构十分固定。

    (1) 模块加载函数

    当通过insmod或者modprobe命令加载内核模块时,模块的加载函数会自动执行,完成本模块的相关初始化工作

    (2) 模块卸载函数

    当通过rmmod命令卸载内核模块时,模块的卸载函数会自动执行,完成本模块的卸载功能

    (3) 模块许可证声明

    如果不声明LICENSE,模块被加载时,将收到内核被污染(Kernel Tainted)的警告。

    (4) 模块参数(可选)

    模块参数是模块被加载的时候可以传递给它的值,它本身对应模块内部的全部变量

    (5) 模块导出符号(可选)

    内核模块可以导出的符号(symbol,对应函数或变量),若导出,则其他模块可以使用本模块中的变量或函数

    (6) 模块作者等信息声明(可选)

    这个驱动并不具有任何控制硬件的行为,只是为了展示linux驱动的通用结构。这几乎是所有驱动程序的通用模版,如led的驱动程序,只需要在hello_ioctl函数中根据不同的传入参数操作gpio寄存器即可。(应用层没有操作硬件的权限,而内核中具有所有权限。驱动程序的作用就是高效的、封装的、有限的向应用层提供服务)

    代码:

     1 /*  
     2 hello.c - The simplest kernel module.
     3 */
     4 #include <linux/kernel.h>
     5 #include <linux/init.h>
     6 #include <linux/module.h>
     7 #include <linux/slab.h>
     8 #include <linux/io.h>
     9 #include <linux/interrupt.h>
    10 
    11 #include <linux/of_address.h>
    12 #include <linux/of_device.h>
    13 #include <linux/of_platform.h>
    14 
    15 /* Standard module information */
    16 MODULE_LICENSE("GPL");
    17 MODULE_AUTHOR("pp.");
    18 MODULE_DESCRIPTION("hello module template ");
    19 
    20 #define DRIVER_NAME "hello"
    21 
    22 unsigned myint = 0xdeadbeef;
    23 char *mystr = "default";
    24 
    25 module_param(myint, int, S_IRUGO);
    26 module_param(mystr, charp, S_IRUGO);
    27 
    28 static int __init hello_init(void)
    29 {
    30     printk(KERN_INFO "Hello module world.
    ");
    31     printk(KERN_INFO "Module parameters were (0x%08x) and "%s"
    ", myint,mystr);
    32 
    33     return 0;
    34 }
    35 
    36 
    37 static void __exit hello_exit(void)
    38 {
    39     printk(KERN_ALERT "Goodbye module world.
    ");
    40 }
    41 
    42 module_init(hello_init);
    43 module_exit(hello_exit);

    编译后生成.ko文件,移植到开发板linux下测试

    默认情况下

    root@plnx_arm:/mnt# insmod hello.ko 
    Hello module world.
    Module parameters were (0xdeadbeef) and "default"
    root@plnx_arm:/mnt# lsmod          
        Tainted: G  
    hello 817 0 - Live 0xbf004000 (O)
    root@plnx_arm:/mnt# rmmod hello    
    Goodbye module world.

    传入参数时:

    root@plnx_arm:/mnt# insmod hello.ko myint=123  mystr="pp"
    Hello module world.
    Module parameters were (0x0000007b) and "pp"
    root@plnx_arm:/mnt# rmmod hello
    Goodbye module world.

    通过其他的查询命令可以看到内核的输出:

    root@plnx_arm:/mnt# ls /sys/module/hello/parameters/
    myint  mystr
    root@plnx_arm:/mnt# tail -n 2 /var/log/messages 
    Jun  4 09:56:33 plnx_arm user.info kernel: Hello module world.
    Jun  4 09:56:33 plnx_arm user.info kernel: Module parameters were (0x0000007b) and "pp"

    在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载。

    静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用。静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新编译和下载内核,效率较低。若采用静态加载的驱动较多,会导致内核容量很大,浪费存储空间。

    动态加载利用了Linux的module特性,可以在系统启动后用insmod命令添加模块(.ko),在不需要的时候用rmmod命令卸载模块,采用这种动态加载的方式便于驱动程序的调试,同时可以针对产品的功能需求,进行内核的裁剪,将不需要的驱动去除,大大减小了内核的存储容量。

    在台式机上,一般采用动态加载的方式;在嵌入式产品里,可以先采用动态加载的方式进行调试,调试成功后再编译进内核。

     

  • 相关阅读:
    Web中路径问题
    post请求乱码
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_10-freemarker静态化测试-基于模板文件静态化
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_09-freemarker基础-内建函数
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_08-freemarker基础-空值处理
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_07-freemarker基础-if指令
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_06-freemarker基础-遍历map数据
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_05-freemarker基础-List指令
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_04-freemarker基础-基础语法种类
    阶段5 3.微服务项目【学成在线】_day04 页面静态化_03-freemarker测试环境搭建
  • 原文地址:https://www.cnblogs.com/shuqingstudy/p/9149598.html
Copyright © 2011-2022 走看看