编译环境搭建及基础实验

news2024/12/24 11:35:59

1.VS  code安装

Linux 版本安装

把资料盘里的安装包.deb拷贝到Ubuntu中, 使用如下命令安装: 软件图标都在目录/usr/share/applications 中,如图路径
复制到桌面中

Visual Studio Code 插件的安装

我们需要按照的插件有下面几个:
1) C/C++ ,这个肯定是必须的。
2) C/C++ Snippets ,即 C/C++ 重用代码块。
3) C/C++ Advanced Lint, C/C++ 静态检测 。
4) Code Runner ,即代码运行。
5) Include AutoComplete ,即自动头文件包含。
6)、 Rainbow Brackets ,彩虹花括号,有助于阅读代码。
7) One Dark Pro VSCode 的主题。
8) GBKtoUTF8 ,将 GBK 转换为 UTF8
9)、 ARM ,即支持 ARM 汇编语法高亮显示。
10) Chinese(Simplified) ,即中文环境。
11) vscode-icons VSCode 图标插件,主要是资源管理器下各个文件夹的图标。
12) compareit ,比较插件,可以用于比较两个文件的差异。
13) DeviceTree ,设备树语法插件。
14) TabNine ,一款 AI 自动补全插件,强烈推荐,谁用谁知道!

 Visual Studio Code 新建工程

打开 VSCode ,然后在 VSCode 上点击 文件 -> 打开文件夹 ,选刚刚
创建的“1_test”文件夹,打开以后如图
可以看出此时的文件夹“ 1_TEST ”是空的,点击 文件 -> 将工作区另存为 ,打
开工作区命名对话框,输入要保存的工作区路径和工作区名字,如图
的“新建文件”按钮创建 main.c main.h 这两个
文件,创建成功以后 VSCode 如图
此时“实验 1 TEST ”中有 .vscode 文件夹、 main.c main.h ,这三
个文件和文件夹同样会出现在“实验 1 test”文件夹中,如图 main.h 中输入如下所示内容:
 #include <stdio.h>

int add(int a, int b);
main.c 中输入如下所示内容
#include <main.h>

 int add(int a, int b)
{
 return (a + b);
}
 
int main(void)
{
 int value = 0;
value = add(5, 6);
 printf("5 + 6 = %d", value);
 return 0; 
 }
代码编辑完成以后 VSCode 界面如图
保存,打开终端打开窗口

2.I.MX6U-ALPHA/Mini 开发平台介绍 

资源图

正点原子 I.MX6U-Mini 开发板底板板载资源如下:
1 个核心板接口,支持 I.MX6ULL 核心板。
1 个电源指示灯(蓝色)。
1 个状态指示灯(红色)。
1 CAN 接口,采用 TJA1050 芯片。
1 485 接口,采用 SP3485 芯片。
1 ATK 模块接口,支持正点原子蓝牙 /GPS/MPU6050/ 手势识别等模块。
1 个摄像头模块接口。
1 USB 串口,可用于代码调试。
1 USB HOST 接口,用于 USB 主机通信。
1 个有源蜂鸣器 。
1 RS232/RS485 选择接口。
1 TF 卡接口。
1 10M/100M 以太网接口( RJ45
1 5V 电源供应 / 接入口
1 3.3V 电源供应 / 接入口
1 个直流电源输入接口(输入电压范围: DC6~18V
1 个启动模式选择配置接口
1 RTC 后备电池座,并带电池
1 个复位按钮,可用于复位 MPU LCD
1 ON/OFF 按钮。
1 个功能按钮
1 个电源开关,控制整个板的电源
1 SDIO WIFI 接口
I.MX6U-Mini 硬件资源说明
1. SDIO WIFI 接口
这是开发板上的一个 SDIO WIFI(P2) 接口,可以通过此接口连接正点原子出品的 SDIO WIFI
模块。 SDIO WIFI 接口和 TF 卡共用一个 USDHC 接口,因此不能同时和 TF 卡使用。
2. USB 转串口
USB 串口,为 MiniUSB 接口( USB_TTL ), USB 连接 CH340C 芯片, CH340C I.MX6IULL 的串口 1 相连接,从而实现 USB 转串口。设计成 USB 串口,是出于现在电脑上串口正在消失, 尤其是笔记本,几乎清一色的没有串口,所以板载 USB 串口可以方便大家调试。
3. I.MX6ULL 核心板接口
这是开发板底板上面的核心板接口,由 2 2*30 的贴片板对板接线端子( 3710F 公座)组
成,可以用来插正点原子的 I.MX6UL/ULL 核心板等,从而学习 I.MX6UL/6ULL 等芯片,达到
一个开发板,学习多款 SOC 的目的,减少重复投资。
4. RGBLCD 接口
这是转接板自带的 RGB LCD 接口( LCD ),可以连接各种正点原子的 RGB LCD 屏模块,
并且支持触摸屏(电阻 / 电容屏都可以)。采用的是 RGB888 格式,可显示 1677 万色,色彩显示 丰富。
5. USB HOST 接口
这是开发板板载的一个卧式 USB-A 座( USB_HOST ),我们可以通过这个 USB-A 座,连接
U /USB 鼠标 /USB 键盘等其他 USB 从设备,从而实现 USB 主机功能。
6. 后备电池接口
这是 I.MX6ULL 后备区域的供电接口,可以用来给 I.MX6ULL 的后备区域提供能量,在外
部电源断电的时候,维持 SNVS 区域数据的存储,以及 RTC 的运行。
7. 启动 (BOOT) 拨码开关
I.MX6U 支持多种启动方式,比如 SD 卡、 EMMC NAND QSPI FALSH USB 等,要想
从某一种设备启动就必须先设置好启动拨码开关。 I.MX6U-Mini 开发板用了一个 8P 的拨码开
关来选择启动方式,支持从 SD 卡、 EMCM NAND USB 这四种启动方式,这四种启动方式 对应的拨码开关拨动方式已经写在了开发板上。大家在使用的时候根据自己的实际需求设置拨 码开关即可。
8. 摄像头模块接口
这是开发板板载的一个摄像头模块接口( P1 ),摄像头模块(需自备),对准插入到此插槽
中。
9. ATK 模块接口
这是开发板板载的一个正点原子通用模块接口( P7 ),目前可以支持正点原子开发的 GPS
模块、蓝牙模块、 MPU6050 模块、激光测距模块和手势识别模块等,直接插上对应的模块,就 可以进行开发。后续我们将开发更多兼容该接口的其他模块,实现更强大的扩展性能。
10. 蜂鸣器
这是一个有源蜂鸣器,通过高低电平控制蜂鸣器的开关。
11. ON/OFF 按键
这是一个 ON/OFF 按键,连接到 I.MX6ULL OF/OFF 引脚上。
12. 复位按键
这是开发板板载的复位按键( RESET ),用于复位 I.MX6U ,还具有复位液晶的功能,因为
液晶模块的复位引脚和 I.MX6U 的复位引脚是连接在一起的,当按下该键的时候, I.MX6U
液晶一并被复位。
13. 用户按键 KEY
这是开发板板载的 1 个机械式输入按键( KEY0 ),可以做为普通按键输入使用。
14. 蓝色电源指示 LED
这是开发板电源指示 LED 灯,为蓝色,当板子供电正常的时候此灯就会常亮。如果此灯不
亮的话就说明开发板供电有问题 ( 排除 LED 灯本身损坏的情况 )
15. 红色用户 LED
这是开发板板载的 1 LED 灯,为红色,用户可以使用此 LED 灯。在调试代码的时候,
使用 LED 来指示程序状态,这是非常不错的一个辅助调试方法。
16. 引出的 IO
这是开发板 IO 引出端口 P4 ,采用 2*24 排针,总共引出 41 IO 口。
17. 3.3V 电源输入 / 输出
这是开发板板载的一组 3.3V 电源输入输出排针( 2*3 )( JP1 ),用于给外部提供 3.3V 的电
源,也可以用于从外部接 3.3V 的电源给板子供电。
大家在实验的时候可能经常会为没有 3.3V 电源而苦恼不已,有了 I.MX6U-Mini 开发板,
你就可以很方便的拥有一个简单的 3.3V 电源(最大电流不能超过 3000mA )。
18. 5V 电源输入 / 输出
这是开发板板载的一组 5V 电源输入输出排针( 2*3 )( JP2 ),该排针用于给外部提供 5V
电源,也可以用于从外部接 5V 的电源给板子供电。
同样大家在实验的时候可能经常会为没有 5V 电源而苦恼不已,正点原子充分考虑到了大
家需求,有了这组 5V 排针,你就可以很方便的拥有一个简单的 5V 电源( USB 供电的时候,
最大电流不能超过 500mA ,外部供电的时候,最大可达 3000mA )。
19. 电源开关
这是开发板板载的电源开关。该开关用于控制整个开发板的供电。这是一个自锁式开关,
按下以后打开开发板电源,整个板子开始供电,电源指示灯 (PWR) 点亮。再次按下开关弹起,
关闭开发板电源,整个开发板都将断电,电源指示灯( PWR )会随之熄灭。
20. DC6~16V 电源输入
这是开发板板载的一个外部电源输入口( DC_IN ),采用标准的直流电源插座。开发板板载
DC-DC 芯片( JW5060T ),用于给开发板提供高效、稳定的 5V 电源。由于采用了 DC-DC
片,所以开发板的供电范围十分宽,大家可以很方便的找到合适的电源(只要输出范围在
DC6~16V 的基本都可以)来给开发板供电。在耗电比较大的情况下,比如用到 4.3 /7 寸屏 /
口的时候,建议使用外部电源供电,可以提供足够的电流给开发板使用。
21. 以太网接口 (RJ45)
这是开发板板载的以太网接口,连接到 I.MX6U ENET2 网络接口。
22. CAN 接口
这是开发板板载的 CAN 总线接口( CAN ),通过 2 个端口和外部 CAN 总线连接,即 CANH
CANL 。这里提醒大家: CAN 通信的时候,必须 CANH CANH CANL CANL ,否则
可能通信不正常!
23. RS485/ 串口 3 接口
这是 RS485 I.MX6ULL 串口 3 的跳线帽设置接口,如果将 485_R U3_T 485_T
U3_R 连起来,那么 RS485 接口就会使用 I.MX6ULL 的串口 3 。做 RS485 实验的时候一定要将
此接口连起来。
24. RS485 接口
这是开发板板载的 RS485 总线接口( RS485 ),通过 2 个端口和外部 485 设备连接。这里提
醒大家, RS485 通信的时候,必须 A A B B 。否则可能通信不正常
25. JTAG 接口
10P JTAG 接口,可用于连接 JLINK 等调试器。
26. USB OTG 接口
这是开发板板载的一个 MiniUSB 头( USB_OTG ),用于 USB OTG 实验。
27. TF 卡接口
这是开发板板载的一个标准 TF 卡接口( TF_CARD ),该接口在开发板的背面,采用小型的
TF 卡接口, USDHC 方式驱动,有了这个 TF 卡接口,就可以满足海量数据存储的需求。

3:Cortex-A7 MPCore 架构  

Cortex-A7 MPCore 简介
Cortex-A7 MPcore 处理器支持 1~4 核,通常是和 Cortex-A15 组成 big.LITTLE 架构的,
Cortex-A15 作为大核负责高性能运算,比如玩游戏啥的, Cortex-A7 负责普通应用,因为 CortexA7 省电。 Cortex-A7 本身性能也不弱,不要看它叫做 Cortex-A7 但是它可是比 Cortex-A8 性能 要强大,而且更省电。
  
“在 28nm 工艺下, Cortex-A7 可以运行在 1.2~1.6GHz ,并且单核面积不大于 0.45mm 2 (
有浮点单元、 NEON 32KB L1 缓存 ) ,在典型场景下功耗小于 100mW , 这使得它非常适 合对功耗要求严格的移动设备,这意味着 Cortex-A7 在获得与 Cortex-A9 相似性能的情况下, 其功耗更低”。
Cortex-A7 MPCore L1 可选择 8KB 16KB 32KB 64KB L2 Cache 可以不配,也可以
选择 128KB 256KB 512KB 1024KB I.MX6UL 配置了 32KB L1 指令 Cache 32KB
L1 数据 Cache ,以及 128KB L2 Cache Cortex-A7MPCore 使用 ARMv7-A 架构,主要特性如下:
①、 SIMDv2 扩展整形和浮点向量操作。
②、提供了与 ARM VFPv4 体系结构兼容的高性能的单双精度浮点指令,支持全功能的
IEEE754
③、支持大物理扩展 (LPAE) ,最高可以访问 40 位存储地址,也就是最高可以支持 1TB
内存。
④、支持硬件虚拟化。
⑥、支持 Generic Interrupt Controller(GIC)V2.0
⑦、支持 NEON ,可以加速多媒体和信号处理算法。

Cortex-A 寄存器组 

ARM 架构提供了 16 32 位的通用寄存器 (R0~R15) 供软件使用,前 15 (R0~R14) 可以用
作通用的数据存储, R15 是程序计数器 PC ,用来保存将要执行的指令。 ARM 还提供了一个当
前程序状态寄存器 CPSR 和一个备份程序状态寄存器 SPSR SPSR 寄存器就是 CPSR 寄存器的
备份。这 18 个寄存器如图 

通用寄存器 

R0~R15 就是通用寄存器,通用寄存器可以分为以下三类:
①、未备份寄存器,即 R0~R7
②、备份寄存器,即 R8~R14
③、程序计数器 PC ,即 R15
分别来看一下这三类寄存器:
1 、未备份寄存器
未备份寄存器指的是 R0~R7 8 个寄存器,因为在所有的处理器模式下这 8 个寄存器都是
同一个物理寄存器,在不同的模式下,这 8 个寄存器中的数据就会被破坏。所以这 8 个寄存器 并没有被用作特殊用途。
2 、备份寄存器
备份寄存器中的 R8~R12 5 个寄存器有两种物理寄存器,在快速中断模式下 (FIQ) 它们对
应着 Rx_irq(x=8~12) 物理寄存器,其他模式下对应着 Rx(8~12) 物理寄存器。 FIQ 是快速中断模 式,看名字就是知道这个中断模式要求快速执行! FIQ 模式下中断处理程序可以使用 R8~R12 寄存器,因为 FIQ 模式下的 R8~R12 是独立的,因此中断处理程序可以不用执行保存和恢复中断现场的指令,从而加速中断的执行过程。
3 、程序计数器 R15
程序计数器 R15 也叫做 PC R15 保存着当前执行的指令地址值加 8 个字节,这是因为 ARM
的流水线机制导致的。 ARM 处理器 3 级流水线:取指 -> 译码 -> 执行,这三级流水线循环执行,
比如当前正在执行第一条指令的同时也对第二条指令进行译码,第三条指令也同时被取出存放
R15(PC) 中。我们喜欢以当前正在执行的指令作为参考点,也就是以第一条指令为参考点,
那么 R15(PC) 中存放的就是第三条指令,换句话说就是 R15(PC) 总是指向当前正在执行的指令
地址再加上 2 条指令的地址。对于 32 位的 ARM 处理器,每条指令是 4 个字节,所以 :
R15 (PC) = 当前执行的程序位置 + 8 个字节。
 
程序状态寄存器
所有的处理器模式都共用一个 CPSR 物理寄存器,因此 CPSR 可以在任何模式下被访问。
CPSR 是当前程序状态寄存器,该寄存器包含了条件标志位、中断禁止位、当前处理器模式标志
等一些状态位以及一些控制位。所有的处理器模式都共用一个 CPSR 必然会导致冲突,为此,
除了 User Sys 这两个模式以外,其他 7 个模式每个都配备了一个专用的物理状态寄存器,叫
SPSR( 备份程序状态寄存器 ) ,当特定的异常中断发生时, SPSR 寄存器用来保存当前程序状
态寄存器 (CPSR) 的值,当异常退出以后可以用 SPSR 中保存的值来恢复 CPSR

4: 汇编LED灯

I.MX6U IO 命名
可以看出, I.MX6ULL IO 分为两类: SNVS 域的和通用的,这两类 IO
质上都是一样的
的形如“ IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 ”的就是 GPIO 命名,命
名形式就是“ IOMUXC_SW_MUC_CTL_PAD_ XX_XX ”,后面的“ XX_XX ”就是 GPIO 命名,
比如: GPIO1_IO01 UART1_TX_DATA JTAG_MOD 等等。 I.MX6ULL GPIO 并不像 STM32 一样以 PA0~15 这样命名,他是根据某个 IO 所拥有的功能来命名的。比如我们一看到 GPIO1_IO01 就知道这个肯定能做 GPIO ,看到 UART1_TX_DATA 肯定就知道这个 IO 肯定能做 为 UART1 的发送引脚。
I.MX6U IO 复用
以“ IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 ”这个 IO 为例
可以看到有个名为: IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 的寄存器,
寄存器地址为 0X020E005C ,这个寄存器是 32 位的,但是只用到了最低 5 位,其中
bit0~bit3(MUX_MODE) 就是设置 GPIO1_IO00 的复用功能的。 GPIO1_IO00 一共可以复用为 9 种功能 IO ,分别对应 ALT0~ALT8 ,其中 ALT5 就是作为 GPIO1_IO00 GPIO1_IO00 还可以作 为 I2C2_SCL GPT1_CAPTURE1 ANATOP_OTG1_ID 等。这个就是 I.MX6U IO 复用,我 们学习 STM32 的时候 STM32 GPIO 也是可以复用的。
由此可见, I.MX6U GPIO 不止 GPIO1_IO00~GPIO1_IO09 10 个,其它的 IO 都可以复
用为 GPIO 来使用。 I.MX6U GPIO 一共有 5 组: GPIO1 GPIO2 GPIO3 GPIO4 GPIO5 其中 GPIO1 32 IO GPIO2 22 IO GPIO3 29 IO GPIO4 29 IO GPIO5 最少,只有 12 IO ,这样一共有 124 GPIO
MX6U GPIO 配置
IOMUXC_SW_MUX_CTL_PAD_XX_XX IOMUXC_SW_PAD_CTL_PAD_XX_XX 这两
种寄存器都是配置 IO 的,注意是 IO !不是 GPIO GPIO 是一个 IO 众多复用功能中的一种。比 如 GPIO1_IO00 这个 IO 可以复用为: I2C2_SCL GPT1_CAPTURE1 ANATOP_OTG1_ID 、 ENET1_REF_CLK 、 MQS_RIGHT GPIO1_IO00 ENET1_1588_EVENT0_IN 、 SRC_SYSTEM_RESET 和 WDOG3_WDOG_B 9 个功能, GPIO1_IO00 是其中的一种,我们想要把 GPIO1_IO00 用作哪个外设就复用为哪个外设功能即可。如果我们要用 GPIO1_IO00 来 点个灯、作为按键输入啥的就是使用其 GPIO( 通用输入输出 ) 的功能。将其复用为 GPIO 以后还 需要对其 GPIO 的功能进行配置,

硬件原理分析 

可以看出, LED0 接到了 GPIO_3 上, GPIO_3 就是 GPIO1_IO03 ,当 GPIO1_IO03
输出低电平 (0) 的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平 (1) 的时候发
光二极管 LED0 不会导通,因此 LED0 也就不会点亮。所以 LED0 的亮灭取决于 GPIO1_IO03
的输出电平,输出 0 就亮,输出 1 就灭。
实验程序编写
1 、使能 GPIO1 时钟
GPIO1 的时钟由 CCM_CCGR1 bit27 bit26 这两个位控制,将这两个位都设置位 11
可。本教程所有例程已经将 I.MX6U 的所有外设时钟都已经打开了,因此这一步可以不用做。
2 、设置 GPIO1_IO03 的复用功能
找到 GPIO1_IO03 的复用寄存器“ IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 ”的地址为
0X020E0068 ,然后设置此寄存器,将 GPIO1_IO03 这个 IO 复用为 GPIO 功能,也就是 ALT5
3 、配置 GPIO1_IO03
找到 GPIO1_IO03 的配置寄存器“ IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 ”的地址为
0X020E02F4 ,根据实际使用情况,配置此寄存
4 、设置 GPIO
我们已经将 GPIO1_IO03 复用为了 GPIO 功能,所以我们需要配置 GPIO 。找到 GPIO3
应的 GPIO 组寄存器地址
5 、控制 GPIO 的输出电平
经过前面几步, GPIO1_IO03 已经配置好了,只需要向 GPIO1_DR 寄存器的 bit3 写入 0
可控制 GPIO1_IO03 输出低电平,打开 LED ,向 bit3 写入 1 可控制 GPIO1_IO03 输出高电平,
关闭 LED
所有的裸机实验我们都在 Ubuntu 下完成,使用 VSCode 编辑器!

新建一个名为“ 1_leds ”的文件夹,然后在“ 1_leds
这个目录下新建一个名为“ led.s ”的汇编文件和一个名为“ .vscode ”的目录,创建好以后“ 1_leds
文件夹如图
vscode 文件夹里面存放 VSCode 的工程文件, led.s 就是我们新建的汇编文件,
我们稍后会在 led.s 这个文件中编写汇编程序。使用 VSCode 打开 1_leds 这个文件夹,打开以后
如图 led.s 中输入如下代码:
 .global _start /* 全局标号 */
 
/*
 * 描述: _start 函数,程序从此函数开始执行此函数完成时钟使能、
 * GPIO 初始化、最终控制 GPIO 输出低电平来点亮 LED 灯。
 */
 _start:
 /* 例程代码 */
 /* 1、使能所有时钟 */
ldr r0, =0X020C4068 /* 寄存器 CCGR0 */
ldr r1, =0XFFFFFFFF 
str r1, [r0] 

ldr r0, =0X020C406C /* 寄存器 CCGR1 */
str r1, [r0]

ldr r0, =0X020C4070 /* 寄存器 CCGR2 */
str r1, [r0]

ldr r0, =0X020C4074 /* 寄存器 CCGR3 */
str r1, [r0]
 
ldr r0, =0X020C4078 /* 寄存器 CCGR4 */
str r1, [r0]

ldr r0, =0X020C407C /* 寄存器 CCGR5 */
str r1, [r0]
 
ldr r0, =0X020C4080 /* 寄存器 CCGR6 */
str r1, [r0]


/* 2、设置 GPIO1_IO03 复用为 GPIO1_IO03 */
ldr r0, =0X020E0068 /* 将寄存器 SW_MUX_GPIO1_IO03_BASE 加载到 r0 中 */
ldr r1, =0X5 /* 设置寄存器 SW_MUX_GPIO1_IO03_BASE 的 MUX_MODE 为 5 */
str r1,[r0]

/* 3、配置 GPIO1_IO03 的 IO 属性 
*bit 16:0 HYS 关闭xx*bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper 功能
*bit [12]: 1 pull/keeper 使能
*bit [11]: 0 关闭开路输出
*bit [7:6]: 10 速度 100Mhz
*bit [5:3]: 110 R0/6 驱动能力
*bit [0]: 0 低转换率
*/
ldr r0, =0X020E02F4 /*寄存器 SW_PAD_GPIO1_IO03_BASE */
ldr r1, =0X10B0
str r1,[r0]

/* 4、设置 GPIO1_IO03 为输出 */
ldr r0, =0X0209C004 /*寄存器 GPIO1_GDIR */
ldr r1, =0X0000008 
str r1,[r0]
/* 5、打开 LED0
* 设置 GPIO1_IO03 输出低电平
*/
 ldr r0, =0X0209C000 /*寄存器 GPIO1_DR */
 ldr r1, =0 
 str r1,[r0]

 /*
 * 描述: loop 死循环
 */
 loop:
     b loop
我们来详细的分析一下上面的汇编代码,我们以后分析代码都根据行号来分析。
2 行定义了一个全局标号 _start ,代码就是从 _start 这个标号开始顺序往下执行的。
11 行使用 ldr 指令向寄存器 r0 写入 0X020C4068 ,也就是 r0=0X020C4068 ,这个是
CCM_CCGR0 寄存器的地址。
12 行使用 ldr 指令向寄存器 r1 写入 0XFFFFFFFF ,也就是 r1=0XFFFFFFFF 。因为我们
要开启所有的外设时钟,因此 CCM_CCGR0~CCM_CCGR6 所有寄存器的 32 位都要置 1 ,也就
是写入 0XFFFFFFFF
13 行使用 str r1 中的值写入到 r0 所保存的地址中去,也就是给 0X020C4068 这个地
址写入 0XFFFFFFFF ,相当于 CCM_CCGR0=0XFFFFFFFF ,就是打开 CCM_CCGR0 寄存器所
控制的所有外设时钟。
15~31 行都是向 CCM_CCGRX(X=1~6) 寄存器写入 0XFFFFFFFF 。这样我就通过汇编代
码使能了 I.MX6U 的所有外设时钟。
35~37 行是设置 GPIO1_IO03 的复用功能, GPIO1_IO03 的复用寄存器地址为 0X020E0068,
寄 存 器 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 MUX_MODE 设置为 5 就 是 将
GPIO1_IO03 设置为 GPIO
49~51 行 是 设 置 GPIO1_IO03 的 配 置 寄 存 器 , 也 就 是 寄 存 器
IOMUX_SW_PAD_CTL_PAD_GPIO1_IO03 的值,此寄存器地址为 0X020E02F4 ,代码里面已经
给出了这个寄存器详细的位设置。
54~63 行是设置 GPIO 功能,经过上面几步操作, GPIO1_IO03 这个 IO 已经被配置为了
GPIO 功能,所以还需要设置跟 GPIO 有关的寄存器。第 54~56 行是设置 GPIO1->GDIR 寄存器,
GPIO1_IO03 设置为输出模式,也就是寄存器的 GPIO1_GDIR bit3 1
61~63 行设置 GPIO1->DR 寄存器,也就是设置 GPIO1_IO03 的输出,我们要点亮开发
板上的 LED0 ,那么 GPIO1_IO03 就必须输出低电平,所以这里设置 GPIO1_DR 寄存器为 0
68~69 行是死循环,通过 b 指令, CPU 重复不断的跳到 loop 函数执行,进入一个死循
环。

 编译代码

1将.c.s文件变为,o

2将所有的.o文件连接为elf格式的可执行文件

3将elf文件转为bin文件

4将elf文件转为汇编,反汇编

链接:

连接就是将所有.o文件链接在一起,并且链接到指定的地方。本实验链接的时候要指定链接起始地址。链接起始地址就是代码运行的起始地址,或者说保存代码的起始地址。

 1arm-linux-gnueabihf-gcc 编译文件

妈的前面注意千万不要敲错了。不然一堆牛马错误

     我们是要编译出在 ARM 开发板上运行的可执行文件,所以要使用我们在前面 安装的
交叉编译器 arm-linux-gnueabihf-gcc 来编译。因为本试验就一个 led.s 源文件,所以编译比较简
单。先将 led.s 编译为对应的.o 文件,在终端中输入如下命令:
上述命令就是将 led.s 编译为 led.o ,其中“ -g ”选项是产生调试信息, GDB 能够使用这些
调试信息进行代码调试。 -c ”选项是编译源文件,但是不链接。 -o ”选项是指定编译产生的文
件名字,这里我们指定 led.s 编译完成以后的文件名字为 led.o。执行上述命令以后就会编译生 成一个 led.o 文件
但是led.o 文件并不是我们可以下载到开发板中运行的文件,一个工程中所有的 C
文件和汇编文件都会编译生成一个对应的 .o 文件,我们需要将这 .o 文件链接起来组合成可执行文件

 2arm-linux-gnueabihf-ld 链接文件

arm-linux-gnueabihf-ld 用来将众多的 .o 文件链接到一个指定的链接位置。我们在学习
SMT32 的时候基本就没有听过“链接”这个词,我们一般用 MDK 编写好代码,然后点击“编
译”, MDK 或者 IAR 就会自动帮我们编译好整个工程,最后再点击“下载”就可以将代码下载
到开发板中。这是因为链接这个操作 MDK 或者 IAR 已经帮你做好了,后面我就以 MDK 为例 给大家讲解。大家可以打开一个 STM32 的工程,然后编译一下,肯定能找到很多.o 文件,如图
左侧的 IROM1 我们都知道是设置 STM32 芯片的 ROM 起始地址和大小的,右
边的 IRAM1 是设置 STM32 芯片的 RAM 起始地址和大小的。其中 0X08000000 就是 STM32 内 部 ROM 的起始地址,编译出来的指令肯定是要从 0X08000000 这个地址开始存放的。对于 STM32 来说 0X08000000 就是它的链接地址,这些.o 文件就是 这个链接地址开始 依次存放,最终生成一个可以下载的 hex 或者 bin 文件,我们可以打开.map 文件查看一下这些文件的链接地址,在 MDK 下打开一个工程的.map 文件方法
接地址。这里我们要区分“存储地址”和“运行地址”这两个概念,“存储地址”就是可执
行文件存储在哪里,可执行文件的存储地址可以随意选择。“运行地址”就是代码运行的时候
所处的地址,这个我们在链接的时候就已经确定好了,代码要运行,那就必须处于运行地址
处,否则代码肯定运行出错。
确定了链接地址以后就可以使用 arm-linux-gnueabihf-ld 来将前面编译出来的 led.o 文件链
接到 0X87800000 这个地址,使用如下命令:
上述命令中 -Ttext 就是指定链接地址,“ -o ”选项指定链接生成的 elf 文件名,这里我们命名
led.elf 。上述命令执行完以后就会在工程目录下多一个 led.elf 文件,如图
led.elf 文件也不是我们最终烧写到 SD 卡中的可执行文件,我们要烧写的 .bin 文件,因此还
需要将 led.elf 文件转换为 .bin 文件,这里我们就需要用到 arm-linux-gnueabihf-objcopy 这个工具

3arm-linux-gnueabihf-objcopy 格式转换  

arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为

led.bin 文件,命令如下:

上述命令中,“ -O ”选项指定以什么格式输出,后面的“ binary ”表示以二进制格式输出,
选项“ -S ”表示不要复制源文件中的重定位信息和符号信息,“ -g ”表示不复制源文件中的调试
信息。上述命令执行完成以后,工程目录如图

4arm-linux-gnueabihf-objdump 反汇编 

大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,
因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:
上述代码中的“ -D ”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一
个名为 led.dis 文件,如图

总结一下我们为了编译 ARM 开发板上运行的 led.o 这个文件使用了如下命令:  

如果我们修改了 led.s 文件,那么就需要在重复一次上面的这些命令,太麻烦了,这个时候
我们就可以使用Makefile 文件了。

5.创建 Makefile 文件

使用“ touch ”命令在工程根目录下创建一个名为“Makefile”的文件 创建好 Makefile 以后我们就只需要执行一次“make”命令即可完成编译,过程如图 如果我们要清理工程的话执行“make clean”即可
后面。/imxdownload led.bin /dev/sdf

5.代码烧写 

我们在调试裸机和 Uboot 的时候是将代码下载到 SD 中,因为方便嘛,当调试完成
以后量产的时候要将裸机或者 Uboot 烧写到 SPI NOR Flash EMMC NAND 等这些存储介质
中的。那么,如何将我们前面编译出来的 led.bin 烧写到 SD 卡中呢?肯定有人会认为直接复制
led.bin SD 卡中不就行了,错!编译出来的可执行文件是怎么存放到 SD 中的,存放的位置是
什么?这个 NXP 是有详细规定的!我们必须按照 NXP 的规定来将代码烧写到 SD 卡中,否则
代码是绝对运行不起来的。
imxdownload”路径为: 开发板光盘 ->5 、开发工具 ->2、Ubuntu 下裸机烧写软件 ->imxdownload imxdownlaod 只能在 Ubuntu 下使用,使用步骤如下:
1 、将 imxdownload 拷贝到工程根目录下
我们要将 imxdownload 拷贝到工程根目录下,也就是和 led.bin处于同一个文件夹下,要不然烧写会失败的,拷贝完成以后如图
2 、给予 imxdownload 可执行权限
我们直接将软件 imxdownload Windows 下复制到 Ubuntu 中以后, imxdownload默认是没有可执行权限的。我们需要给予 imxdownload 可执行权限,使用命令“chmod”,命令如下: 当给予 imxdownload可执行权限以后其名字变成了绿色的,如果没有可执行权限的话其名字颜色是白色的。所以在 Ubuntu中我们可以初步的从文件名字的颜色判断其是否具有可执行权限。
3 、确定要烧写的 SD 卡。
准备一张新的 SD(TF) 卡,确保 SD卡里面没有数据,因为我们在烧写代码的时候可能会格式化 SD 卡!!!
Ubuntu 下所有的设备文件都在目录“ /dev ”里面,所以插上 SD 卡以后也会出现在“ /dev”里面,其中存储设备都是以“ /dev/sd ”开头的。我们要先看一下不插 SD卡的时候电脑都有哪些存储设备,以防插入SD卡以后分不清谁是谁。输入如下所示命令:
4 、向 SD 卡烧写 bin 文件
使用 imxdownload SD 卡烧写led.bin文件,命令格式如下:
其中 .bin 就是要烧写的 .bin 文件, SD Card 就是你要烧写的 SD 卡,比如我的电脑使用如下
命令烧写 led.bin 到/dev/sdd中:
烧写的最后一行会显示烧写大小、用时和速度,比如 led.bin 烧写到 SD
中的大小是 3.2KB ,用时 0.0160821s ,烧写速度是 201KB/s。注意这个烧写速度,如果这个烧写速度在几百KB/s以下那么就是正常烧写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1444160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[C#]winform制作圆形进度条好用的圆环圆形进度条控件和使用方法

【创建圆形进度条流程】 在C# WinForms应用程序中创建一个圆形进度条&#xff08;通常用作仪表盘的显示&#xff09;可以通过多种方式实现。下面是一个简单的例子&#xff0c;演示如何使用System.Drawing命名空间中的图形绘制功能来绘制一个基本的圆形进度条。 首先&#xff0…

随机MM引流源码PHP开源版

引流源码最新随机MM开源版PHP源码&#xff0c;非常简洁好看的单页全解代码没任何加密 直接上传即可用无需数据库支持主机空间

linux应用 进程间通信之信号量(System V)

1、定义 System V 信号量是一种用于进程间同步和互斥的机制&#xff0c;它是 System V IPC&#xff08;Inter-Process Communication&#xff0c;进程间通信&#xff09;机制的一部分。信号量通常用于控制对共享资源的访问&#xff0c;以避免竞争条件&#xff08;race conditi…

【EAI 017】Interactive Language: Talking to Robots in Real Time

论文标题&#xff1a;Interactive Language: Talking to Robots in Real Time 论文作者&#xff1a;Corey Lynch, Ayzaan Wahid, Jonathan Tompson Tianli Ding, James Betker, Robert Baruch, Travis Armstrong, Pete Florence 作者单位&#xff1a;Robotics at Google 论文原…

口腔助手|口腔挂号预约小程序|基于微信小程序的口腔门诊预约系统的设计与实现(源码+数据库+文档)

口腔小程序目录 目录 基于微信小程序的口腔门诊预约系统的设计与实现 一、前言 二、系统功能设计 三、系统实现 1、小程序前台界面实现 2、后台管理员模块实现 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、最新…

【软件设计师】——面向对象设计原则

为了提高软件的可维护性、可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;在面向对象编程的过程中我们需要遵守以下六条原则。 开闭原则 定义&#xff1a; 编写的代码需要对 扩展开放 对 修改关闭 &#xff0c;实现 热插拔 的效果。 例&#xff1a;在编写不同皮…

【Web】小白友好的Java内存马基础学习笔记

目录 简介 文件马与内存马的比较 文件马原理 内存马原理 内存马使用场景 内存马分类 内存马注入方式 这篇文章主要是概念性的&#xff0c;具体技术细节不做探究&#xff0c;重点在祛魅。 简介 内存马&#xff08;Memory Shellcode&#xff09;是一种恶意攻击技术&…

【Linux】学习-动静态库

动静态库 头文件与库的区别 头文件一般而言&#xff0c;是声明和宏定义。头文件是在预处理阶段使用的 库文件是已经编译好的二进制代码。是一种目标文件&#xff0c;库文件是在链接阶段使用的 对于头文件和库我们可以这样理解&#xff0c;就是头文件提供的是一个函数的声明&…

Hive正则表达式

Hive版本&#xff1a;hive-3.1.2 一、Hive的正则表达式概述 正则表达式是一种用于匹配和操作文本的强大工具&#xff0c;它是由一系列字符和特殊字符组成的模式&#xff0c;用于描述要匹配的文本模式。 Hive的正则表达式灵活使用解决HQL开发过程中的很多问题&#xff0c;本篇文…

基于SpringBoot+Vue的服装销售商城系统

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与环…

无人机系统组装与调试,多旋翼无人机组装与调试技术详解,无人机飞控系统原理

多旋翼无人机飞控系统的组装 在开始组装前&#xff0c;确保您已准备好所有必要的工具和材料。这包括螺丝刀、电烙铁、焊台、杜邦线、飞控板、GPS模块、电机、桨叶等。 飞控安装 安全开关安装&#xff0c;将安全开关固定在机架上。将安全开关的线插到飞控SWITCH插口上。 电调…

如何从 iPhone 恢复已删除的视频:简单有效方法

无论您是在尝试释放空间时不小心删除了 iPhone 上的视频&#xff0c;还是在出厂时清空了手机&#xff0c;现在所有数据都消失了&#xff0c;都不要放弃。有一些方法可以恢复这些视频。 在本文中&#xff0c;我们将向您展示六种最有效的数据恢复方法&#xff0c;可以帮助您从 i…

直播app开发,技术驱动的实时互动新纪元

随着互联网技术的快速发展&#xff0c;直播已成为我们日常生活的重要组成部分。从娱乐、教育到商业活动&#xff0c;直播的广泛应用正在改变着我们的生活和工作方式。在这一变革中&#xff0c;直播开发扮演着至关重要的角色。本文将探讨直播开发的核心理念、技术挑战以及未来的…

离散数学——图论(笔记及思维导图)

离散数学——图论&#xff08;笔记及思维导图&#xff09; 目录 大纲 内容 参考 大纲 内容 参考 笔记来自【电子科大】离散数学 王丽杰

PacketSpy:一款功能强大的网络数据包嗅探、捕捉和分析工具

关于PacketSpy PacketSpy是一款功能强大的网络数据包嗅探工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以轻松捕捉并分析目标网络系统中的流量。PacketSpy提供了跟网络流量安全相关的全面功能&#xff0c;可以用于检查HTTP请求与响应、查看原始Payload数据、以…

web前后端小坑记录

游戏服务器过年这段时间忙完了&#xff0c;好久没看web了&#xff0c;重温一下。发现竟然没有文章记录这些修BUG的过程&#xff0c;记录一下。 目录 如何处理F5刷新&#xff1f; 如何处理F5刷新&#xff1f; 后端应该发现路由不存在&#xff0c;直接返回打包好的index.html就…

腾讯云4核8G服务器够用吗?容纳多少人同时访问?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

steam搬砖项目免费分享,学会即可上手

亲身体验过很多互联网微创业项目&#xff0c;steam搬砖项目我愿称之为最强副业&#xff01;如果你每天有1-2小时的空闲时间&#xff0c;那我非常建议你试试这个。两个平台之间搬运下装备就能进账&#xff0c;努力点月入几千还是完全没问题的。 steam搬砖怎么赚钱&#xff1f;做…

【Spring框架】Spring事务同步

目录 一、什么是Spring事务同步 二、 事务同步管理器 2.1 TransactionSynchronizationManager事务同步管理器 2.1.1 资源同步 2.1.2 事务同步 2.1.3 总结 三、事务同步管理器保障事务的原理 四、spring事务为何使用TransactionSynchronizationManager spring源码实现 …

哪家洗地机比较好用?性能好的洗地机推荐

在众多功能中&#xff0c;我坚信洗地机的核心依旧是卓越的清洁能力以及易于维护的便捷性&#xff0c;其他的附加功能可以看作是锦上添花&#xff0c;那么如何找到性能好的洗地机呢&#xff1f;我们一起看看哪些洗地机既能确保卫生效果还能使用便利。 洗地机工作原理&#xff1…