告别迷茫!手把手教你用VSCode+Makefile搭建i.MX6ULL裸机开发环境(Ubuntu 20.04保姆级教程)

张开发
2026/5/31 7:05:07 15 分钟阅读
告别迷茫!手把手教你用VSCode+Makefile搭建i.MX6ULL裸机开发环境(Ubuntu 20.04保姆级教程)
从零构建i.MX6ULL裸机开发环境VSCodeMakefile实战指南嵌入式开发的世界里i.MX6ULL处理器因其出色的性价比和丰富的外设资源成为众多工业控制和物联网项目的首选。但对于刚接触裸机开发的工程师来说搭建一个高效可靠的开发环境往往成为第一道门槛。本文将彻底解决这个问题——我们将基于Ubuntu 20.04 LTS使用VSCode作为核心开发工具配合Makefile实现自动化编译打造一个专业级的i.MX6ULL裸机开发环境。1. 环境准备与工具链配置1.1 虚拟机与Ubuntu基础环境在物理机上直接开发嵌入式系统存在诸多不便使用虚拟机是最佳实践。VMware Workstation Pro 16提供了完美的解决方案# 检查VMware版本 vmware --version安装Ubuntu 20.04 LTS时有几个关键配置点需要注意磁盘分配建议至少40GB空间内存设置开发机推荐4GB以上网络模式桥接模式最方便开发安装完成后立即执行以下基础配置# 更新软件源并升级系统 sudo apt update sudo apt upgrade -y # 安装基础开发工具 sudo apt install -y build-essential git make gcc gdb1.2 交叉编译工具链安装i.MX6ULL采用ARM Cortex-A7架构需要专门的交叉编译工具链。Linaro GCC 7.5是经过验证的稳定版本# 创建工具链目录 mkdir -p ~/toolchains cd ~/toolchains # 下载Linaro GCC 7.5 wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz # 解压并设置环境变量 tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz echo export PATH$PATH:~/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin ~/.bashrc source ~/.bashrc # 验证安装 arm-linux-gnueabihf-gcc --version工具链验证成功后还需要安装相关依赖库sudo apt install -y libncurses5-dev libssl-dev flex bison2. VSCode开发环境配置2.1 核心插件安装VSCode已成为嵌入式开发的首选IDE以下插件必不可少插件名称功能描述配置要点C/C智能提示和调试支持配置c_cpp_properties.jsonRemote-SSH远程开发支持配置SSH免密登录Makefile ToolsMakefile支持设置build目录ARM AssemblyARM汇编高亮无需额外配置安装完成后需要特别配置C/C插件的include路径// .vscode/c_cpp_properties.json { configurations: [ { includePath: [ ${workspaceFolder}/**, ~/toolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/include ] } ] }2.2 远程开发配置使用Remote-SSH插件可以实现在Windows主机上开发在Linux虚拟机中编译的高效工作流在Ubuntu中安装SSH服务sudo apt install -y openssh-server sudo systemctl enable ssh在Windows主机生成SSH密钥对并复制公钥到Ubuntussh-copy-id usernameubuntu-ipVSCode中配置Remote-SSH连接Host imx6ull-dev HostName ubuntu-ip User username IdentityFile ~/.ssh/id_rsa3. 工程结构与Makefile设计3.1 合理的工程目录结构一个专业的裸机工程应该具备清晰的模块化结构imx6ull-baremetal/ ├── bsp/ # 板级支持包 │ ├── led/ # LED驱动 │ ├── uart/ # 串口驱动 │ └── ... # 其他外设驱动 ├── project/ # 应用代码 │ ├── start.S # 启动汇编 │ └── main.c # 主程序 ├── imx6ull/ # 芯片头文件 │ ├── fsl_common.h # NXP通用头文件 │ └── MCIMX6Y2.h # 寄存器定义 ├── Makefile # 构建脚本 └── imx6ull.lds # 链接脚本3.2 高效Makefile编写Makefile是自动化构建的核心以下是一个针对i.MX6ULL优化的模板# 工具链配置 CROSS_COMPILE arm-linux-gnueabihf- CC $(CROSS_COMPILE)gcc LD $(CROSS_COMPILE)ld OBJCOPY $(CROSS_COMPILE)objcopy # 工程配置 TARGET baremetal_demo BUILD_DIR build # 源文件配置 SRCS project/start.S \ project/main.c \ bsp/led/led.c OBJS $(addprefix $(BUILD_DIR)/,$(notdir $(SRCS:.c.o))) OBJS : $(OBJS:.S.o) # 编译选项 CFLAGS -mcpucortex-a7 -mfpuneon-vfpv4 -mfloat-abihard \ -nostdlib -ffreestanding -O2 -Iimx6ull -Ibsp # 构建规则 all: $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/%.o: project/%.S | $(BUILD_DIR) $(CC) -c $(CFLAGS) $ -o $ $(BUILD_DIR)/%.o: project/%.c | $(BUILD_DIR) $(CC) -c $(CFLAGS) $ -o $ $(BUILD_DIR)/$(TARGET).elf: $(OBJS) $(LD) -Timx6ull.lds $^ -o $ $(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf $(OBJCOPY) -O binary $ $ $(BUILD_DIR): mkdir -p $ clean: rm -rf $(BUILD_DIR) .PHONY: all clean关键优化点自动创建build目录隔离中间文件支持多目录源文件编译针对Cortex-A7的优化编译选项清晰的依赖关系定义4. 调试与烧写技巧4.1 串口调试配置在没有JTAG的情况下串口是最常用的调试手段安装CH340驱动sudo apt install -y linux-modules-extra-$(uname -r)配置minicomsudo apt install -y minicom sudo minicom -s配置参数串口设备/dev/ttyUSB0波特率115200硬件流控关闭4.2 镜像烧写工具使用正点原子提供的imxdownload工具烧写SD卡# 给烧写工具执行权限 chmod x tools/imxdownload # 烧写到SD卡确认设备名正确 ./tools/imxdownload build/baremetal_demo.bin /dev/sdX烧写过程输出解析头信息解析成功 镜像大小: 32KB 烧写偏移: 1KB 开始烧写... [] 100% 烧写完成耗时: 1.2s4.3 常见问题排查遇到启动失败时按以下步骤排查检查反汇编代码arm-linux-gnueabihf-objdump -D build/baremetal_demo.elf disassembly.txt确认向量表位置Disassembly of section .text: 87800000 _start: 87800000: e59ff018 ldr pc, [pc, #24] ; 87800020 Reset_Handler检查SD卡启动模式BOOT_MODE0: 接地BOOT_MODE1: 接3.3V5. 进阶开发技巧5.1 多文件工程管理随着工程规模扩大需要更智能的Makefile管理# 自动查找源文件 SRC_DIRS project bsp SRCS $(shell find $(SRC_DIRS) -name *.c -or -name *.S) # 自动生成依赖 DEP_DIR $(BUILD_DIR)/dep DEPFLAGS -MT $ -MMD -MP -MF $(DEP_DIR)/$*.d COMPILE.c $(CC) $(DEPFLAGS) $(CFLAGS) -c $(BUILD_DIR)/%.o: %.c | $(DEP_DIR) $(COMPILE.c) $ -o $ $(DEP_DIR): mkdir -p $ -include $(wildcard $(DEP_DIR)/*.d)5.2 链接脚本优化针对i.MX6ULL的内存布局优化链接脚本MEMORY { ROM (rx) : ORIGIN 0x87800000, LENGTH 1M RAM (rwx) : ORIGIN 0x87900000, LENGTH 15M } SECTIONS { .text : { KEEP(*(.vectors)) *(.text*) } ROM .data : { __data_start .; *(.data*) __data_end .; } RAM AT ROM .bss : { __bss_start .; *(.bss*) *(COMMON) __bss_end .; } RAM }5.3 自动化测试框架集成简单的测试框架加速开发迭代// test_framework.h #define TEST_CASE(name) void name(void) #define RUN_TEST(test) do { \ printf(Running %s... , #test); \ test(); \ printf(Passed\n); \ } while(0) // 示例测试用例 TEST_CASE(test_led_init) { if(led_init() ! 0) { printf(LED init failed\n); while(1); } }在开发过程中我发现最影响效率的往往是环境配置的不一致。通过将开发环境容器化可以彻底解决这个问题# Dockerfile.dev FROM ubuntu:20.04 RUN apt update apt install -y \ build-essential \ gcc-arm-linux-gnueabihf \ git \ make WORKDIR /workspace CMD [/bin/bash]

更多文章