![嵌入式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=1738863494-yWZCAaJPMvupMOMp5ALsKlfgTFQIGCjl-0-480d15991db5ea139b2a562e30385bdf)
解压下载的64位的Neon Eclipse:
![051-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-03.jpg?sign=1738863494-aFmu6s73ZTVg9BM98h9LdWKl9xv13pgF-0-8fd2c30b57453c1d536d4661e48ca6f4)
请确保运行的Eclipse为Yocto SDK做好了配置。这样配置工具链(路径)就很方便了。下面将使用SAMA5D2的内核源码和Yocto SDK的交叉编译工具链来演示如何配置Eclipse以开发驱动程序。
![051-04](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-04.jpg?sign=1738863494-fg7l4YTSvUzyXSP2CgpGpOxAYkK7OXLs-0-0be82d42dfd6b1847e8c97b18d05497b)
选择工作区路径,例如:
![051-05](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/051-05.jpg?sign=1738863494-maoZ5wKglPAnGR0HI35A6WqfOr165iqa-0-c041beda0efa7b8cc9b80b9362347911)
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=1738863494-TmIskaPgSmDIW3xnUN3isOSf436TuaQ3-0-8fa9847078db1f9e65b5b84602b8885a)
图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=1738863494-v2vqxU8uowWfJcoQqSrMEdR9pbdtKm5b-0-7b08df48511ec05187365bdfc7661047)
图1-6 Eclipse C工程配置
3. 添加包含printk()
宏定义的文件。如果不进行这一步,索引器将找不到它(因为它被用在很多地方),如图1-7所示。
![053-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/053-01.jpg?sign=1738863494-RD8kZ2fPKRJ1NWyJ84lWfbAnnvk9Gq5J-0-dbe09f8c88191907b2e63a264e1e2fd5)
图1-7 添加包含printk()
定义的文件
4. 单击Providers标签,去掉交叉编译器的默认搜索路径。索引器应使用内核内头文件来代替工具链根路径下的文件,如图1-8所示。
![053-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/053-02.jpg?sign=1738863494-4sOD4zMlo6pV1cvvNq36U5ZSf7uyOuFS-0-7bf344ef9065f8f206b498f1b6c3067a)
图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=1738863494-ePUI0osCtBnhef1IftuXX8HGTqKapeGl-0-4a2feff89edf6a6e3370522b20fa8920)
图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=1738863494-OAza5Fw13DVEzr9utLyhBzqlSZg2bwbq-0-ccad5d2a613c95eb2ed4c41d31e195ff)
图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=1738863494-5GQYIOQnxaHPY9lOsAcKax56nfvF8jOy-0-d27527b9b222baa5b573c666232e961c)
图1-11 定义过滤器
8. 禁止未包含在构建中的索引文件。这可以减少要索引的文件数,如图1-12所示。
![055-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/055-02.jpg?sign=1738863494-AIuoogWw6ZG4nFqAZ9P0TxhbTzc9YpoT-0-b71ce46f0476970b3ef8434917e24c44)
图1-12 禁止不必要的索引文件
9. 设置与构建内核相关的构建参数,如图1-13所示。
![055-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/055-03.jpg?sign=1738863494-f2dCtihV3AENMUnomBENmofzyd8SYuEh-0-39970ad5f6ed965c629413c1d337e65e)
图1-13 设置内核构建参数
10. 在子页面Environment中设置合适的环境路径。这样的话不用每次打开Eclipse时都要获取环境。单击PATH变量(检查以确保突出显示)。如图1-14所示。
![056-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/056-01.jpg?sign=1738863494-A2ir75W7BXLeMyRkoDO2w6ETxFaqSl7I-0-e82d89ebb64c1ae88fdbe4bbf890e1c2)
图1-14 设置环境变量参数
11. 单击OK按钮以保存选项并运行过滤器。使用强制重构选项,确保每一个文件被正确索引。这可以通过工程管理的上下文菜单完成:
![056-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/056-02.jpg?sign=1738863494-Gy5HadcMSURtrBEdFMaS2ezyUAeX4bs6-0-65a047ed9f821b6bce6663f2a5dd7fb2)
建立索引将需要几分钟的时间。在工作区的目录里大约有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=1738863494-BCSpUO03p7gfV0jPOeON6qMsnsWj9Zgy-0-3d53b849150cd3bf2c66720e5ef9b874)
图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=1738863494-vba9uVL3vSDS6ki3Vi8gXtbCZKab4q9p-0-9253de1cf5caa4ffc11a3fbf9504d033)
![057-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/057-03.jpg?sign=1738863494-UmIx4rkbLLb9YgXbH2mwpwyO1TDN8E67-0-130a969347044fb1942be2d33bee09db)
图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=1738863494-Cq6mbnlmMJ8Hu3uuHIh4wMvNwP85Ts1J-0-bfca77189c7358673d0ebb85a9d83036)
图1-17 关闭工具链搜索路径
![058-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/058-02.jpg?sign=1738863494-uEIY8lN1BYQcexGa1LMCrB8VugHQHbjo-0-055456c86626413b7b253f203e46d181)
图1-18 设置工具链搜索路径
4. 定义__KERNEL__符号和__LINUX_ARM_ARCH__(其值为7):
![058-03](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/058-03.jpg?sign=1738863494-GlsYKxbcMOSHs1TdY2e0XAGxqaH429Ek-0-4646e38de304838b0ee5e75b14e69b2d)
图1-19 定义内核符号
5. 如图1-20所示,使用子页面Environment设置合适的环境路径。这样的话不用每次打开Eclipse时都要获取环境。单击PATH变量。在打开Eclipse之前务必获取环境路径。
![059-01](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/059-01.jpg?sign=1738863494-YFF4dlcd4SCrAId8w0L3gEwT5Pvi3vHG-0-e7374c1a32861fe71a2afe0de0c0880f)
图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=1738863494-AuEIBPYEG9u4MAlP4lVg1jfGhdEmD4hC-0-0436ddf18f9f5bab791a49144642c585)
图1-21 设置部署和清理目录名称
重复编写deploy
和clean
目标的名称。
![059-02](https://epubservercos.yuewen.com/D1DB85/20966230701867406/epubprivate/OEBPS/Images/059-02.jpg?sign=1738863494-4aSzXhcdrOVLFOEs9M5I1LUpil6FiG7b-0-887b67c191b47689a164ee4e48b1d2d8)
现在可以单击编译按钮来构建、清理并部署自己编写的Linux内核模块!