2020.8.31号:wsqxfx
1、secureCRT安装之后破解码破解不了,网上的用不了稍后处理
2、开发板的介绍我自己看了,就不写进去了
重点:
1、ARM汇编基础:对于大部分cortex-A系列的芯片,芯片上电以后C语言的环境还没准备好,所以第一行程序肯定是汇编,至于写多少汇编,看到哪一步能把C语言环境准备好,
2、GNU汇编语法:GNU汇编语法适用于所有的架构,并不是ARM独享的,GNU汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分,如下:
Label:instruction@comment
Label:标号,表示地址的位置,有些指令前面可能有标号,可以通过标号得到指令的地址,标号也可以表示数据的地址,任何以“:”结尾的标识符都会被识别为一个标号。
Instruction:指令,也就是 汇编指令或者伪指令
Comment:注释内容 @跟// /**/意义一样
例如 add(标号):MOVS R0,#0x12(指令) @将R0设置为0x12(注释)
注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ARM中的指令,伪指令,伪操作,寄存器名等可以全部使用大写,也可以全部使用小写,不能大小混写。
3、用户可以使用.section伪操作来定义一个段,汇编系统预定义了一些段名:
.text代码段 .data初始化的数据段 .bss未初始化的数据段 .rodata只读的数据段
汇编程序的默认入口标号是start,
.global _start
_start:
Ldr r0,=0x12 @r0=0x12
.global是伪操作,将_start设置为全局标号,常见的伪操作有
.byte 定义单字节数据:.byte 0x12
.short 定义双字节数据:.byte 0x1212
.long 定义四字节数据:.byte 0x12123434
.equ 赋值语句 .equ num,0x12
.align 数据字节对齐 .align 4 表示4字节对齐
.end 便是源文件结束
.global 定义一个全局符号,格式 .global symbol .global _start
上面这些就是最基本的伪操作了
4、GNU汇编支持函数,函数格式如下,返回语句不是必须的
函数名:
函数体
返回语句 bx xx
例子:中断服务函数
//未定义终端
Undefined_Handler:
LDR R0,=Undefined_Handler
bx R0
//SVC中断
SVC_Handler:
LDR R0,=SVC_Handler
bx R0
//预取终止函数
PrefAbort_Handler:
LDR R0,=PrefAbort_Handler
bx R0
5、常用汇编指令(暂时学习到7.2.4)
1、处理器内部数据传输指令
处理器最多的事情就是在处理器内部来回的传递数据,常见的操作:
1、将数据从一个寄存器传递到另一个寄存器 MOV R0,R1
2、将数据从一个寄存器传递到特殊寄存器,如CPSR SPSR寄存器
MRS R0,CPSR
MSR CPSR,R1 将R1里面的数据复制到特殊寄存器CPSR中
3、将立即数传递到寄存器
MOV R1,#0X12 @R1=0X12
2、存储器访问指令
ARM不能直接访问存储器,比如RAM中的数据,I.MX6UL中的寄存器就是RAM类型的,我们用汇编来配置I.MX6UL的寄存器的时候需要解除存储器访问指令,一般先将要配置的值写入到RX寄存器中,然后借助存储器访问指令将RX中的数据写入到I.MX寄存器中,读取的过程就是相反的。常用的存储器访问指令有两种:LDR STR。
LDR: LDR RX,[RN,#offset] 从存储器RN+offset的位置读取数据存放到RX中
STR: STR RX,[RN,#offset] 将RX中的数据存储到RN+offset的位置上
2.1、LDR主要是把存储器上的数据加载到寄存器中,LDR也可以将一个立即数加载到寄存器RX中,LDR加载立即数是“=”,不是“#”。
LDR R0,=0X0209C004@将寄存器地址加载R0中,即R0=0X0209C004
LDR R1,[R0]@读取R0地址的数据保存到R1中
2.2、STR将数据写入到寄存器中。
LDR R0,=0X0209C004@将寄存器地址加载R0中
LDR R1,=0X20002000@将想写入的值加载到R1中
STR R1,[R0]@将R1的值写到R0地址中
3、入栈和出栈指令
3.1、通常我们会在A函数中调用B函数,当B函数执行完以后再回到A函数继续执行,要想在调回A函数的时候还能够正常运行,就必须在跳到B函数之前将当前处理器状态保存起来,(就是保存R0~R15这些寄存器),当B函数执行完之后再恢复这些寄存器的值即可,保护寄存器需要入栈,恢复寄存器需要出栈,利用当前的栈指针SP来生成地址,处理器的堆栈是向下增长的。
3.2、PUSH<R0~R3,R12>@将R0~R3,R12压栈
PUSH<LR>@LR入栈
出栈的就是从栈顶出栈,也就是常说的先进后出,
POP<LR>
POP<R0~R3,R12>
3.3、PUSH STMFD SP!
POP LDMFD SP!
这上面是PUSH和POP的另外一种写法,所以入栈和出栈的操作还可以写成:
STMFD SP!,{R0~R3,R12} @将R0~R3,R12压栈
STMFD SP!,{LR}@LR入栈
LDMFD SP!,{LR}@LR出栈
LDMFD SP!,{R0~R3,R12}@出栈R0~R3,R12
STMFD !SP STM是STR的变化,STR只能存储一个数据,STM存储存储多个
FD :FULL descending 满递减的意思
SP:栈指针
1、跳转指令
4.1、B指令:这是最简单的跳转指令,B指令会将PC寄存器的值设置为跳转目标地址,一旦执行B指令,ARM处理器就会立即跳转到指定的目标地址。如果要调用的函数不会再返回到原来执行处,那就可以用B指令。最典型的就是汇编初始化C运行环境,然后跳转到C文件的main函数中运行。
4.2、BL指令相比B指令,在跳转之前会在寄存器LR中保存当前PC寄存器值,所以可以通过将LR寄存器的值重新加载到PC中集训从跳转之前的代码运行。跟入栈出栈配合,上面学习的知识
B和BL指令的区别,B是执行了之后就不会回到最初的地方了。
2、算数运算指令
ADD:加法 ADC:带进位的加法
SUB:减法 SBC: 带借位的减法
MUL:乘法
UDIV:无符号除法
SDIV:有符号除法
3、逻辑运算指令
AND:& 按位与
ORR:| 按位或
BIC: BIC Rd,Rn Rd=Rd&(~Rn) 位清除
ORN: ORN Rd,Rn,Rm Rd=Rn|(Rm) 按位或非?????---是不是写错了
EOR: EOR Rd,Rn Rd=Rd^RN 按位异或
是不是文档写错了,后续查一下,应该是写错了吧。
2020-09-02:wsqxfx
学习的方式:第一遍:先看这一章的内容,了解概念问题,第二遍:摘录我认为比较重要的内容做笔记;第三遍:实际上机操作。一个章节大概这样就学习了三遍,基本内容就掌握了。
汇编LED实验总结
1、将I.MX6U的Io作为GPIO使用,我们需要以下几步
1.1、使能GPIO对应的时钟------18章
1.2、设置IOMUXC_SW_MUX_CTR_PAD_XX_XX,设置IO的复用功能,使其复用为GPIO功能-----30章
1.3、设置寄存器IOMUXC_SW_PAD_CTR_PAD_XX_XX,设置IO的上下拉、速度等--30章
1.4、配置GPIO,设置为输入/输出,是否使能中断,默认输出电平等---26章
认真阅读这些寄存器代表的含义,其实也不难
2、汇编程序的编写,这个编写其实也不难,左盟主的教程给的很详细,基本上就是往指定的地址里写进指定的参数。重要的是学习方法
为了编译在ARM开发板上运行的led.o文件,使用了如下命令
2.1.arm-linux-gnueabihf-gcc -g -c led.s -o led.o -g:调试信息 -c:只编译不链接 -o:指定编译产生的 名字
2.2.arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf -Ttext:指定链接的地址 -o:指定链接生成的文件名
2.3.arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin -O:指定以什么格式输出,到此处我们得到了最终要的led.bin文件,
2.4.arm-linux-gnueabihf-objdump -D led.elf > led.dis -D:表示反汇编所有的段,led.dis就是汇编文件
3、建立Makefile文件:避免每次都重复编译
代码内容如下
通过make 和 make clean 命令编译、清理工程
4、代码的烧写
学习STM32的时候,编译完的代码可以直接通过MDKIAR下载到内部flash中。I.MX6U虽然内部有96K的ROM,但是这96K是NXP自己用的,不向用户开放。所以相当于I.MX没有内部flash,我们的代码需要地方存放。为此,I.MX6U支持从外置的存储介质中启动,所以我们可以将代码烧写到存储介质中,这些介质中,除了SD卡外,其他一般都是焊接到板子上的,我们没法直接烧写,SD卡是移动的,可以将SD卡插到电脑上,在电脑上将.bin文件烧录到SD卡中,然后插到板子上。量产的时候不可能放到SD卡中,一般存放在其他介质中,比如NOR FLASH NAND FLASH QSPI FLASH .
前面编译的.bin文件不能直接复制到SD卡中,编译出来的可执行文件是怎么存放到SD卡中,存放的位置是什么,这个NXP是有详细规定的,我们必须按照NXP的规定来将代码烧写到SD卡中。否则代码是绝对运行不起来的。
左盟主用的是正点原子编写的软件 将编译出来的.bin文件烧写到SD卡中,软件叫imxdownload,我暂时就用他的,后面搞清楚是按照什么规则的。 -----今晚暂定学习到这里