i.MX6ULL 裸机开发 C 语言驱动与 BSP 工程管理学习总结

i.MX6ULL裸机开发今日知识点总结

一、C语言操作寄存器

  1. volatile关键字:防止编译器优化寄存器读写,保证每次都直接读硬件寄存器地址,不能缓存到CPU寄存器。
  2. 寄存器两种定义方式
    • 方式1:宏直接强转地址:#define 寄存器名 *((unsigned int *)地址)
    • 方式2:结构体映射寄存器组,把一组连续寄存器封装成结构体,用指针访问,代码更简洁。
  3. LED裸机驱动函数
    • clock_init():打开CCM时钟门控CCGR0‑CCGR6,全部写0xFFFFFFFF,开启全部外设时钟;i.MX6ULL外设默认时钟关闭,不开启GPIO无法工作。
    • led_init():IO复用配置、电气属性配置、设置GPIO为输出方向。
    • led_on() / led_off():操作GPIO数据寄存器DR控制引脚电平。
    • led_delay():软件空循环延时,缺点:延时不精准,受CPU主频影响。
  4. 基础Makefile编写
    • 定义交叉编译工具链变量;
    • 模式规则 %.o:%.S、%.o:%.c,自动把汇编、C文件编译为.o目标文件;
    • 链接:-Ttext 地址指定程序运行起始地址;
    • objcopy:把elf转为可烧录的bin二进制文件;
    • objdump:生成反汇编.dis文件,用于调试查看汇编代码;
    • clean伪目标:清理编译产物;load伪目标:烧录bin到SD卡。

二、SDK头文件、BSP工程管理、链接脚本

  1. NXP SDK头文件使用

    • 不使用完整IDE,只提取SDK的头文件使用;
    • 使用SDK提供函数:IOMUXC_SetPinMux()引脚复用、IOMUXC_SetPinConfig()配置引脚电气参数;
    • 通过指针方式访问寄存器:GPIO1->GDIR、GPIO1->DR。
  2. 工程BSP目录规范(板级支持包)

    目录 存放内容
    project main.c、start.S(启动汇编)
    imx6ull 芯片SDK头文件MCIMX6Y2.h、fsl_iomuxc.h等
    bsp 外设驱动:led.c/h、beep.c/h硬件模块代码
  3. 蜂鸣器驱动硬件基础

    • S8550是PNP三极管做开关;基极高电平导通,蜂鸣器响。
  4. 链接脚本 imx6ull.lds

    • 作用:给链接器规定程序各段在DDR内存的排布蓝图。
    • . = 0x87800000:设置程序链接起始地址。
    • 段说明
      • .text:代码段,存放汇编、C的指令;必须把start.o放在text段最开头,上电最先执行启动汇编。
      • .rodata:只读常量数据段。
      • .data:已经初始化的全局变量。
      • .bss:未初始化全局变量;定义符号__bss_start、__bss_end标记BSS段首尾地址。
  5. 启动汇编start.S任务(非常重要) 上电不能直接跑main函数,汇编要做三件事:

    1. 设置栈指针SP(C语言函数调用、局部变量依赖栈);
    2. 根据__bss_start、__bss_end把BSS段全部清零;
    3. 跳转执行C语言main函数。

三、踩坑重点

  1. Makefile自动扫描源码时,目录名拼写、文件名大小写必须严格匹配 (start.S大写S,小写.s不会被匹配)。
  2. 汇编语法:指令和标签之间必须有空格,不能下划线连写,例:bl main,不能写bl_main。
  3. 链接脚本的__bss_start、__bss_end是给汇编使用的符号,缺失会报未定义错误。
  4. main函数标准写法是int main(void),void main(void)会报编译器警告。
  5. 裸机开发顺序:开外设时钟 → 初始化GPIO引脚 → while(1)业务逻辑,时钟不能后开。
  6. 全部打开CCGR时钟只是实验写法;产品中只开启需要的外设时钟降低功耗。

四、整体程序执行流程

开发板上电 → 执行start.S启动汇编 → 设置栈、清零BSS段 → 跳转到main → 开启外设时钟 → 初始化LED/蜂鸣器GPIO → while死循环实现闪烁鸣叫。

相关推荐
comyccccc10 小时前
STM32F407VET6核心板的部分电路绘制学习笔记
笔记·stm32·学习
叼烟扛炮10 小时前
Linux 学习笔记(三十六):并发进阶——读写锁 vs 自旋锁,到底怎么选?
linux·运维·服务器·笔记·学习
是隼人10 小时前
buuctf-pwn [极客大挑战 2019]Not Bad(orw+jmp)题解(学习过程持续更新)
学习·安全·pwn入门·ctf入门
bu_shuo10 小时前
删除Windows资源管理器左侧【此电脑】的Linux企鹅图标
linux·windows
步行cgn10 小时前
Spring MVC 删除功能:用隐藏表单模拟 DELETE 请求的完整解析
linux·运维·服务器
女神下凡10 小时前
芯参谋(77):裸机(无 OS)存储驱动开发指南
arm开发·单片机·嵌入式硬件·设计规范·1024程序员节
宁波阿成11 小时前
CentOS 7 环境下 Tomcat 8.5 升级至 9.0.123 操作总结
linux·centos·tomcat
lazy H11 小时前
【计算机网络】第 12 篇:IPv6 详解——地址格式、地址类型与双栈网络
网络·经验分享·后端·学习·计算机网络·408
(●—●)橘子……11 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode
爱和冰阔落11 小时前
【Linux网络】UDP 服务器怎么写?从 socket、bind 到 recvfrom/sendto,手写完整回显服务器
linux·运维·服务器·网络