![嵌入式Linux设备驱动程序开发指南(原书第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/453/40381453/b_40381453.jpg)
1.12 使用Eclipse
Eclipse几乎为每种语言和体系结构都提供了IDE和平台环境。它们以Java、C/C++、JavaScript和PHP IDE而闻名,这些IDE构建在可扩展的平台上,用于创建桌面、Web和云IDE。这些平台为开发人员提供了最广泛的扩展组件工具集合。Eclipse可以用来浏览内核源码,以替代Linux终端的形式。
你将使用Neon版本来开发驱动。你可以从下面的地址下载Eclipse环境:https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr。转到Neon Packages
版本并下载Eclipse IDE C/C++ developers
(根据你的主机系统决定采用32位还是64位版本)。
安装Eclipse很简单,只需要下载正确的版本并解压它。系统必须安装正确版本的Java SDK。Ubuntu允许安装多个版本的Java虚拟机。Neon需要Java SDK8。
![051-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-02.jpg?sign=1739295007-Ou2rGksGsR9OkdFiLZ1jMmXyEnKd9PHg-0-0eb1a1c822209912c5ce470ce01af573)
解压下载的64位的Neon Eclipse:
![051-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-03.jpg?sign=1739295007-GevoYgtFbaGxAU7djNng70yOCwdmqnKP-0-dbafdbcecc9ff62261549bd15ae9d4b3)
请确保运行的Eclipse为Yocto SDK做好了配置。这样配置工具链(路径)就很方便了。下面将使用SAMA5D2的内核源码和Yocto SDK的交叉编译工具链来演示如何配置Eclipse以开发驱动程序。
![051-04](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-04.jpg?sign=1739295007-LPDBaahu5tw8DvMWCSl89nurr28UKzfF-0-268f1cd37a1c3e8d509e09801787a3a6)
选择工作区路径,例如:
![051-05](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-05.jpg?sign=1739295007-WgasYxHokeVoIIcdy333GubGkRIhKriF-0-62e6713bd2f8a4661e8712458b9dfb16)
1.12.1 用于内核源码的Eclipse配置
在配置Eclipse之前,须确保内核已经被配置和编译过(在之前的章节已经配置和编译过内核了),定义CONFIG_*并生成autoconf.h
。当配置和构建指定的体系结构时,会生成一些便于索引的必要文件。
1. 启动Eclipse并建立一个C工程(如图1-5所示):
- 打开File -> New -> C Project。
- 给工程起个名字(仅用于Eclipse),例如起名为
my_kernel
。 - 不要使用默认的路径(工作区)。将路径指向内核源码的文件夹:
/home/<user>/my-linux-sam
。 - 因为使用make构建内核,所以选择工程类型为Makefile工程。
- 使用交叉工具链Cross GCC。
- 打开Next -> Finish。
![052-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/052-01.jpg?sign=1739295007-6m5960vVmJf3ZMhaZ7oUcyXk2WThB9rg-0-c95d4f527c7d6f5aaf7b0340f55f728f)
图1-5 创建Eclipse C工程
2. 工程建立后要修改相关配置。打开Project->Properties并选择左侧的C/C++ General选项。单击Preprocessor Include Path,Macros etc..项,选择Entries标签并选择语言栏里的GUN C项。在Setting Entries列表里选择CDT User Settings Entries。添加include/linux/kconfig.h
文件作为预处理的宏文件,如图1-6所示。
![052-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/052-02.jpg?sign=1739295007-J6DqM4kGnMuixnTT8HxAzCpMJ0aN54hB-0-d661985d326dcde040835e5dffc42e64)
图1-6 Eclipse C工程配置
3. 添加包含printk()
宏定义的文件。如果不进行这一步,索引器将找不到它(因为它被用在很多地方),如图1-7所示。
![053-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/053-01.jpg?sign=1739295007-90d4U8HIL7w8z1FvNjMN1on95YCXeONb-0-c8b63eebfa661bad918253c481d7c3d2)
图1-7 添加包含printk()
定义的文件
4. 单击Providers标签,去掉交叉编译器的默认搜索路径。索引器应使用内核内头文件来代替工具链根路径下的文件,如图1-8所示。
![053-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/053-02.jpg?sign=1739295007-GZNdvlYJFEzjlAGIQw2J4rHUNqBxDlkL-0-2c940ca0f4083cd9b41cf799ed9a8689)
图1-8 配置搜索路径一
5. 必须包含内核里的include路径。内核不使用任何外部库。在C/C++ General选项单击Paths and Symbols,单击Includes标签并在语言栏选择GUN C选项。最后单击Add按钮,添加要包含的路径(如图1-9所示):
/my_kernel/include
:常规路径/my_kernel/arch/arm/include
:与体系结构相关路径
![054-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/054-01.jpg?sign=1739295007-YcOHqqC0nZV7KjsGRuIptp7YuiIHyWyF-0-479932e2a459f76f875fce3d64be4ecf)
图1-9 配置搜索路径二
6. 添加__KERNEL__(注意:KERNEL前后各有两个下划线符)和__LINUX_ARM_ARCH__(其值为7)符号。符号__KERNEL__在很多地方被用到,在一些文件中它用来区分内核API(已经定义了的)与用户态API(没有定义的)。在构建的时候,这些符号在Makefile中被设置。在Paths and Symbols选项中,选择Symbols标签,单击Add按钮添加这些符号,如图1-10所示。
![054-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/054-02.jpg?sign=1739295007-x1RizSHVNfxOHGnbenPgp28gsqLuJYyv-0-1fa04d094f2fedb814753d5fcbbd391d)
图1-10 配置符号
7. arch
目录包含处理器体系结构特定文件。必须定义过滤器,以排除与当前配置的体系结构文件无关的文件和文件夹。在Paths and Symbols选项,单击Source Location标签,然后选择Edit Filter标签并在新弹出的窗口单击Add Multiple标签,并选择arch/arm
之外的arch/
的所有子目录。同时过滤掉tools
目录,该目录包含冲突的include文件,如图1-11所示。
![055-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/055-01.jpg?sign=1739295007-kgEOi5eq5ZsRZ3RJeWEIbxNpCbSOSfWv-0-e80eeef9fe8858eadf7812c9c9ba9051)
图1-11 定义过滤器
8. 禁止未包含在构建中的索引文件。这可以减少要索引的文件数,如图1-12所示。
![055-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/055-02.jpg?sign=1739295007-EIrU5Vq8ZemhSl2sexdDgRUG8JKCr5aI-0-64391c24f58a86f8e17c097e0ed863a6)
图1-12 禁止不必要的索引文件
9. 设置与构建内核相关的构建参数,如图1-13所示。
![055-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/055-03.jpg?sign=1739295007-oyMH05n8H3Q5QH9gAiL6SJ9ZaDHQmrC6-0-606e1500e541b8eb679098960de2382f)
图1-13 设置内核构建参数
10. 在子页面Environment中设置合适的环境路径。这样的话不用每次打开Eclipse时都要获取环境。单击PATH变量(检查以确保突出显示)。如图1-14所示。
![056-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/056-01.jpg?sign=1739295007-FA6Xa6dW2CMWOmRZuZhjCTOA3Mr2zXDI-0-2ec89b3fa971d26b36e2108294eef19b)
图1-14 设置环境变量参数
11. 单击OK按钮以保存选项并运行过滤器。使用强制重构选项,确保每一个文件被正确索引。这可以通过工程管理的上下文菜单完成:
![056-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/056-02.jpg?sign=1739295007-R1AyuycHVTfZPWcDmZg0cpL9Dyium9EB-0-2756fbc662b19fe2d2db54d4173feb21)
建立索引将需要几分钟的时间。在工作区的目录里大约有700~800 MB的数据被创建。大约将分析20 000个文件(取决于内核版本)。
如果Eclipse被正确的配置好了,光标下方的符号将自动展开。如果配置不好,一些宏和符号将作为警告或者错误的形式突出显示出来。Eclipse索引器不同于GCC,其目标是使得内核源代码更容易被使用,而不是删除所有的警告信息。
现在Eclipse可以用来构建内核了。如果你改变了任意一个CONFIG_*设置项,为了让Eclipse识别这些改变,你可能需要从Eclipse构建一次工程。注意,这样并不意味着要重构索引,这意味着通过让Eclipse调用make命令来构建内核(通常在Eclipse的快捷键为<Ctrl+B>键)。Eclipse会自动检测对文件include/generated/autoconf.h
的改变,重新读取编译文件中的宏定义代码,然后重新构建索引。
1.12.2 用于开发Linux驱动程序的Eclipse配置
你将在Eclipse里创建一个工程来编写、构建并部署驱动程序。该配置看起来与内核源码的情况相同。
1. 创建一个新的Makefile C工程。指定存放驱动程序的位置。在图1-15中将看到路径是home/<user>/Linux_4.9_sam_drivers
。
![057-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/057-01.jpg?sign=1739295007-u7vA85YaUZgoaUvKO9Kd8rdUTpFruM04-0-b87a41aabe6bada6f4a7c69f2019f843)
图1-15 Linux驱动程序的Eclipse配置
请遵循以下步骤:
- 打开File -> New -> C Project。
- 设置工程名(仅用于Eclipse),例如提供名字
my_modules
。 - 不使用默认的位置(工作区)。同时指出包含内核模块源码的目录。
- 内核用make命令构建,所以选择Makefile工程。
- 使用交叉工具链。
- 打开Next -> Finish。
2. 创建工程后,修改设置。转到Project -> Properties,然后打开左侧的C/C++ General选项。单击Preprocessor include Paths, Macros etc..,然后单击Entries标签并在语言列表选择GNU C。在Setting Entries列表选择CDT User Setting Entries。必须通知索引器有关内核配置。必须包含内核工程里的kconfig.h
和printk.h
两个文件。单击Add标签两次,然后在显示的窗口选择Workspace Path并添加下面的路径(如图1-16所示):
![057-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/057-02.jpg?sign=1739295007-5Qz681ZmKM429NvaagffZIoUF9w0LXpG-0-e808f37fca501171b0993c0821821dc7)
![057-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/057-03.jpg?sign=1739295007-3jqBVVbvmhhm0zypx4dklZrRZ12lsXJS-0-783f241b46fe2bebc14d0f47d63c5880)
图1-16 添加内核搜索路径
3. 关闭工具链中内置的包含路径的搜索,并设置适当的包含路径。这些包含路径与内核工程的路径相同(my_kernel/include
和my_kernel/arch/arm/include
)。如图1-17和图1-18所示。
![058-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/058-01.jpg?sign=1739295007-dQiqkyvC2L0B07oMDzo2ypQFRUd0Mc73-0-b6ee6ba006769cfe6a4a33950d183230)
图1-17 关闭工具链搜索路径
![058-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/058-02.jpg?sign=1739295007-x9UT0LqenuiZT9MamzCgetCBLfOoyYGN-0-7d9a95f4491d645aef8e6f3cc30af901)
图1-18 设置工具链搜索路径
4. 定义__KERNEL__符号和__LINUX_ARM_ARCH__(其值为7):
![058-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/058-03.jpg?sign=1739295007-6nN4plQwGnNuC8Uim2Pcir59Xaq5vC9h-0-b10aba1fca19d5f3fc4dca14c33696bb)
图1-19 定义内核符号
5. 如图1-20所示,使用子页面Environment设置合适的环境路径。这样的话不用每次打开Eclipse时都要获取环境。单击PATH变量。在打开Eclipse之前务必获取环境路径。
![059-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/059-01.jpg?sign=1739295007-HaMoHc7hqyY27GNGnmyZF7McfzRR1qbK-0-08025b094996cb5272a815cb0bed7d26)
图1-20 设置环境变量参数
选择OK按钮保存设置。
创建新的helloworld.c
和Makefile
文件,并把它们保存在内核模块的源码目录。在my_modules
工程里,单击右键选择New -> Source File创建这些文件。在开发软件的时候先把代码写到文件里。此时可以将它们保持为空文件。
如图1-21所示在Build Targets
标签里,在my_modules
上单击右键,选择New并给目标起个名字all
。
![059-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/059-03.jpg?sign=1739295007-aYdbRQHoP12Z82eVizNyxqIExVxZgQFy-0-b7a32817e9392a6ff8250e51926de0a3)
图1-21 设置部署和清理目录名称
重复编写deploy
和clean
目标的名称。
![059-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/059-02.jpg?sign=1739295007-qv7diMtBh2dgoMGEgyDQA91qoklL983X-0-3d3a981c5673297dcaca487a24177cd2)
现在可以单击编译按钮来构建、清理并部署自己编写的Linux内核模块!