微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM7嵌入式系统中Bootloader分析与设计

ARM7嵌入式系统中Bootloader分析与设计

时间:11-11 来源:互联网 点击:

= ENDIF

进入main函数后即可以开始本阶段stage2的初始化任务,这包括:

(1)初始化至少一个串口,以便和终端用户进行交互;

(2)初始化计时器,延时并提示启动模式的选择,如果进入启动加载模式,则系统控制权交由uClinux操作系统,Bootloader功成身退,否则程序继续向下执行。

(3)初始化网络,包括网络基本信息配置等;

(5)如果系统配有LCD等外设,可以在此初始化;

(6)初始化Flash:检测是否支持该Flash芯片(可通过比较Flash ID的方式实现);

(7)初始化中断,包括屏蔽中断,清除中断悬挂标志,初始化中断向量表,注册需要的中断处理函数等。

(8)初始化命令控制台,等待用户键入命令。

在初始化这些设备之前,也可以改变 LED 灯的状态,以表明我们已经进入main函数执行。设备初始化完成后,可以通过串口输出一些打印信息,如程序名字字符串、版本号等。本系统中采用的系统启动引导方案流程图如图1所示。

4.难点分析

4.1异常及中断处理

在ARM支持的7种模式中,共有5种异常模式,而其中又尤以外部中断模式(IRQ)应用较为广泛,其异常处理过程也较为复杂。本文下面将以IRQ异常处理为例,讲述一个通用的中断使用及处理过程。一个ARM通用的中断处理过程大致可以分为以下3步:

(1) 异常响应:获取异常处理程序入口地址,并进入异常处理程序;

(2) 现场保护及恢复:即进入中断服务程序(ISR)前后中断现场的保护和恢复;

(3) 中断服务:计算中断源索引号,清中断,然后进入中断服务。

本例中IRQ异常处理相关代码如下:

ResetEntry

b SYS_RST_HANDLER ;复位异常

......

b IRQ_SVC_HANDLER ;外部中断请求

MACRO ;通过一个宏定义,统一处理各异常处理程序与异常向量地址的映射关系

$HandlerLabel HANDLER $ExceptHandler

$HandlerLabel

sub sp,sp,#4 ;预留一个字的空间用来保存PC的跳转地址

stmfd sp!,{r0} ;保存下面中断处理中使用到的r0寄存器

ldr r0,=$ExceptHandler ;将保存有异常处理函数入口的地址读入r0

ldr r0,[r0] ;将异常处理函数入口读入r0

str r0,[sp,#4] ;将异常处理函数入口存入堆栈中刚才预留的空间

ldmfd sp!,{r0,pc} ;恢复现场,同时跳入异常处理函数

MEND

IRQ_SVC_HANDLER HANDLER IrqSvcVector ;调用宏定义

......

SYS_RST_HANDLER ;复位异常时程序跳转地址

...... ;系统初始化代码

ldr r0, =IrqSvcVector

ldr r1, =IRQ_SERVICE

str r1, [r0] ;将IRQ异常处理程序入口存入变量IrqSvcVector

......

IRQ_SERVICE

STMFD sp!, {r0-r12, lr}

BL ISR_IrqHandler ;跳入C语言中定义的中断服务程序(ISR)

LDMFD sp!, {r0-r12, lr}

SUBS pc, lr, #4 ;异常返回同时复制相应SPSR到CPSR,实现处理器模式自动切换

void ISR_IrqHandler(void) //C语言中定义的中断服务程序

{

unsigned int IntOffSet;

IntOffSet = (unsigned int)inl(INTOFFSET);//取出中断源索引号

Clear_PendingBit(IntOffSet>>2); //清中断

(*InterruptHandlers[IntOffSet>>2])(); // 进入对应的中断服务子函数

}

从上面的代码我们可以总结得出,接收到IRQ中断请求后程序的执行流程是:

(1)执行完当前指令,程序自动跳到0x18地址;

(2)从0x18 程序跳转到IRQ_SVC_HANDLER;

(3)从IRQ_SVC_HANDLER 再到SDRAM高端异常矢量表;

(4)从SDRAM高端异常矢量表跳转到IRQ_SERVICE异常处理程序;

(5)由IRQ_SERVICE最后进入中断服务程序,完成中断处理任务后返回。

4.2 命令控制台

当Bootloader工作在下载模式时,通常会通过串口向终端用户提供一个简单的命令控制台,为了使用的方便,我们这里对其功能进行了扩充,添加了命令键入时对键盘“上、下、左、右、Home、End”几个方向键的支持。

通过串口收发或显示字符时,我们使用的通常是字符的ASCII码。对于非控制字符,也即键入命令时我们可能使用到的命令字符,在控制台中我们使用了ASCII码值从0x20~0x7e之间的字符。对于控制字符,在常用字符ASCII码对照表中我们可以找到Enter键、Backspace(退格)键以及ESC键的ASCII码,但是却没有上下左右方向键以及Home、End键对应的ASCII码,通过对键盘输入字符的串口收发测试发现,如果在测试时按下了方向键则串口在每次按键后会连续发送出3字节数据,前两字节所有方向键的数据相同,分别是0x1b,0x5b,第3字节对应不同的按键,上下右左方向键分别对应的值为:0x41、0x42、0x43、0x44,Home和End键对应的值为0x48和0x4b。故要检测键盘是否键入了方向键,需要向串口连续读取三字节的数据,同理,要控制光标向左、向右移动或Home、End也需要连续

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top