ARM-点亮第一颗LED

参考文档:1. imx6ull裸机(v1.2).pdf

从内核切换到外设的学习

1.开发板介绍

(1)IMX6ULL-Mini开发板是由正点原子提供的, 搭载NXP生产i.MX6ULL的SOC, 主打高性能、低功耗与紧凑体积

(2)整个开发板由核心板与底板组成,核心板通过双列直插方式与底板连接

(3) 核心板 六层板

CPU:NXP i.MX 6ULL Cortex-A7单核处理器,主频 528MHz(工业级) 或 800MHz(商业级)467, BGA封装

内存:512MB DDR3L RAM,支持高速数据存取。

存储:8GB eMMC,支持多种启动模式(SD卡、NAND、eMMC)

屏幕:4.3寸屏 800*480分辨率

(4)底板(看了LED模块)

红色led灯提供用户可控的的LED灯

蓝色led灯是电源指示灯

510欧姆限流电阻作用防止电流过大保护灯珠。

Cortex-A7 核心设计:ARM

i.MX6ULL SOC: NXP

IMX6ULL-Mini 开发板: 正点原子

2.开发工具下载

(1)安装Visual Studio Code

汇编高亮插件:Arm Assembly

(2)创建工程文件夹 D:\IMX6ULL\led_asm

(3)创建启动代码 start.S(注意大写S后缀,会进行预处理,后期用到一些宏)

3.编写启动代码

(1).global _start

rom: 0x8000 0000 size:512M

(2) cps指令:

CPS<effect> <iflags>{, #<mode>}

CPS #<mode>

示例: cpsid i (i f a)

cps #0x12

ldr sp, =0x820000000

cps #0x1F

ldr sp, =0x840000000

cpsie i

3.点亮LED灯

(1)查阅手册

参考文档:1. IMX6ULL_MINI_V2.2(Mini底板原理图).pdf

  1. IMX6ULL参考手册.pdf

(1)初始化

(1)复用功能配置

Chapter 32:IOMUX Controller (IOMUXC)

IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03: 低四位(0101)

(2)电气特性

Chapter 32:IOMUX Controller (IOMUXC)

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03

(3)GPIO方向寄存器

Chapter 28:General Purpose Input/Output (GPIO)

GPIOx_GDIR

(2)运行时开关灯

(1)GPIO数据寄存器

Chapter 28:General Purpose Input/Output (GPIO)

GPIOx_DR

(2)修改外设寄存器

LDR<c> <Rt>, \{, #+/-\}

LDR<c> <Rt>, \, #+/-<imm12>

LDR<c> <Rt>, \, #+/-\!

LDR<c> <Rt>, <label>

LDR<c> <Rt>, PC, #-0

LDR<c> <Rt>, \,+/-\{, \}{!}

LDR<c> <Rt>, \,+/-<Rm>{, <shift>}

STR<c> <Rt>, \{, #+/-\}

STR<c> <Rt>, \, #+/-<imm12>

STR<c> <Rt>, \, #+/-\!

STR<c> <Rt>, \,+/-\{, \}{!}

STR<c> <Rt>, \,+/-<Rm>{, <shift>}

STRB<c> <Rt>, \{, #+/-\}

STRB<c> <Rt>, \, #+/-<imm12>

STRB<c> <Rt>, \, #+/-\!

ldr r0, =0x020C4068

ldr r1, =0xFFFFFFFF

str r1, r0

(3)编译器安装

(1)拷贝 gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 到/usr/local/arm

(2)解压 sudo tar -xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

(3)删除 sudo rm gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz

(4)配置 回家目录, 修改环境变量配置文件 vi .bashrc

export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/

(5)重启虚拟机:reboot

(6)检查编译器版本:arm-linux-gnueabihf-gcc -v

(4)FileZilla Client工具:它是一个Windows系统下免费的ftp工具。(可选)

a.手动配置Ubuntu的ftp服务。

(1) 安装ftp服务: sudo apt-get install vsftpd

(2) 修改配置: VI 命令打开/etc/vsftpd.conf

找到local_enable=YES write_enable=YES 确保这两行之前没有 #,(line28/line31)

(3) 重启ftp服务, sudo /etc/init.d/vsftpd restart

(4) 查看ftp服务器工作状态: sudo /etc/init.d/vsftpd status; 绿灯正常

b.win下安装FileZilla Client

(1)IMX6ULL资料/软件/FileZilla_3.39.0_win64-setup_bundled.exe s双击。

(2)记得可以选择创建桌面快捷方式:Desktop icon

(5)上传代码(可选)

(1)文件->站点管理器->新站点->

主机(H):ens33IP:192.168.71.134

用户(U):linux

密码(W):1

点击连接

(2)右侧win本地站点,左侧Ubuntu远程站点,选择对应文件夹

右键点击上传文件夹->上传

(6)编译代码

(1)使用arm-linux-gnueabihf-gcc只汇编不链接

arm-linux-gnueabihf-gcc -c start.S -o start.o -g

(2)使用arm-linux-gnueabihf-ld链接代码到特定地址(得到可执行,可连接程序linux executable linkable file)

arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf

(3)使用arm-linux-gnueabihf-objcopy 格式转换

arm-linux-gnueabihf-objcopy -O binary -S(去符号信息) -g(去调试信息) start.elf start.bin

(4)使用arm-linux-gnueabihf-objdump 反汇编(此处只是为了阅读代码,非必要步骤)

arm-linux-gnueabihf-objdump -D start.elf > start.dis

(7)led.bin拷贝到TFcard

(1)连接SD卡到Ubuntu

(1)可移动设备

(2)右下角图标

(2)查看/dev

ls /dev/sdb

(3)拷贝下载工具imxdownload到Ubuntu工程目录下

修改权限:chmod +777 imxdownload

(4)烧写程序到SD卡

./imxdownload start.bin /dev/sdb

注意烧写速率,如果上M的速度是不成功的,必须拔掉USB读卡器,重启Ubuntu

(8)测试

(1)启动方式选择SD卡

原理图:BOOt模块(USB启动 SD卡启动 板载EMMC启动 nandflash启动 ) -> 通过拨码卡关选择

(2)插入SD卡

查看开发板图找到 TFcard 插入SD卡

(3)开发板上电

保证开关弹起的状态下,插上电源适配器,按下旁边蓝色开关,查看蓝色电源灯

(4)观察红色Led灯

练习:修改汇编代码,添加延时函数完成led灯闪烁

(9)Makefile简化编译过程

(1)Makefile的三要素:目标:start.bin 依赖:start.S 规则:如何产生目标

start.bin : start.S

arm-linux-gnueabihf-gcc -c start.S -o start.o -g

arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf

arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin

arm-linux-gnueabihf-objdump -D start.elf > start.dis

(2)伪目标 clean 不加依赖

rm start.o start.elf start.bin start.dis -f

(3)伪目标 load

./imxdownload start.bin /dev/sdb

(4)优化(存放变量)

COMPLITER = arm-linux-gnueabihf-

CC = $(COMPLITER)gcc

LD = $(COMPLITER)ld

OBJCOPY = $(COMPLITER)objcopy

OBJDUMP = $(COMPLITER)objdump

start.bin : start.S

$(CC) -c start.S -o start.o -g

$(LD) -Ttext 0x87800000 start.o -o start.elf

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

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

clean:

rm start.o start.elf start.bin start.dis -f

load:

./imxdownload start.bin /dev/sdb

.s=====================================================================

.global _start

_start:

ldr pc, =_reset_handler

ldr pc, =_undef_handler

ldr pc, =_software_handler

ldr pc, =_prefect_handler

ldr pc, =_data_handler

nop

ldr pc, =_irq_handler

ldr pc, =_fiq_handler

_undef_handler:

b _undef_handler

_software_handler:

b _software_handler

_prefect_handler:

b _prefect_handler

_data_handler:

b _data_handler

_irq_handler:

b _irq_handler

_fiq_handler:

b _fiq_handler

_reset_handler:

cpsid i //关掉IRQ的中断开关

cpsid f //关掉FIQ的中断开关

cps #0x12 //切换到10010

ldr sp, =0x82000000 //定义栈顶指针

cps #0x1F //切换到11111

ldr sp, =0x84000000 //定义栈顶指针

cpsie i

b main

finish:

b finish

main====================================================

//复用寄存器

#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 (*((volatile unsigned int *)(0x020E0068)))

//电气寄存器

#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 (*((volatile unsigned int *)(0x020E02F4)))

//方向寄存器

#define GPIO1_GDIR (*((volatile unsigned int *)(0x0209C004)))

//输出寄存器

#define GPIO1_DR (*((volatile unsigned int *)(0x0209C000)))

void led_init(void)

{

//初始化复用

IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x5;

//初始化电气

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0;

//初始化方向

GPIO1_GDIR |= (1 << 3);

return;

}

void led_on(void)

{

GPIO1_DR &= ~(1 << 3);

}

void led_delay(unsigned int t)

{

while(t--);

}

void led_off(void)

{

GPIO1_DR |= (1 << 3);

}

void main(void)

{

led_init();

while(1)

{

led_on();

led_delay(0x3FFFF);

led_off();

led_delay(0x3FFFF);

}

}

======================================================================

  1. 在LED实验中,在对Soc引脚配置时都做了哪些工作?

首先对LED灯关联的引脚CPIO1_03进行初始化

初始化内容包括

1,将地址为0x020E 0068的SW---MUX---CTL(MUX控制寄存器)的后四位修改为0101

  1. 将地址为0x020E 02F4的SW---PAD---CTL(电气控制寄存器)后16位修改为10B0

3更改GPIO1_IO03的方向为输入,GP1O1_GDIR寄存器

地址为0x0209 C004,修改3位为1

开灯关灯,修改GPIO1_IO03的电平,寄存器GPIO1_DR地址为0x0209 C000 的第3位0低电平开,1高电平关

  1. 什么是编译器、连接器、格式转换器和反汇编器?

编译器

属于编译流程的编译阶段(核心阶段)。它实现将预处理后的高级语言源代码(如 C/C++)翻译成特定处理器架构的汇编代码.S文件。其作用是进行语法分析、语义检查、代码优化,并生成底层汇编指令,是连接人类可读代码与机器底层指令的桥梁。

连接器

属于编译流程的链接阶段。它实现将编译器生成的多个目标文件(.o)以及所需的库文件(如标准库)合并、定位并绑定成一个完整的可执行文件。其作用是解决模块间的符号引用(如函数调用、全局变量),分配最终的内存地址,确保程序各个部分能正确拼接并运行。

格式转换器(Format Converter)

通常属于编译流程的后处理阶段(有时也属于构建工具链的一部分)。它实现将连接器生成的通用可执行文件格式(如 ELF)转换为特定目标环境所需的格式(如纯二进制 .bin、Intel Hex 等)。其作用是去除文件头、调试信息等冗余数据,生成可以直接烧录到裸机硬件或特定引导程序中的镜像文件。

反汇编器(Disassembler)

属于编译流程的逆向分析阶段(并非构建流程的必经环节,而是调试与验证工具)。它实现将机器码(目标文件或可执行文件)反向翻译回汇编代码。其作用是在没有源代码的情况下,帮助开发者查看底层指令、分析程序逻辑、定位崩溃原因以及验证编译器生成的代码是否符合预期。

1. 预处理(汇编文件通常不需要,C文件需要)

arm-linux-gnueabihf-gcc -E led.s -o led.i

2. 编译(生成汇编)

arm-linux-gnueabihf-gcc -S led.i -o led.s

3. 汇编(生成目标文件)

arm-linux-gnueabihf-gcc -c led.s -o led.o

4. 链接(生成 ELF 可执行文件,裸机需要 -nostdlib 和链接脚本)

arm-linux-gnueabihf-ld -Ttext 0x87800000 -o led.elf led.o

注意:更完整的裸机链接通常需要指定链接脚本(.lds)

5. 格式转换(生成最终烧录的 .bin 文件)

arm-linux-gnueabihf-objcopy -O binary -S led.elf led.bin

3、arm汇编调用c语言函数以及c语言函数调用汇编编写的函数,函数参数和返回值如何处理?

当ARM汇编调用C语言函数时,C语言函数需要对函数进行外部声明,同时汇编需要对其进行import引用,同时将使用通用寄存器R0-依次向后的值作为函数的参数,返回值默认采用R00000进行接收。

当C语言使用汇编函数时,C语言需要对函数进行外部声明,同时汇编代码需要对函数进行exp0ort导出,C在使用汇编函数时应参考汇编函数的参数数量,传入对应的参数。参数将依次修改R0-的值,返回值默认修改R0

让 S0P 保持 8 字节对齐,核心就一句话:任何改变 SP 的操作,增减量都必须是 8 的倍数。

相关推荐
zbyyd2 小时前
i.MX6ULL 裸机开发进阶|C 驱动、SDK、BSP 工程、链接脚本
arm
一直C3 小时前
ARM裸机开发|IMX6ULL GIC中断详解,中断流程、GIC版本分类、CP15协处理器
arm·imx6ull·寄存器
myy-learn4 小时前
ARM-复用寄存器以及电气寄存器深化-蜂鸣器
arm
祖力556 小时前
ARM中断(IMX6ULL中断、GIC通用中断控制器)
嵌入式硬件·arm·imx6ull·中断·gic·通用中断控制器
susplus1 天前
【ARM 裸机开发 (IMX6ULL-mini)】GNU工具、Makefile 工程构建、链接脚本详解|C 语言点灯 + 蜂鸣器驱动
linux·arm·makefile·imx6ull
斑马1391 天前
ARM学习笔记(二)——ARM汇编基础
汇编·arm开发·arm
朝发如雪2 天前
快速掌握单片机基础(6)(数据处理与传送指令)(跳转与分支指令)(栈操作与混合编程)(程序状态寄存器操作指令)(内存映射)
单片机·arm
晊晌_h2 天前
ARM 学习 |ARM 汇编指令实战笔记
嵌入式·arm·arm汇编
斑马1392 天前
ARM学习笔记(一)——基本概念
arm开发·arm