-
嵌入式系统课程论文
在
PROTEUS
中使用
ARM
处理器
及
uC/OS-II
移植理解
Rein Lee
一.嵌入式系统概述
通过本次嵌入式
系统课程的学习,我了解了嵌入式系统的概念。所谓嵌入式
系统,是指用于执行独立功能
的专用计算机系统,它由包括微处理器、定时器、
微控制器、
存
储器、
传感器等一系列微电子芯片与器件,
和嵌入在存储器中的
微
型操作系统、控制应用软件组成,共同实时诸如实时控制、监视、管理、移动计
算、
数据处理等各种自动化处理任务。
嵌入式
系统以应用为中心,
以微电子技术、
控制技术和通讯技术为基础
,
强调硬件软件的协同性与整合性,
软件与硬件可裁
减,以满足系统对功能、成本、体积和功耗等要求。
1
.
1
嵌入式系统的硬件特征
嵌入式系统的
硬件必须根据具体的应用任务,
以功耗、
成本、
体积、
可靠性、
处理能力等为指标来选择。
嵌入式系统的核心是系统软件和应用软件。
由于存储
空间有限,因而要求软件代码紧凑、可靠,大多对实时性有严格的要求。
早期的嵌入式系统设计方法,通常是采用“硬件优先”原则。在粗略估计软
件任务需求的情况下,
首先进行硬件设计与实现。
然后在此硬件
平台上,
再进行
软件设计。因为很难充分利用硬件软件资源,取
得最佳性能的效果。同时,一旦
在测试时发现问题,
需求对设计
进行修改时,
整个设计流程将重新进行,
对成本
和设计周期的影响很大。这种传统的设计方法只能改善硬件
/
< br>软件各自的性能,
在有限的设计空间不可能对系统做出较好的性能综合优化,
p>
在很大程度上依赖于
设计者的经验和反复实验。
随着电子系统功能的日益强大和微型化,系统设计涉及的问题越来越多,难
度也越来越大。
硬件和软件也不再是截然分开的两个概念。
因而出现了软硬件协
同的设计方法。
在系统目标要
求下,
协同设计软硬件体系结构,
以最大限度地挖
掘系统软硬件能力,得到高性能低代价的优化设计方案。
1
.
2
嵌入式操作系统
< br>目前流行的嵌入式操作系统可以分为两类:
一类是从运行在个人电脑上的操
作系统向下移植到嵌入式系统中,形成的嵌入式系统,如微软公司的
W
indows
CE
,
SUN
公司的
Java
操作系统,嵌入式
Linux
等。
另一类是实时操作系统,如
WindRiver
公司的
VxWorks
,
ISI
p>
的
pSOS
,
AT
I
的
Nucleus
,和免费公开源代
码的
uC/OS-II
等。
二.在
Proteus
中使用
ARM
处理器
由于
Proteus
中只支持
LPC
系列的
ARM
处理器,在这里只是简单的列举出
LPC2124
的一些特性:
LPC2
124
是基于一个支持实时仿真和跟踪的
16/32
位
ARM7TDMI-S CPU
的
微处理器,
并带有
256k
的嵌入的高速
Flash
存储器和
16
k
的片那静态
RAM
。
128
位宽度的存储器接口和独特的加速结构使得
32
位代码能够在最大的时钟速率下
运行。
对代码规模有严格控制的应用可使用
16
位
Thumb
模式,
将使得代码规模
降低超过
30
%,而性能的损失却很小。
LPC2124
片那
Boot
装载程序实现在系统编程(
ISP
)和在应用编程(
IAP
)
< br>。
1ms
可以编程
512
字节。
整片擦除只需要
400ms
。
此外还有
4
路
A/D
转换器,
转
换时
间低于
2.24us
;
2
个
32
位定时器,
6
路
PWM
输出、
RT
C
、看门狗和多个串
第
1
页
共
7
页
嵌入式系统课程论文
行接口。
LPC
系列微处理器的抗干扰能力强,在很多应用中得到了使用。
p>
三.软件分析
1
.
LPC
的
Memory Map
、
Remap<
/p>
和
LPC2124
的
Bootblock
程序
Memory Map
是把芯片中、芯片外的
< br>Flash
、
RAM
、外设、<
/p>
BootBlock
等进行
统一编址,用
地址来表示对象。
LPC
系列
ARM<
/p>
处理器的这个地址是出厂时,由
厂家规定的,用户只能访问,而不
能进行更改。
Remap
和
Boot
,个人理解如下:
< br>在
Reset
信号周期内,
LP
C2124
运行芯片内部自带的
Bootblock
程序,复位
信号过后才是运行用户的程序。
p>
LPC
系列
ARM
处理器的
Bootblock
被固化在最高的
< br>Flash
块中,
运行时是被
映
射到
0x7FFFE000
~
0x7F
FFFFFF
区域,这个程序是厂家写入的,它由任何复
位硬件
激活,在任何复位后都会先执行
Boot
装载程序。之所以要把
BootBlock
程序放在
Flas
h
块的顶端,
是因为各芯片的
Flas
h
大小不一致,
厂家为了
BootBl
ock
在芯片中的位置固定,
在编址的
2G
靠前的位置虚拟划分一个区域作为
BootBlock
p>
区域。这就是
Remap
。
BootBlock
的工作如下:
<
/p>
1
.判断
P0.14
是否为低,如果为低,进入
ISP
模式。
< br>
2
.若
P0.14
不为低,要判断
Boot
(
1
:
0
)这两个脚,如果为
11
,要设置
MEMAP=1
< br>,即运行内部
Flash
。否则设
MEMAP
=
3
,运行外部
Flash
。
3
p>
.如果是运行外部
Flash
,那需要把外
部
Flash
的起始地址重新映射到
0
x00000000
,以便复位信号过后就开始运行用户程序。
个人理解
BootBlock
相当于<
/p>
PC
中的
BIOS
,由厂家固化,上电后首先完成映
射,即把它的地址映射到
0
x00000000
处,当初始化完成后,就运行内部
Flas
h
或者外部
Flash
的程序,通常要
以向量表开头,这个过程就是
Remap
,也就是把
内部
ROM
或者外部
Fl
ash
的地址映射到
0x00000000
处。
2
.启动代码分析
运行完
BootBlock
程序之后就是要运行用户自己编写的启动代码了。启动代
码中最重要的是
异常向量表。这个表包括复位、未定义指令、软中断、预取指中
止、数据中止、
IRQ
中断和
FIQ
中
断。
Reset
LDR
PC, ResetAddr
LDR
PC,
UndefinedAddr
LDR
PC, SWI_Addr
LDR
PC, PrefetchAddr
LDR
PC, DataAbortAddr
DCD
0xb9205f80
;
插入用户代码有效签名
LDR
PC, [PC, #-0xff0]
;
从
p>
VIC
处取得
IRQ
入口地址
LDR
PC,
FIQ_Addr
ResetAddr
DCD
ResetInit
UndefinedAddr
DCD
Undefined
SWI_Addr
DCD
SoftwareInterrupt
第
2
页
共
7
页
嵌入式系统课程论文
PrefetchAddr
DCD
PrefetchAbort
DataAbortAddr
DCD
DataAbort
Nouse
DCD
0
IRQ_Addr
DCD
0
FIQ_Addr
DCD
FIQ_Handler
Undefined
B
Undefined
;
未定义指令
PrefetchAbort
B
PrefetchAbort
;
取指令中止
;
取数据中止
DataAbort
B
DataAbort
;
快速中断
未定义指令、取指令中止、快速中断使得
PC
< br>不跳转,进入死循环,等待看
门狗复位用户程序。
对于<
/p>
ARM9
,
有
M
MU
单元,
应该在
PrefetchA
bort
和
DataAbort
处进行
处理,然后返回到发生异常的指令处重新执行一次。
FIQ_Handler
STMFD
SP!, {R0-R3,
LR}
;ADS
编译器会自动保存
R
4-R11
IMPORT
FIQ_Exception
;<
/p>
也可以在
startup.s
的开头引入
BL
FIQ_Exception
;<
/p>
调用
C
语言中的中断服务程序
LDMFD
SP!, {R0-R3, LR}
;
出栈
SUBS
PC,
LR,
#4
如果在
CPSR
中没有禁止中断,那么每执行一条指令,处理器会检查是否有
FIQ
或者
IRQ
中断发生。若有中断发生,当且仅当
PC
指更新后,即处理器对下
一条指令进行取
指发生后,处理器才会进入到中断的服务程序中。因此保存在
LR
中的指是
PC-4
,此处的
PC
p>
是更新后的
PC
,由于
ARM
处理器是三级流水线
的结构,因此返回地址是
LR-4
,返回到的地址是将要执行,但是被中断了指令。
LDR
只能实现当前
PC 4KB
p>
范围内的跳转,
而在
LDR
的不远处用
DCD
定义
一个字
,而在这个字里存放最终的异常服务程序的入口地址,可以实现在
4GB
范围内的全范围跳转。要求整个向量表的累加和为
0
。
__user_initial_
stackheap
函数是对用户的堆栈进行初始化,对它的调用是在
< br>__main
中完成的,
对编程人员不可见。
__main
是
ADS
编
译系统提供的一个库函
数,
使用
__m
ain
标号引导系统时,
必须将应用程序的入口定义为
main()
。
__main
< br>完成代码和数据的复制,并且把
ZI
数据区清零。这一步
当代码和数据区在存储
和运行时处于不同的存储器位置时有意义。
__main
保证了系统在进入用户的应
用程序前自动完成了
系统调用。
但是如果所有的初始化过程都已经被用户代码显
式地
被完成,如堆栈初始化、加载映象、执行映象、
RW
、
ZI
数据的复制等,那
么用户应用程序的入口函
数可以任意定义
any_name()
,完成初始化后,直接<
/p>
B
any_name
即可。
个人建议使用
B
__
main
的方式,
防止疏忽出现不必要的错误,
比如出现程序中的全局变量没有被正确的初始化等错误。
.S
分析
通过定义宏:
$$IRQ_Label
HANDLER
$$IRQ_Exception_Function
来实现
LPC
2124
的多
个中断源共
用一段异常处理代码的目的。
第
3
页
共
7
页