摘要:ARM7TDMI-S是ARM公司设计的一款32位精简指令集处理器内核,LPC210x系列是飞利浦半导体公司生产的基于ARM7TDMI-S内核的芯片。在嵌入式系统设计中,针对嵌入式处理器和操作系统的Bootloader代码的设计是一个难点。本文根据用LPC2106进行嵌入式系统设计的实际经验,总结出基于ARM7TDMI-S内核的嵌入式处理器芯片的Bootloader代码设计的一般流程;给出LPC2106芯片在基于μC/OS-II操作系统的嵌入式应用中,BootLoader程序的详细设计流程及其中的一些关键技术和代码。
引言
芯片的Bootloader代码(即启动代码)就是芯片复位后进入操作系统之前执行的一段代码,主要是为运行操作系统提供基本的运行环境,如初始化CPU堆栈、初始化存储器系统等。Bootloader代码与CPU芯片的内核结构、具体芯片和使用的操作系统等因素有关。其功能有点类似于PC机的BIOS(Basic Input/Output System,基本输入输出系统)程序,但是由于嵌入式系统的软硬件都要比PC机的简单,所以它的Bootloader代码要比BIOS程序简单得多。
嵌入式系统被定义为:以应用中为心,以计算机技术为基础,软件硬件可裁剪,适用于系统对功能、可靠性、成本、何种、功耗有严格要求的专用计算机系统。嵌入式系统的核心部件是嵌入式处理器。随着嵌入式系统在人们日常生活中的广泛运用,嵌入式处理器得到前所未有的飞速发展。基于ARM核的嵌入式处理器芯片种类繁多。由于ARM公司只设计内核的不生产具体的芯片,即便是基于同一种内核,不同厂家生产的芯片差别很大,因此不易编写出统一的Bootloader代码。ARM公司针对这一问题而采取的策略是,不提供完事的Bootloader代码(ARM公司的开发工具ADS提供了一些功能代码),Bootloader代码不足的部分由芯片厂商提供或者由用户自己编写。飞利浦公司没有提供LPC210x系列的Bootloader代码,所以用户只能自己编写Bootloader代码。
1 ARM7TDMI-S和LPC210x
ARM7TDMI-S是目前比较低端的ARM核—ARM核不是芯片,它与其它部件如RAM、ROM、片内外设组合在一起才构成实际的芯片。ARM7是用于对成本和功耗都非常敏感的消费应用的低价位、低功耗的32位核。其主要特点如下:冯.诺依曼结构、3段流水线、0.9MIPS/MHz;非常低的功耗;嵌入式ICE-RT(In Circuit Emulation-Real Time,实时在线仿真)逻辑。
LPC2104/2105/2106基于一个支持实时仿真和跟踪的ARM7TDMI-S内核,并带有128KB的高速Flash存储器,128位宽度的存储器接口和独特的加速结构,使32位代码能够在最大时钟速率下运行。由于LPC2104/2105/2106具有非常小的尺寸和极低的功耗,它们非常适合于那些将小型化作为主要要求的应用,例如存储取控制和POS机。带有宽范围的串行通信接口、片内多达64KB的SRAM,由于具有大的缓冲区和强大的处理器能力,它们非常适合于通信网关和协议转换器、软件调制解调器、声音识别以及低端的图像处理。而多个32位定时器、PWM输出和32个GPIO,使它们特别适用于工业控制和医疗系统。LPC2106是LPC210x系列的一种,其它两种为LPC2104/2105。它们都基于ARM7TDMI-S内核。三种芯片唯一的区别就是SRAM的容量大小:LPC2106是64KB,而LPC2104是16KB,LPC2105是32KB。
2 Bootloader代码
2.1 Bootloader代码的作用
嵌入式系统的资源有限,应用程序通常都是固化在ROM中运行。ROM中的程序执行前,需要对系统硬件和软件运行环境进行初始化。这些工作是用汇编语言和C语言编写的Bootloader代码完成的。在ARM处理器的嵌入式系统中,Bootloader代码的作用主要有以下几点:
*初始化CPU各种模式的堆栈和寄存器;
*初始化系统中要使用的各种片内外设;
*初始化目标板;
*引导操作系统。
2.2 Bootlader代码设计的一般流程
Bootloader代码是嵌入式系统中应用程序的开头部分,它与应用程序一起固化在ROM中,并首先在系统上运行。设计好Bootloader代码是设计嵌入式程序的关键,也是系统能够正常工作的前提。Bootloader代码所执行的操作主要信赖于CPU内核的类型,以及正在开发的嵌入式系统软件中需要使用CPU芯片上的哪些资源。Bootloader代码的一般流程(即Bootloader代码应该进行的操作)如图1所示。
2.3 基于LPC2104和μC/OS-II是多任务的实时操作系统。针对该款芯片和多任务实时操作系统的Bootloader程序的流程如图2所示。
2.3.2 关键代码分析
;中断向量表,给出了CPU芯片出现异常时应该转去执行的程序地址
Vectors
LDR PC,ResetAddr
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;
/*其它步骤的代码与实际的软件功能相关,不具有代表性,故在此不列出*/
}
3 结论
本文介绍的Bootloader代码已经在基于Philips公司的LPC2106芯片开发的系统上运行并测试通过。针对不同的CPU芯片编写Bootloader代码,首先要了解该CPU的内核结构、指令系统,其次是具体芯片的结构和各种片上资源,以及所采用的操作系统。以上所列的设计流程不是一成不变的,在具体应用中要权衡取舍。
- ARM7(51802)
- 代码设计(6290)
ARM7 系列微处理器有哪些特点
ARM7TDMI (Rev 3)核心处理器产品概述
ARM7TDMI技术参考中文手册
ARM9TDMI技术参考手册
ARM嵌入式系统应用中的问题总结分析
ARM嵌入式系统应用中的问题总结分析
ARM嵌入式系统应用中的问题总结分析
ARM嵌入式系统应用中的问题总结分析
ARM嵌入式系统的基本结构
ARM嵌入式系统的学习步骤
ARM嵌入式系统的学习步骤
ARM嵌入式系统的学习步骤
ARM嵌入式系统的学习步骤
ARM嵌入式系统硬件设计及应用实例
ARM嵌入式Linux系统开发从入门到精通
ARM嵌入式Linux系统开发详解
ARM嵌入式最小系统的启动架构是什么?
ARM和嵌入式系统方向介绍
嵌入式ARM原理与应用
嵌入式系统中的掉电保护过程是什么样的?
嵌入式系统结构与协同性探讨
嵌入式系统开发过程中的常见问题和解决方法
嵌入式Linux怎么学?给大家推荐几本学习嵌入式系统的书籍
嵌入式硬件系统的相关资料分享
嵌入式软件代码保护系统是由什么构成的?
μC/OS-II在LPC213X上有哪些移植方案?
《ARM嵌入式系统基础教程》下载
【下载】ARM嵌入式系统基础教程(周立功第2版)
与嵌入式相关的资料
基于ARM7实现嵌入式应用启动程序
基于ARM7的嵌入式音频处理系统的设计
基于ARM怎么搭建嵌入式Linux系统?
基于ARM高速闪存MCU应对广泛嵌入式需求
基于嵌入式操作系统的开发方法有哪些?
基于μClinux ARM的嵌入式系统的设计
基于网络加载的嵌入式BootLoader有什么优点?
大佬都在看的嵌入式复习提纲
移植BootLoader嵌入式操作系统
采用ARM怎么实现嵌入式监测系统?
基于ARM的嵌入式系统软件设计
203ARM7TDMI中文资料参考手册pdf
142arm7tdmi介绍
48基于μClinux/ARM的嵌入式系统的设计
21ARM7TDMI-S在嵌入式系统中的Bootloader代码
25基于ARM7的嵌入式系统上开发USB接口的详细资料
161ARM7TDMI-S 在嵌入式系统中的Bootloader代
10基于ARM的嵌入式系统实验分析
10ARPI7TDPlMI—S在嵌入式系统中的Bootloade
22ARM7在嵌入式应用中启动程序的实现
67嵌入式系统BootLoader 移植
47ARM7TDMI-S(Rev 4)技术参考手册
27在嵌入式系统中实现从RAM快速引导技术
1903
ARM7技术参考手册(中文版)
0ARM7嵌入式系统的中断设计与中断处理优化
198嵌入式系统的实时数据接口扩展研究
1371
基于ARM嵌入式系统开发与应用_吴明晖
0基于LPC2131嵌入式系统μCOS-II实现CAN通讯
1964
ARM7TDMI技术参考手册
6基于NXP LPC213X系列ARM7TDMI-S处理器的开发板
12ARM仿真器与嵌入式系统设计讲解
1uClinux在嵌入式系统中的移植
5基于ARM7核处理器VxWorks系统BSP设计方案解析
35嵌入式Linux系统移植的实现
2535
基于嵌入式Linux系统的Bootloader模型在MIPS64上的移植设计浅析
1259基于ARM的FPGA从串配置方案设计适用于嵌入式系统的应用
3521
如何使用ARM进行嵌入式系统的设计与实现
14LPC213X通过μC/OS-II的多种移植方案
974
基于ARM的FPGA嵌入式系统实现
1586
如何使用ARM进行嵌入式linux的系统设计
10如何编写ARM处理器的Bootloader
4772
ARM7TDMI 调试架构分析
3148
ARM7TDMI-S(Rev 4)技术手册手册
30嵌入式实时操作系统FreeRTOS在ARM7上移植实现
21基于ARM和Linux的嵌入式远程视频监控系统的设计
9ARM嵌入式系统原理及应用教程
42ARM嵌入式系统复习要点
13ARM嵌入式系统
6初识ARM嵌入式系统
17ARM嵌入式系统硬件设计的应用实例
3911
电子发烧友App


评论