📄 (2).txt
字号:
嵌入式系统的资源有限,应用程序通常都是固化在ROM中运行。ROM中的程序执行前,需要对系统硬件和软件运行环境进行初始化。这些工作是用汇编语言和C语言编写的Bootloader代码完成的。在ARM处理器的嵌入式系统中,Bootloader代码的作用主要有以下几点:
*初始化CPU各种模式的堆栈和寄存器;
*初始化系统中要使用的各种片内外设;
*初始化目标板;
*引导操作系统。
Bootlader代码设计的一般流程
Bootloader代码是嵌入式系统中应用程序的开头部分,它与应用程序一起固化在ROM中,并首先在系统上运行。设计好Bootloader代码是设计嵌入式程序的关键,也是系统能够正常工作的前提。Bootloader代码所执行的操作主要信赖于CPU内核的类型,以及正在开发的嵌入式系统软件中需要使用CPU芯片上的哪些资源。Bootloader代码的一般流程(即Bootloader代码应该进行的操作)如图1所示。
基于LPC2104和μC/OS-II是多任务的实时操作系统。针对该款芯片和多任务实时操作系统的Bootloader程序的流程如图2所示。
关键代码分析
;中断向量表,给出了CPU芯片出现异常时应该转去执行的程序地址
Vectors
LDR PC,ResetAddr
LDR PC,UndefinedAddr
LDR PC,SWI_Addr
LDR PC,SWI_Addr
LDR PC,PrefetchAddr
LDR PC,DataAbortAddr
DCD 0xb9205f80
LDR PC,[PC,#-0xff0]
LDR PC,FIQ_Addr
ResetAddr DCD Reset
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
;InitStack函数,其功能是初始化CPU各种模式的堆栈
InitSatck
MOV R0,LR ;因芯片模式切换,故将程序返回地址保存至R0,同时在初始化堆栈完成后使用R0返回
MSR CPSR_c,#0xd3 ;设置管理模式堆栈
LDR SP,StackSvc
MSR CPSR_c,#0xd2 ;设置中断模式堆栈
LDR SP,StackIrq
MSR CPSR_c,#0xd1 ;设置快速中断模式堆栈
LDR SP,StackFiq
MSR PSR_c,#0xd7 ;设置中止模式堆栈
LDR SP,StackAbt
MSR CPSR_c,#0xdb ;设置未定义模式堆栈
LDR SP,StackUnd
MSR CPSR_c,#0xdf ;设置系统模式堆栈
LDR SP,StackUsr
MOV PC,R0
StackUsr DCD UsrStackSpace+(USR_STACK_LEGTH-1)*4
StackRvc DCD SvcStackSpace+(SVC_STACK_LEGTH-1)*4
StackIrq DCD IrqStackSpace+(IRQ_STACK_LEGTH-1)*4
StackFiq DCD FiqStackSpace+(FIQ_STACK_LEGTH-1)*4
StackAbt DCD AbtStackSpace+(ABT_STACK_LEGTH-1)*4
StackUnd DCD UndtStackSpace+(UND_STACK_LEGTH-1)*4
;系统初始化代码
Reset
BL InitStack ;调用InitStack函数初始化芯片各种模式的堆栈
BL TargetResetInit ;调用TargetResetInit函数对系统进行基本初始化
B _main ;跳转到ADS提供的启动代码_main函数处,它初始化函数库并最终引导CPU进入操作系统的main()函数
上面的程序代码只包含了流程图中的几个主机步骤。这些步骤都是必不可少的,其余的步骤都在TargetResetInit函数中加以实现。本例中的TargerReset Init函数如下:
void TargetResetInit(void)
{/*设置系统各部分时钟*/
PLLCON=1;
#if((Fcclk /4)/Fpclk==1
VPBDIV=0;
#endif
#if((Fcclk/4)/Fpclk==2
VPBDIV=2;
#endif
#if((Fcclk/4)/Fpclk==4
VPBDIV=1;
#endif
#if(Fcco/Fcclk)==1
PLLCFG=((Fcclk/Fosc)-1)|(1<<5);
#endif
#if(Fcco/Fcclk)==2
PLLCFG=((Fcclk/Fosc)-1|(2<<5);
#endif
#if(Fcco/Fcclk)==4
PLLCFG=((Fcclk/Fosc)-1|(3<<5);
#endif
#if(Fcco/Fcclk)==8
PLLCFG=((Fcclk/Fosc)-1)|(4<<5);
#endif
PLLFEED=0xaa;
PLLFEED=0x55;
while(PLLSTAT &(1<<10)==0)
PLLCON=3;
PLLFEED=0xaa;
PLLFEED=0x55;
/*设置存储器加速模块*/
MAMCR=2;
#if Fcclk<20000000
MAMTIM=1;
#else
#if Fcclk<40000000
MAMTIM=2;
#else
MAMTM=3;
#endif
#endif
/*初始化VIC,使芯片在进入μC/OS-II多任务环境前关中断*/
VICIntEnClr=0xffffffff;
VICVectAddr=0;
VICIntSelect=0;
/*其它步骤的代码与实际的软件功能相关,不具有代表性,故在此不列出*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -