第七讲:IMX启动方式
启动设备选择
ARM-A系列的芯片支持多种启动方式,因此当你使用芯片的时候,你需要知道这一点(当然这一点也是取决于芯片手册的)
芯片手册system boot章节,介绍了IMX芯片的启动方式,boot的意思就是启动、引导程序的意思
而我们以前学的M3系列的,它的启动方式就3种,而且程序的烧录地址是内部的ROM,但是IMX芯片的内部ROM我们无法使用,因为它里面存在着启动程序
当我们使用内部BOOT启动的时候,就是选择外部存储器了,下面是支持的外部存储器
重点是:扩展的自己的知识面,启动方式有很多种,假如你以后需要设计开发板,那么你也需要充分的考虑这种问题
IVT表和Bootdata讲解
我们之前就知道,内部的ROM我们是无法使用的,因为里面存在一段程序,而这个程序是有一定的作用的,比如:上面还有找到外置存储等
DCD详解
这一讲的内容听不懂,没有做笔记
第八讲:使用C语言程序点亮LED灯
之前有提过,C语言的运行是需要环境的,而汇编的运行是不需要环境的,因此我们需要知道C语言的环境如何配置,重点是栈指针的指向,sp的指向可以指向内部RAM和外部RAM,如果我们需要指向外部RAM(DDR),那么我们需要初始化一下DDR,但是这个芯片已经初始化好了,因此我们不需要初始化DDR,只需要直接配置sp的地址就可以。但是配置SP的地址是需要访问权限的,因此我们需要拿到一个很高的权限(SVC模式下),通过汇编代码让此时的CPU处于特权模式,我们才能配置一些参数。而SVC模式的决定与一个寄存器,而配置这个寄存器需要的指令是MSR和MRS,不能使用MOV或者LDR,
理解这里的向下增长和为什么sp2mb是0X8020000
我们可以想想我们之前学的stm32的启动文件,其实它一开始也是配置了栈指针,但是为什么没有配置特权模式呢?因为它初始时就为特权模式
程序复位执行的第一条语句不是main而是systeminit,初始化时钟的频率
大致C语言的环境如下:
b指令是不返回的跳转
C语言代码的编写
步骤:.s--.h--.c--makefile--链接脚本--makefile修改
先写汇编代码初始化C语言环境,在.h种宏定义我们需要使用的寄存器的地址,在.c文件种代码,makefile进行编译处理
.s代码编写
.global _start _start: /* 设置SVC模式 */ MRS R0,CPSR BIC R0,R0,#0X1F ORR R0,R0,#0x13 MSR CPSR,R0 LDR SP,=0X80200000 B main
MRS的使用,move to r from s
B是返回不跳转,跳转至main种,无法更改一般
注意事项:学会MRS\BIC\ORR\MSR\LDR的使用规则
.h代码编写
注意事项:volatile以及是无符号类型
#ifndef _MAIN_H_ #define _MAIN_H_ #define CCM_CCGR1 *((volatile unsigned int*)0X20C406) #define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 *((volatile unsigned int*)0X20E0068) #define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 *((volatile unsigned int*)0X20E02F4) #define GPIO1_DR *((volatile unsigned int *)0X0209C000) #define GPIO1_GDIR *((volatile unsigned int *)0X0209C004) #define GPIO1_PSR *((volatile unsigned int *)0X0209C008) #define GPIO1_ICR1 *((volatile unsigned int *)0X0209C00C) #define GPIO1_ICR2 *((volatile unsigned int *)0X0209C010) #define GPIO1_IMR *((volatile unsigned int *)0X0209C014) #define GPIO1_ISR *((volatile unsigned int *)0X0209C018) #define GPIO1_EDGE_SEL *((volatile unsigned int *)0X0209C01C) #endif
.c代码编写
根据寄存器进行赋值即可,跟51编程一样的
Makefile的编写
$^;依赖文件集合,就是相当于objs,下面可以替换成$(objs)
$@;目标文件,相当于.o文件
$<;依赖文件的第一个,相当于.s或者.c
-Ttext链接,包括链接文件和链接地址,链接其实就是把多个.o放在一个地方去就是链接至0x87800000地址中
由于汇编是为了初始化C语言环境,因此汇编的开头地址必须就是我们的链接地址,下面出现的这种情况就是:链接地址的开头不是汇编而是main函数,解决方法就是;把优化去掉
链接脚本的编写
链接脚本以.lds为结尾
起始地址、代码段(汇编的.o文件一定放在开头其余的可以直接省略写为*(.text),
_bss_start和_bss_end这里是一个写法,因为bss段是未初始化的区,因此我们需要知道这个区的地址,我们自己清零,防止使用了我们不知道的变量(以后会学到,这里只是告诉我们有这个东西)
这里涉及到了linux的内存分区,并且地址从小到大依次写
使用链接脚本
自己-T链接脚本