当前位置: 首页 > news >正文

硬件开发2-ARM裸机开发2-IMX6ULL

一、利用main函数调用外设接口 - led

1、配置好启动文件:start.S;

  1. 其内部包含(按顺序记录):
    1. 配置异常向量表,并封装跳转异常向量表情况的函数
    2. 模式切换与栈指针初始化
      1. 切换到IRQ模式并设置其栈指针
      2. 切回SYS/USER模式并设置其栈指针
    3. 调b main

2、main函数

  1. 封装寄存器地址封装、灯初始化、灯亮、灯暗、灯延时的函数
  2. 在main函数内部调用函数接口                       
关键字:volatile:

        防止被修饰的变量会被 “意外修改”,禁止编译器对该变量进行优化

3、编译:

//定义交叉编译工具链的前缀和工具

COPLITE=arm-linux-gnueabihf-

CC=$(COPLITE)gcc

LD=$(COPLITE)ld

OBJCOPY=$(COPLITE)objcopy

OBJDUMP=$(COPLITE)objdump

//列出目标与依赖文件target

OBJS=start.o main.o

TARGET=led

//.S(汇编)和.c(C语言)文件编译为.o目标文件(后者源文件,前者目标文件)
%.o : %.S

    $(CC) -c -g $^ -o $@        //$^表示:所有依赖文件(%.S %.c)   $@表示:目标文件(%.o)

%.o : %.c

    $(CC) -c -g $^ -o $@

//链接->二进制文本->反汇编
$(TARGET).bin:$(OBJS)

    $(LD) -Ttext 0x87800000 $(OBJS) -o $(TARGET).elf

    $(OBJCOPY) -O binary -S -g $(TARGET).elf $(TARGET).bin

    $(OBJDUMP) -D $(TARGET).elf > $(TARGET).dis


clean:

    rm $(OBJS) $(TARGET).elf $(TARGET).bin $(TARGET).dis -f

load:

    ./imxdownload $(TARGET).bin /dev/sdb

4、小点:

  • sp寄存器
    • 概念:
      • ARM架构中,SP寄存器(Stack Pointer,栈指针寄存器):是用于管理函数调用、中断处理等场景中栈操作的核心寄存器;
      • 有效RAM范围内(如0x80000000~0x90000000)
    • 功能:   
      • SP寄存器指向当前栈顶的内存地址,能够动态进行处理压栈和弹栈
      • 属于满减栈,保存函数调用的返回地址、局部变量、中断现场信息等

5、代码实现:

start.S

main.c

makefile

6、优化1.0 - 配置时钟

改动:在main.c中配置了时钟寄存器

7、优化2.0 - 添加硬件寄存器定义和驱动库文件

改动:在main.c中,添加硬件寄存器定义和驱动库文件,

(1)GPIO方向寄存器

  • ARM架构中,GPIO方向寄存器(GDIR)的每个bit控制一个引脚(bit3对应GPIO1_IO03)。
  • |= (1 << 3) 将bit3置1,配置为输出模式,符合硬件要求的原子性位操作(避免影响其他引脚)

(2)GPIO1->DR 位操作注释:

开漏/推挽输出:
DR寄存器bit3直接驱动引脚电平:

  • DR &= ~(1 << 3) 输出低电平(LED点亮,假设共阳极接法)

  • DR |= (1 << 3) 输出高电平(LED熄灭)

8、优化3.0 将功能性函数分离

改动:将有关led的函数封装,放入 led.c led.h

9、makefile

    二、唤醒蜂鸣器

    操作类似:进行优化,进行了BSP工程管理

    1、BSP工程管理

        1.project :存放必要程序


    2.imx6ull :存放NXP提供的i.mx6ull头文件

    3.bsp :存放硬件外设相关功能模块

    4.Makefile: 需要遍目录

    如下图所示

    2、链接脚本(.lds)

    (1)概要

            使用BSP进行工程管理时,makefile就要升级了,同时也需要写一个链接脚本,保证插电启动时,首先运行的是start.S。

            明确链接器:代码段、数据段、BSS 段的存放地址和顺序(为 I.MX6ULL 启动做准备)

            start.S(启动代码)放在最前面,且需初始化BSS段(未初始化全局变量清 0)

    (2)规则
    1)内存布局定义核心结构

    链接脚本的核心是SECTIONS命令块,用于定义程序各段在内存中的布局:

    SECTIONS {/* 各段定义 */
    }
    
    2)关键要素分类说明
    - 定位计数器与起始地址
    • . = 0x87800000;
      • 使用定位计数器(.)设置起始链接地址
      • 示例中设置为I.MX6ULL的SD启动地址
      • 后续段将从这个地址开始依次排列
    - 代码段(.text)处理
    .text : {obj/start.o      /* 必须首先放置启动文件 */*(.text)        /* 收集所有目标文件的.text段 */
    }
    
    • 确保启动代码(start.o)位于最前
    • 通配符*(.text)收集所有.text段
    - 数据段组织
    段类型语法示例作用对齐要求
    只读数据段.rodata ALIGN(4) : {*(.rodata*)}存放常量数据(如字符串)4字节对齐
    已初始化数据.data ALIGN(4) : {*(.data)}存放已初始化全局/静态变量4字节对齐
    未初始化数据.bss ALIGN(4) : {*(.bss)}存放未初始化全局/静态变量4字节对齐
    - BSS段特殊处理
    __bss_start = .;     /* 定义BSS起始符号 */
    .bss ALIGN(4) : {*(.bss)          /* 标准BSS段 */*(COMMON)        /* 公共块数据 */
    }
    __bss_end = .;       /* 定义BSS结束符号 */
    
    • 需要显式定义起止符号供启动代码使用
    • 必须包含COMMON段
    • 通常需要4字节对齐
    - 对齐控制
    • ALIGN(4)指令确保段起始地址4字节对齐
    • 对齐操作对32位处理器至关重要
    • 可防止内存访问越界和性能下降
    3)完整要素流程图
    SECTIONS
    │
    ├─ 定位计数器设置(.=0x87800000)
    │
    ├─ .text段
    │   ├─ 强制包含start.o
    │   └─ 收集所有.text段
    │
    ├─ .rodata段(ALIGN4)
    │
    ├─ .data段(ALIGN4)
    │
    ├─ BSS段处理
    │   ├─ __bss_start标记
    │   ├─ .bss段(ALIGN4)
    │   │   ├─ 标准.bss
    │   │   └─ COMMON块
    │   └─ __bss_end标记
    4)代码示例解释

    3、代码实现

    start.S

    imx6ull.lds

    beep.c  beep.h

    main.c

    makefile


    文章转载自:

    http://6BwXkUbV.zLxkp.cn
    http://xXNqgjCP.zLxkp.cn
    http://jk8SbaXQ.zLxkp.cn
    http://jIHtXBiX.zLxkp.cn
    http://feNwFcRX.zLxkp.cn
    http://OMQBHhUh.zLxkp.cn
    http://RZOs21MG.zLxkp.cn
    http://f3doUIP8.zLxkp.cn
    http://gmwZDTUW.zLxkp.cn
    http://BmYaLv4I.zLxkp.cn
    http://qZ3jrKnL.zLxkp.cn
    http://UMcg9mIu.zLxkp.cn
    http://MpqY9w01.zLxkp.cn
    http://FQ23ObfD.zLxkp.cn
    http://0U8SLvRh.zLxkp.cn
    http://e7sgPWDu.zLxkp.cn
    http://xaNxv1GU.zLxkp.cn
    http://g2i8H2Me.zLxkp.cn
    http://qX9U0zMn.zLxkp.cn
    http://T6UCO7C4.zLxkp.cn
    http://t77gs8Vq.zLxkp.cn
    http://WpPqHiUs.zLxkp.cn
    http://qAK1dUtV.zLxkp.cn
    http://EpMDSBZK.zLxkp.cn
    http://9zDUHxXB.zLxkp.cn
    http://fLCnc19o.zLxkp.cn
    http://PUU9POyQ.zLxkp.cn
    http://UJHqMujI.zLxkp.cn
    http://ZuP1p4xR.zLxkp.cn
    http://Bl497xIf.zLxkp.cn
    http://www.dtcms.com/a/378608.html

    相关文章:

  • 电商网站被DDoS攻击了怎么办?
  • Java NIO的底层原理
  • QT 常用控件(概述、QWidget核心属性、按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
  • MATLAB2-结构化编程和自定义函数-台大郭彦甫视频
  • 鸿蒙的编程软件的介绍
  • 鸿蒙审核问题——Scroll中嵌套了List/Grid时滑动问题
  • REDPlayer 鸿蒙原生视频播放库组件介绍与使用指南
  • HarmonyOS 应用开发深度解析:ArkUI 声明式 UI 与现代化状态管理最佳实践
  • redis 入门-1
  • Json-rpc通信项目(基于C++ Jsoncpp muduo库)
  • TODO的面试(dw三面、sqb二面、ks二面)
  • Vibe Coding实战项目:用Qwen3-Coder做了个AI跳舞视频生成器
  • Vue 封装Input组件 双向通信
  • 【混合开发】进阶到【大前端++】
  • ZooKeeper Java客户端与分布式应用实战
  • 【复习】计网每日一题---传输层无连接不可靠服务
  • 2025年秋招答疑:AI面试如何破解在线作弊难题?
  • KafKa01:在Windows系统上安装Kafka
  • 【Big Data】Amazon S3 专为从任何位置检索任意数量的数据而构建的对象存储
  • C++:模版进阶
  • 【Canvas与旗帜】圆角红面白边蓝底梅花五星旗
  • 不同局域网远程桌面连接:设置让外网电脑直接windows自带远程桌面访问内网计算机,简单3步实现通用详细教程
  • set 认识及使用
  • 如何打造“高效、安全、精准、可持续”的智能化实验室?
  • 究竟什么时候用shared_ptr,什么时候用unique_ptr?
  • 前端抽象化,打破框架枷锁:react现代化项目中的思想体现
  • 基于开源AI智能名片、链动2+1模式与S2B2C商城小程序的流量运营与个人IP构建研究
  • gstreamer:创建组件、管道和总线,实现简单的播放器(Makefile,代码测试通过)
  • Kibana 双栈网络(Dual-Stack)支持能力评估
  • go 日志的分装和使用 Zap + lumberjack