搜索
bottom↓
回复: 0

《领航者ZYNQ之嵌入式Linux开发指南_V2.0》第三十六章 驱动静态

[复制链接]

出0入234汤圆

发表于 2022-1-23 11:31:29 | 显示全部楼层 |阅读模式
1)实验平台:正点原子领航者V2 ZYNQ开发板
2)  章节摘自【正点原子】《领航者ZYNQ之嵌入式Linux开发指南_V2.0》
3)购买链接:https://detail.tmall.com/item.htm?id=609032204975
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-329957-1-1.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子FPGA技术交流QQ群:90562473
1.png

2.jpg


3.png


第三十六章 驱动静态编译

       前面所有章节的驱动实验当中,我们都是将驱动代码编译成.ko驱动模块,然后在linux系统下使用insmod或modprobe命令加载驱动模块之后进行测试;驱动开发工程师将驱动代码编译成.ko驱动模块可以很方便的进行驱动调试,所以在驱动调试阶段一般都选择将其编译为模块,这样我们修改驱动以后只需要编译一下驱动代码即可,不需要编译整个Linux源代码;而且在调试的时候只需要加载或者卸载驱动模块即可,不需要重启整个系统。总之,将驱动编译为模块最大的好处就是方便开发,当驱动开发完成,确定没有问题以后就可以将驱动编译进Linux内核中,当然也可以不编译进Linux内核中,具体看自己的需求以及设备的特点来决定!
       那么本章将给大家介绍如何将驱动源码编译进Linux内核中,这里我把它叫做静态编译,本章就以上一章(第三十五章)驱动实验为例,将驱动源码编译进linux内核中。

       1.1修改Makefile
       首先将上一章实验目录16_asyncnoti下的驱动源文件asyncnoti.c拷贝到linux内核源码目录drivers/char目录下,如下所示:
第三十六章 驱动静态编译511.png

图 36.1.1 拷贝驱动源文件到内核源码目录

       /home/zynq/linux/kernel/linux-xlnx-xilinx-v2018.3是笔者内核源码所在目录,linux内核源码目录下的drivers文件夹中存放了驱动相关的代码,此目录根据驱动类型的不同,分门别类进行整理,比如drivers/i2c就是I2C相关驱动目录,drivers/gpio就是GPIO相关的驱动目录,而char目录下存放的就是字符设备相关的驱动代码,所以这里我们将驱动源文件asyncnoti.c拷贝到了drivers/char目录。
       打开drivers/char目录下的Makefile文件,将asyncnoti.c文件添加进来,如下所示:
第三十六章 驱动静态编译871.png

图 36.1.2 将asyncnoti.o添加到Makefile文件中

       内核源码drivers目录下的各个子目录以及子目录的子目录中一般都会存在一个Makefile文件,在这些Makefile文件中我们会看到很多“obj-$(CONFIG_XXX)  += xxxx.o”,例如图 36.1.2中所示。CONFIG_XXX变量一般可以取3个不同的值:y、m、n;所以将$(CONFIG_XXX)替换之后也就是定义了三个变量obj-y、obj-m、obj-n。
       当我们编译内核源码的时候,obj-y变量中所有的xxxx.o所对应的xxxx.c文件都会被编译进内核镜像;当在内核源码目录执行“make modules”编译内核模块的时候,obj-m变量中所有的xxxx.o文件对应的xxxx.c源文件会被编译成.ko驱动模块文件;而obj-n变量中所有的xxxx.o文件对应的xxxx.c源文件既不会编译进内核镜像文件,也不会编译成驱动模块。所以由此可以知道CONFIG_XXX好比是一个“选择器”,你可以选择将源文件编译进内核中,也可以选择编译成一个.ko驱动模块文件,也可以不编译。
       在图 36.1.2中我们将“obj-$(CONFIG_ASYNCNOTI)  += asyncnoti.o”添加到了Makefile文件的最后,CONFIG_ASYNCNOTI可以自定义,但是不能和其它名字冲突,一般就是“CONFIG_”加上.c源文件的大写字母;将内容添加到Makefile文件之后保存退出即可!
       1.2修改Kconfig
       打开内核源码drivers/char目录下的Kconfig文件,添加如下内容:
第三十六章 驱动静态编译1664.png

图 36.2.1 修改Kconfig文件

       关于Kconfig文件的语法在15.2.2小节中给大家介绍过,这里不再说明!“config ASYNCNOTI”其实就是CONFIG_ASYNCNOTI变量的配置项,用于配置CONFIG_ASYNCNOTI变量的值是y、m还是n。tristate表示三态,也就是可以将CONFIG_ASYNCNOTI变量的值设置为y、m或者n中的任何一个,后边携带的字符串信息表示的是对该config配置项的一个描述信息。
     “default y”表示该配置项的默认值是y,关于Kconfig文件的语法如果大家有什么不懂的可以看看15.2.2小节。在Kconfig文件中添加配置项之后,当我们在内核源码目录执行“make menuconfig”的时候就可以通过图形化界面的方式对其进行配置了。
       1.3menuconfig配置
        在内核源码目录下执行下面这些命令进入到menuconfig配置界面:
  1. make distclean                                                                                                                                // 清理整个工程
  2. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig        // defconfig
  3. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig                                // menuconfig
复制代码
第三十六章 驱动静态编译2371.png

图 36.3.1 执行menuconfig图形化配置界面命令

       进入menuconfig图形化界面之后,找到Character devices配置界面:
  1. Device Drivers  --->
  2.         Character devices  --->
复制代码
如下图所示:
第三十六章 驱动静态编译2545.png

图 36.3.2 Character devices配置界面

       在图 36.3.2中可以看到我们在上一个小节为asyncnoti.c驱动源文件添加的配置项“Character device key driver support”,“<*>”尖括号里边的“*”符号表示该配置项默认是选中的,也就是配置为“y”;将光标移动到该配置条目上,分别按键盘上的“Y”、“M”、“N”键可以分别选择将该驱动编译进内核、编译成单独的驱动模块、不编译驱动源文件。因为本章我们需要将驱动编译进内核中,所以这里选“Y”即可!
       对于menuconfig界面中的每一个配置项,都可以查看它的help帮助信息,如下所示:
第三十六章 驱动静态编译2910.png

图 36.3.3 menuconfig配置项帮助信息

       从图 36.3.3中可以知道,该配置项就是我们在图 36.2.1中所加入到Kconfig文件中的配置项。按回车键退出帮助页面,保存当前配置,然后退出menuconfig界面。
       1.4编译测试
       为了验证我们加入的asyncnoti.c驱动源文件在内核启动的时候会自动运行,我们可以在asyncnoti.c文件的驱动入口函数mykey_init中加入打印语句,如下所示:
第三十六章 驱动静态编译3211.png

图 36.4.1 加入打印语句

       修改完成之后保存退出即可,接下来就可以进行编译了,执行下面这条命令编译内核源码得到zImage镜像文件:
  1. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage -j16
复制代码
       编译完成之后,如下所示:
第三十六章 驱动静态编译3399.png

图 36.4.2 内核源码编译完成

       编译得到的zImage文件所在目录为arch/arm/boot/zImage,将zImage文件拷贝到开发板SD启动卡的Fat分区中,替换旧的zImage镜像文件,然后重新启动开发板;系统在启动过程当中就会自动运行asyncnoti.c驱动模块,打印信息如下所示:
第三十六章 驱动静态编译3595.png

图 36.4.3 内核启动打印信息

       图 36.4.3中标识出来的打印信息就是我们在asyncnoti.c驱动源文件中加入的打印信息,所以可以证明我们的驱动程序已经成功运行了,那么接下来可以进行驱动程序的测试工作了;输入用户名和密码登录开发板linux系统,进入到根文件系统/lib/modules/4.14.0-xilinx目录下,执行下面这条命令运行上一章的驱动测试程序asyncKeyApp:
  1. ./asyncKeyApp /dev/key
复制代码
       按下或者松开开发板的PS_KEY0按键,终端就会打印相应的信息,如下所示:
第三十六章 驱动静态编译3924.png

图 36.4.4 运行驱动测试程序

       测试的效果跟上一章测试情况是一样的,说明的驱动工作正常。测试完成之后按住键盘Ctrl+C组合键退出asyncKeyApp测试程序。将驱动代码静态编译到linux内核中之后,我们就不需要使用insmod或modprobe等方式加载.ko驱动模块了,内核启动的过程中会自动运行驱动程序!


回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 ( 公安交互式论坛备案:44190002001997 粤ICP备09047143号 )

GMT+8, 2022-8-8 21:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表