当前位置:首页 > 公众号精选 > IOT物联网小镇
[导读]作 者:道哥,10年嵌入式开发老兵,专注于:C/C、嵌入式、Linux。关注下方公众号,回复【书籍】,获取Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章(PDF格式)。目录学习的困惑实践环境编译进内核编译为驱动模块资料下载别人的经验,我们的阶梯!大家好,我是道哥...

作  者:道哥,10 年嵌入式开发老兵,专注于:C/C 、嵌入式、Linux


关注下方公众号,回复【书籍】,获取 Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章( PDF 格式)。


目录


  • 学习的困惑


  • 实践环境


  • 编译内核


  • 编译为驱动模块


  • 资料下载


别人的经验,我们的阶梯!


大家好,我是道哥。今天给大家分享一些笔记本里的一些存货: Linux 系统中的驱动和中断相关。


大概会用 6~7 篇的文章,由浅入深的为大家介绍Linux中驱动程序的编写方法。


文章的顺序,也是我之前自己学习时的顺序。


以前的学习记录比较零散,现在只是把它们按照一定的顺序重新梳理一下。


这几篇文章,理论知识会少一些,更注重实际的操作


我会把操作用引导的代码,全部上传到网盘上,在文末有下载说明


只要根据文中介绍的步骤进行操作,就一定可以操作成功。


学习的困惑

记得以前我在开始学习驱动开发的时候,找来很多文章、资料来学习,但是总是觉得缺少了点全局视角。


就好像:我想看清一座山的全貌,但总是被困在一个、又一个山谷中一样。


主要的困惑有 3 点:


  1. 每一篇文章的介绍都是正确的,但是如果把很多文章放在一起看,就会发现怎么说的都不一样啊?


  2. 有些文章注重函数的介绍,但是缺乏一个全局的视角,从整体上来观察驱动程序的结构;


  3. 对于一个新手来说,能够边学习、边实践,这是最好的学习方式,但是很多文章不会注意这方面。虽然文章内容很漂亮,但是不知道怎么去实践、验证。


因此,这几篇文章我们就从最简单的驱动模块编译开始,然后介绍字符设备驱动程序。


在这部分,会以 GPIO 为例子,重点描述其中的关键节点。


最后再介绍在中断处理程序中,如何利用信号量、小任务、工作队列,把内核事件传递到应用层来处理。


作为第一个开篇文章,从最简单的内核编译开始。


实际操作一下:如何把一个最简单的驱动程序(hello),按照 2 种方式进行编译:


  1. 编译进内核;


  2. 编译为一个独立的驱动模块;


实践环境

为了便于测试,以下操作都是在 Ubuntu16.04 操作系统里完成的。


编译Linux驱动程序,肯定需要内核源码,这里选择的是 linux-4.15 版本,可以在官网下载。


文末有下载方式。


下载之后,把linux-4.15.tar.gz解压到Ubuntu中任意目录即可,例如:解压到~/tmp/目录下:


$ tar -zxvf linux-4.15.tar.gz -C ~/tmp/

编译进内核

创建驱动程序目录

linux中的驱动,一般都放在 linux-4.15/drivers/ 目录下,因此在这个目录中创建一个hello文件夹。


$ mkdir linux-4.15/drivers/hello
对于一个驱动来说,最重要的就是3个文件:


  1. 源代码


  2. Kconfig


  3. Makefile


只要按照固定的格式来编写这3个文件,linux内核的编译脚本就可以确保把我们的驱动程序编译进去。


创建源文件

首先是源码,在hello文件夹中创建源文件hello.c:


$ cd linux-4.15/drivers/hello
$ touch hello.c
源文件hello.c的内容是:


#include

  • #include


  • // 当驱动被加载的时候,执行此函数
    static int __init hello_init(void)
    {
    printk(KERN_ALERT "welcome, hello"\n");
    return 0;
    }

    // 当驱动被卸载的时候,执行此函数
    static void __exit hello_exit(void)
    {
    printk(KERN_ALERT "bye, hello\n");
    }

    // 版权声明
    MODULE_LICENSE("GPL");

    // 以下两个函数属于 Linux 的驱动框架,只要把驱动两个函数地址注册进去即可。
    module_init(hello_init);
    module_exit(hello_exit);
    有两个小地方注意一下:


    1. 在内核中,打印函数是 printk,而不是 printf;


    2. 打印信息的级别有好几个,从 DEBUG 到 EMERG,这里使用的是 KERN_ALERT,方便查看打印信息。


    创建 Kconfig 文件

    这个文件是用来对内核进行配置的,当执行 make menuconfig 指令的时候,这个文件就被解析。


    先创建文件:


    $ cd linux-4.15/drivers/hello
    $ touch Kconfig
    添加如下内容:


    config HELLO
    tristate "hello driver"
    help
    just a simplest driver.
    default y
    第一行内容 config HELLO ,在执行配置的时候,将会生成一个变量 CONFIG_HELLO ,而这个变量,将会在编译的时候,被 Makefile 引用。


    最后一行的 default y ,就表示把 CONFIG_HELLO 的值设置成 y,从而让这个驱动被编译到内核中。


    现在,hello驱动中的KConfig配置文件已经准备好了,但是还需要这个配置文件登记到Linux内核的整体配置文件中。


    也就是把它登记在 linux-4.15/drivers/Kconfig 文件的末尾:


    source "drivers/hello/Kconfig"

    endmenu // 加在这一句的上面
    现在,可以来执行下面指令,看一下具体的配置界面:


    $ cd linux-4.15/
    $ make distclean
    $ make ARCH=x86_64 defconfig
    $ make ARCH=x86_64 menuconfig
    第2条指令,是用来把默认的配置保存到当前目录下的 .config 配置文件,也就是把一个默认的配置文件复制过来,作为我们自己的配置文件。


    以后再修改配置参数时,修改的内容就会存储在 .config 文件中,


    第3条指令,是用来配置内核的,可以进入Device Drivers菜单,然后在最底层看到我们的hello driver被标记成星号, 这表示被编译进内核。


    按向下方向键,把高亮定位到 Device Drivers ---> ,然后敲回车键,进入到 Device Drivers 的配置界面。


    按向下方向键,一直到最后一个条目,就可以看到我们的 hello 驱动了,如下:


    可以看到 hello driver 前面显示的是型号 *,这表示:该驱动将会编译进内核。


    我们可以按下空格键试一下,会在三种标记中切换:型号,M,空值。M 标记意思是编译成驱动模块。


    我们这里选择星号(编译进内核),然后按下右方向键,最下方的几个按键的焦点移动到按钮上:


    按下回车键,就会弹出保存对话框,选择默认保存文件 .config 即可,然后在按钮高亮的时候,按下回车键即可保存。


    此时,在弹出的确认窗口中,选择 ,按下回车键即可:


    此时,返回到 Device Drivers 的配置界面,在最下面的按钮中,选择让 高亮,然后一路退出即可。


    创建 Makefile 文件

    Makefile文件是make工具的脚本,首先创建它:


    $ cd linux-4.15/drivers/hello
    $ touch Makefile
    其中的内容只有一行:


    obj-$(CONFIG_HELLO) = hello.o
    1. CONFIG_HELLO 可以看做一个变量,在编译的时候,这个变量的值可能是:y, n 或者 m。


    2. 在刚才的 Kconfig 参数配置中,CONFIG_HELLO 被设置为 y,于是这句话就被翻译成:obj-y = hello,表示把 hello 驱动编译进内核。


    现在,hello驱动程序的Makefile已经创建好了,我们还要让linux内核的编译框架知道这个文件才行。


    在文件 linux-4.15/drivers/Makefile 中的末尾,添加如下内容:


    obj-$(CONFIG_HELLO) = hello/

    编译

    万事俱备,只欠编译!依次执行如下指令:


    $ cd linux-4.15/
    $ make -j4
    make指令执行结束之后,编译得到的内核中(vmlinux)就包含了我们的hello驱动。


    编译为驱动模块

    编译为驱动模块,也有两种 操作方式:


    编译所有的驱动模块

    1. 在执行 make ARCH=x86_64 menuconfig 指令的时候,把 hello 配置成 M;


    2. 然后在 linux-4.15 中执行编译模块指令:make -j4 modules。


    编译成功之后,就可以得到文件: linux-4.15/drivers/hello/hello.ko


    这样的编译指令,是把所有的模块都编译了一次(在输出信息中,可以看到编译了很多模块)。


    只编译 hello 这一个驱动模块

    另外一种编译驱动模块的方式是:进入hello目录,只编译这一个驱动模块。


    这种编译方法,就需要修改hello目录下的Makefile文件了,内容如下:


    可以把 hello 目录下的所有文件删除,只保留源文件 hello.c,然后新建 Makefile 文件。


    ifneq ($(KERNELRELEASE),)
    obj-m := hello.o
    else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
    default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    clean:
    $(MAKE) -C $(KERNEL_PATH) M=$(PWD) clean
    endif
    然后,在hello文件夹中执行make指令,即可得到驱动模块 hello.ko


    验证一下

    加载驱动:


    $ cd linux-4.15/drivers/hello
    $ sudo insmod ./hello.ko
    此时终端窗口是没有任何输出的,需要输入指令 dmesg | tail ,可以看到 hello_init 函数的输出内容:


    卸载驱动:


    $ sudo rmmod hello
    再次输入 dmesg | tail ,可以看到 hello_exit 函数的输出内容:


    资料下载

    在公众号【IOT物联网小镇】的后台回复关键字:1112,获取下列文件的网盘地址:


    linux-4.15.tar.gz


    hello文件夹压缩包



    ------ End ------
  • 本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
    换一批
    延伸阅读

    9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

    关键字: 阿维塔 塞力斯 华为

    加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

    关键字: AWS AN BSP 数字化

    伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

    关键字: 汽车 人工智能 智能驱动 BSP

    北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

    关键字: 亚马逊 解密 控制平面 BSP

    8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

    关键字: 腾讯 编码器 CPU

    8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

    关键字: 华为 12nm EDA 半导体

    8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

    关键字: 华为 12nm 手机 卫星通信

    要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

    关键字: 通信 BSP 电信运营商 数字经济

    北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

    关键字: VI 传输协议 音频 BSP

    北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

    关键字: BSP 信息技术
    关闭
    关闭