仓库已经开源!所有教程,主线内核移植,跑新版本imx-linux/uboot都在这里!欢迎各位大佬观摩!喜欢的话点个⭐!
仓库地址:https://github.com/Awesome-Embedded-Learning-Studio/imx-forge
静态网页:https://awesome-embedded-learning-studio.github.io/imx-forge/
当你第一次在 VSCode 中打开 driver/chardev_led_v1_01/alpha-board/chardev_led_v1_01_main.c 时,可能会遇到这种情况:
<linux/module.h>pr_info()struct file_operationsioremap()这些都是正常的! 因为内核代码不是标准的用户空间程序,它需要特殊的编译配置:
__KERNEL__ 宏不过没事,内核有compile_commands,完全可以更加丝滑的开发驱动!
在 VSCode 中安装 clangd 插件(由 LLVM 官方提供)。
注意:安装 clangd 后,建议禁用 C/C++ IntelliSense(Microsoft 的 cpptools),因为两者会冲突。
# 确认内核源码存在
ls -la third_party/linux_mainline/include/linux
ls -la third_party/linux_imx/include/linux # 如果使用 imx 内核
# 确认交叉编译器在 PATH 中
which arm-none-linux-gnueabihf-gcc
clangd 通过以下方式(按优先级排序)获取配置:
.clangd 文件compile_commands.jsoncompile_flags.txt对于内核驱动开发,核心是 compile_commands.json,它由内核构建系统自动生成,包含了完整的编译信息。
compile_commands.json 是一个 JSON 格式的编译数据库,记录了每个源文件的完整编译命令,包括:
Linux 内核构建系统已经内置了生成 compile_commands.json 的支持。
内核使用 scripts/clang-tools/gen_compile_commands.py 脚本:
.cmd 文件.cmd 文件中提取编译命令compile_commands.json# 检查文件是否存在
ls -lh third_party/linux_mainline/compile_commands.json
# 查看内容格式(应该是 JSON 数组)
head -30 third_party/linux_mainline/compile_commands.json
典型的条目格式:
{
"command":"arm-none-linux-gnueabihf-gcc -I... -D__KERNEL__ ... -c file.c",
"directory":"/home/charliechen/imx-forge/out/mainline/linux",
"file":"/path/to/source/file.c"
}
项目根目录已经配置好 .clangd,直接指向内核的 compile_commands.json:
# .clangd (项目根目录)
CompileFlags:
CompilationDatabase:third_party/linux_mainline
Remove:
--mno-fp-ret-in-387
--mpreferred-stack-boundary=*
# ... 更多需要过滤的编译标志
这个配置的工作原理:
CompilationDatabase: third_party/linux_mainlinecompile_commands.jsonRemovecompile_commands.json 中获取所有需要的头文件路径和宏定义由于内核的 compile_commands.json 已经包含了所有必要的编译信息,项目根目录的 .clangd 配置可以让 clangd 正确解析:
✅ 内核头文件路径(<linux/module.h>、<asm/io.h> 等) ✅ 架构相关路径(arch/arm/include/ 等) ✅ 预处理器宏(__KERNEL__、架构宏等) ✅ 所有驱动的内核 API(copy_to_user()、ioremap() 等)
因此,在项目任何目录下打开驱动代码,clangd 都能正常工作!
Ctrl+Shift+P 打开命令面板clangd: Restart打开 chardev_led_v1_01_main.c,测试以下功能:
#include"linux/module.h"
// 应该能补全 MODULE_LICENSE、MODULE_AUTHOR 等
MODULE_
// 应该能看到 pr_info 的参数提示
pr_info("test\n");
F12 或 Ctrl+Click 跳转到 module.h 的定义copy_to_user() 的定义原因:内核头文件路径不正确
解决:检查 .clangd 中的路径是否正确,使用相对路径:
# 从项目根目录验证
ls third_party/linux_mainline/compile_commands.json
# 验证内核头文件存在
ls third_party/linux_mainline/include/linux/module.h
原因:某些编译标志不被 clangd 支持
解决:在项目根目录 .clangd 的 CompileFlags.Remove 中添加这些标志:
Remove:
--fno-ipa-sra
--fzero-init-padding-bits=all
# 添加更多需要过滤的标志