您现在的位置:机电论文网>> 嵌入式系统>> 正文内容

arm7tdmi-s芯片lpc2106在嵌入式系统中的bootloader代码设计

作者: 来源: 发布时间:2018/2/11 16:12:47  点击数:1045
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,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;
/*其它步骤的代码与实际的软件功能相关,不具有代表性,故在此不列出*/
}
3 结论
本文介绍的bootloader代码已经在基于philips公司的lpc2106芯片开发的系统上运行并测试通过。针对不同的cpu芯片编写bootloader代码,首先要了解该cpu的内核结构、指令系统,其次是具体芯片的结构和各种片上资源,以及所采用的操作系统。以上所列的设计流程不是一成不变的,在具体应用中要权衡取舍。

更多
字体:【】-【】-【】【关闭此页

上一篇:基于arm920t处理器s3c241'   下一篇:32位arm嵌入式处理器开发过程中调'


特别声明:机电之家(http://www.jdzj.com )所共享的机电类资料,机电论文、机电类文章、机电企业类管理制度、机电类软件都来自网上收集,其版权归作者本人所有,如果有任何侵犯您权益的地方,请联系我们,我们将马上进行处理。购买的论文都出自原创,保证作者的原创的版权的转让,任何纠纷由法律解决。