正点原子-Linux嵌入式开发学习-第二期02

第七讲:IMX启动方式

启动设备选择

ARM-A系列的芯片支持多种启动方式,因此当你使用芯片的时候,你需要知道这一点(当然这一点也是取决于芯片手册的)

芯片手册system boot章节,介绍了IMX芯片的启动方式,boot的意思就是启动、引导程序的意思

而我们以前学的M3系列的,它的启动方式就3种,而且程序的烧录地址是内部的ROM,但是IMX芯片的内部ROM我们无法使用,因为它里面存在着启动程序 

正点原子-Linux嵌入式开发学习-第二期02_第1张图片

正点原子-Linux嵌入式开发学习-第二期02_第2张图片

当我们使用内部BOOT启动的时候,就是选择外部存储器了,下面是支持的外部存储器

正点原子-Linux嵌入式开发学习-第二期02_第3张图片 重点是:扩展的自己的知识面,启动方式有很多种,假如你以后需要设计开发板,那么你也需要充分的考虑这种问题正点原子-Linux嵌入式开发学习-第二期02_第4张图片

 IVT表和Bootdata讲解

正点原子-Linux嵌入式开发学习-第二期02_第5张图片

 我们之前就知道,内部的ROM我们是无法使用的,因为里面存在一段程序,而这个程序是有一定的作用的,比如:上面还有找到外置存储等

DCD详解

这一讲的内容听不懂,没有做笔记

第八讲:使用C语言程序点亮LED灯

之前有提过,C语言的运行是需要环境的,而汇编的运行是不需要环境的,因此我们需要知道C语言的环境如何配置,重点是栈指针的指向,sp的指向可以指向内部RAM和外部RAM,如果我们需要指向外部RAM(DDR),那么我们需要初始化一下DDR,但是这个芯片已经初始化好了,因此我们不需要初始化DDR,只需要直接配置sp的地址就可以。但是配置SP的地址是需要访问权限的,因此我们需要拿到一个很高的权限(SVC模式下),通过汇编代码让此时的CPU处于特权模式,我们才能配置一些参数。而SVC模式的决定与一个寄存器,而配置这个寄存器需要的指令是MSR和MRS,不能使用MOV或者LDR,

正点原子-Linux嵌入式开发学习-第二期02_第6张图片

 正点原子-Linux嵌入式开发学习-第二期02_第7张图片

 理解这里的向下增长和为什么sp2mb是0X8020000

我们可以想想我们之前学的stm32的启动文件,其实它一开始也是配置了栈指针,但是为什么没有配置特权模式呢?因为它初始时就为特权模式

程序复位执行的第一条语句不是main而是systeminit,初始化时钟的频率

正点原子-Linux嵌入式开发学习-第二期02_第8张图片

 大致C语言的环境如下:正点原子-Linux嵌入式开发学习-第二期02_第9张图片

 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的使用规则

正点原子-Linux嵌入式开发学习-第二期02_第10张图片

 .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地址中

 

正点原子-Linux嵌入式开发学习-第二期02_第11张图片

正点原子-Linux嵌入式开发学习-第二期02_第12张图片

 

 由于汇编是为了初始化C语言环境,因此汇编的开头地址必须就是我们的链接地址,下面出现的这种情况就是:链接地址的开头不是汇编而是main函数,解决方法就是;把优化去掉

正点原子-Linux嵌入式开发学习-第二期02_第13张图片

正点原子-Linux嵌入式开发学习-第二期02_第14张图片

正点原子-Linux嵌入式开发学习-第二期02_第15张图片

 

链接脚本的编写 

链接脚本以.lds为结尾

起始地址、代码段(汇编的.o文件一定放在开头其余的可以直接省略写为*(.text),

_bss_start和_bss_end这里是一个写法,因为bss段是未初始化的区,因此我们需要知道这个区的地址,我们自己清零,防止使用了我们不知道的变量(以后会学到,这里只是告诉我们有这个东西)

正点原子-Linux嵌入式开发学习-第二期02_第16张图片

 这里涉及到了linux的内存分区,并且地址从小到大依次写

使用链接脚本

自己-T链接脚本

正点原子-Linux嵌入式开发学习-第二期02_第17张图片

 

你可能感兴趣的:(linux学习,学习)