基于ARM9的BootLoader启动设计.docx
《基于ARM9的BootLoader启动设计.docx》由会员分享,可在线阅读,更多相关《基于ARM9的BootLoader启动设计.docx(13页珍藏版)》请在冰豆网上搜索。
基于ARM9的BootLoader启动设计
长治学院
课程设计报告
课程名称:
嵌入式系统原理与应用技术
设计题目:
Bootloader程序设计
系别:
计算机系
专业:
计算机科学与技术
组别:
第7组(韩伟伟、王富涌)
学生姓名:
韩伟伟学号:
08407106
起止日期:
2011年12月15日-2011年12月22日
指导教师:
刘丽丽
第一章概述
1.1课程设计名称
BootLoader程序设计
1.2课程设计目的
串口驱动和网口驱动程序的设计,可以通过串口或网口接收数据或文件,并且可以写到flash中
1.3要求
编写BootLoader程序uart.huart.c串口驱动测试程序main.c
第二章背景分析
2.1BootLoader的概念
简单地说,BootLoader就是在操作系统内核运行之前运行的一段小程序。
通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
2.2BootLoader的主要任务与典型结构框架
从操作系统的角度看,BootLoader的总目标就是正确地调用内核来执行。
另外,由于BootLoader的实现依赖于CPU的体系结构,因此大多数BootLoader都分为stage1和stage2两大部分。
依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在stage1中,而且通常都用汇编语言来实现,以达到短小精悍的目的。
而stage2则通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。
BootLoader的stage1通常包括一下步骤(以执行的先后顺序):
(1)硬件设备初始化。
(2)为加载BootLoader的stage2准备RAM空间。
(3)复制BootLoader的stage2到RAM空间中。
(4)设置好堆栈。
(5)跳转到stage2的C入口点。
BootLoader的stage2通常包括一下步骤(以执行的先后顺序):
(1)初始化本阶段要使用的硬件设备。
(2)检测系统内存映射。
(3)将kernel映像和根文件系统映像从Flash上独到RAM空间中。
(4)为内核设置启动参数。
(5)调用内核。
第三章BootLoader串口驱动程序的设计
3.1UART寄存器简介
S3C2440AUART控制器,提供3个独立的异步串行I/O端口,每个端口都可以在中断模式或DMA模式下工作。
UART可以产生中断请求或DMA请求,以便在CPU和UART之间传输数据。
在使用系统时钟的情况下,UART可以支持最高115.2Kbps的传输速率。
如果外部设备通过UEXTCLK为UART提供时钟,那么UART的传输速率可以更高。
每个UART通道包含两个用于接收和发送数据的16字节的FIFO缓冲寄存器。
由于UART是串行异步通信方式,因此在UART通信过程中每次只能传输1位(bit),若干位组成一个数据帧(frame),帧是UART通信中最基本单元,它主要包含开始位、数据位、校验位(如果开启了数据校验,要包含校验位)和停止位。
UART在通信之前要在发送端和接受端约定好帧的结构,也就是约定好传输数据帧格式。
(1)开始位:
必须包含在数据帧中,表示一个帧的开始。
(2)数据位:
可选5、6、7、8位,该长度可由编程人员指定。
(3)校验位:
如果在开启了数据校验时,该位必须指定。
(4)停止位:
可选1、2位,该位长度可由编程人员指定。
通信双方约定好帧格式后,指定同一波特率,以保证双方数据传输的同步。
UART串口驱动需要设置的寄存器及其具体特性如表4-1~表4-8所示:
表3-1UART0串行控制寄存器(ULCON0)
寄存器名
地址
是否读写
描述
复位默认值
ULCON0
0x50000000
R/W
串口0串行控制寄存器
0x00
ULCON0
位
描述
初始值
保留
7
0
红外模式
6
选择串口0是否使用红外模式:
0=正常通信模式1=红外通信模式
0
校验模式
5:
3
设置串口0在数据接收和发送时采用的校验方式:
0xx=无校验100=奇校验101=偶校验
110=强制校验/检测是否为1
111=强制校验/检测是否为0
000
停止位
2
设置串口0停止位数:
0=每个数据帧一个停止位
1=每个数据帧二个停止位
0
数据位
1:
0
设置串口0数据位数:
00=5个数据位01=6个数据位
10=7个数据位11=8个数据位
00
表3-2UART0串口控制寄存器(UCON0)
寄存器名
地址
是否读写
描述
复位默认值
UCON0
0x50000004
R/W
串口0控制寄存器
0x00
UCON0
位
描述
初始值
FCLK分频因子
15:
12
当UART0选择FCLK作为时钟源时,设置其FCLK的分频因子
UART0工作时钟频率=FCLK/FCLK分频因子+6
0000
UART时钟源选择
11:
10
选择UART0的工作时钟PCLK,UEXTCLK,FCLK/n:
00,10=PCLK01=UEXTCLK
11=FCLK/n
00
发送数据中断产生类型
9
设置UART0中断请求类型,在非FIFO传输模式下,一旦发送数据缓冲区为空,立即产生中断信号,在FIFO传输模式下达到发送数据触发条件时立即产生中断信号:
0=脉冲触发1=电平触发
0
接收数据中断产生类型
8
设置UART0中断请求类型,在非FIFO传输模式下,一旦接收到数据,立即产生中断信号,在FIFO传输模式下达到接收数据触发条件时立即产生中断信号:
0=脉冲触发1=电平触发
0
接收数据超时
7
设置当接收数据时,如果数据超时,是否产生接收中断:
0=不开启超时中断1=开启超时中断
0
接收数据错误中断
6
设置当接收数据时,如果产生异常,如传输中止,帧错误,校验错误时,是否产生接收中断:
0=不产生错误状态中断
1=产生错误状态中断
0
回送模式
5
设置该位时UART会进入回送模式,该模式仅用于测试
0=正常模式1=回送模式
0
发送终止信号
4
设置该位时,UART会发送一个帧长度的终止信号,发送完毕后,该位自动恢复为0
0=正常传输1=发送终止信号
0
发送模式
3:
2
设置采用哪个方式执行数据写入发送缓冲区
00=无效01=中断请求或查询模式
10=DMA0请求
00
接收模式
1:
0
设置采用哪个方式执行数据写入接收缓冲区
00=无效01=中断请求或查询模式
10=DMA0请求
0
表3-3UARTFIFO控制寄存器(UFCON0)
寄存器名
地址
是否读写
描述
复位默认值
UFCON0
0x50000008
R/W
串口0FIFO控制寄存器
0x00
UFCON0
位
描述
初始值
发送数据
触发级别
7:
6
设置FIFO发送模式的触发级别:
00=FIFO为空触发01=16字节触发
10=32字节触发11=48字节触发
0
接收数据
触发级别
5:
4
设置FIFO接收模式的触发级别:
00=FIFO为空触发01=16字节触发
10=32字节触发11=48字节触发
00
保留
3
0
发送FIFO重置
2
在重置FIFO后自动清除发送缓冲区
0=正常模式1=自动清除
0
接收FIFO重置
1
在重置FIFO后自动清除接收缓冲区
0=正常模式1=自动清除
0
启用FIFO
0
0=不启用FIFO1=启用FIFO
0
表3-4UARTMODEM控制寄存器(UMCON0)
寄存器名
地址
是否读写
描述
复位默认值
UMCON0
0x5000000C
R/W
串口0MODEM控制寄存器
0x00
UMCON0
位
描述
初始值
保留
7:
5
必须全部置0
0
AFC自动流控
4
0=不开启流控1=开启流控
0
保留
3:
1
必须全部置0
000
请求发送
0
如果启用AFC,该位无效,S3C2440A会自动控制nRTS,如果不启用AFC,nRTS必须由软件控制
0=高电平激活nRTS1=低电平激活nRTS
0
表3-5UART发送/接收状态寄存器(UTRSTAT0)
寄存器名
地址
是否读写
描述
复位默认值
UTRSTAT0
0x50000010
R/W
串口0发送/接收状态寄存器
0x06
UTRSTAT0
位
描述
初始值
发送器为空
2
当发送缓存寄存器中没有数据要发送且发送移位寄存器为空时,自动置1
0=非空1=发送器为空
1
发送缓存
寄存器为空
1
当发送缓存寄存器为空时,自动置1
0=发送缓存寄存器非空
1=发送缓存寄存器为空
1
接收缓存
寄存器为空
0
当接收缓存寄存器有数据到达是,自动置1
0=接收缓存寄存器为空
1=缓存寄存器接收数据
0
表3-6UART发送缓存寄存器(UTXH0)
寄存器名
地址
是否读写
描述
复位默认值
UTXH0
0x50000020(L)
0x50000023(B)
W
串口0发送缓存寄存器
—
表3-7UART接收缓存寄存器(URXH0)
寄存器名
地址
是否读写
描述
复位默认值
URXH0
0x50000024(L)
0x50000027(B)
R
串口0接收缓存寄存器
—
表3-8UART比特率除数寄存器(UBRDIV0)
寄存器名
地址
是否读写
描述
复位默认值
UBRDIV0
0x50000028
R/W
串口0比特率除数寄存器
0x00
UBRDIV0
位
描述
初始值
比特率除数
15:
0
设置比特率除数(大于0)使用外部输
入时可以置0
—
3.2UART串口工作原理
每个UART包含一个波特率产生器、发送器、接收器和一个控制单元。
波特率发生器的时钟可以由PCLK或UEXTCLK提供。
发送器和接收器包含64字节的FIFO缓冲寄存器和数据移位器。
发送时,数据被写入FIFO,然后拷贝到发送移位器中(1字节大小),接下来数据通过发送数据引脚(TxDn)被发送。
接收时,接收到的数据从接收数据引脚(RxDn)移入,然后从移位器(1字节大小)拷贝到FIFO中。
3.3UART驱动程序详细设计
UART驱动程序设计到的函数主要有初始化函数、串口发送字节函数、串口发送字符串函数、串口接收字节函数
新建uart.h头文件,编写代码如下:
#ifndef_UART_H
#define_UART_H
//串口寄存器宏定义
#definerULCON0(*(volatileunsignedlong*)0x50000000)
#definerUCON0(*(volatileunsignedlong*)0x50000004)
#definerUFCON0(*(volatileunsignedlong*)0x50000008)
#definerUMCON0(*(volatileunsignedlong*)0x5000000C)
#definerUTRSTAT0(*(volatileunsignedlong*)0x50000010)
#definerUTXH0(*(volatileunsignedlong*)0x50000020)
#definerURXH0(*(volatileunsignedlong*)0x50000024)
#definerUBRDIV0(*(volatileunsignedlong*)0x50000028)
#definerGPHCON(*(volatileunsignedlong*)0x56000070)
#definerGPHDAT(*(volatileunsignedlong*)0x56000074)
#definerGPHUP(*(volatileunsignedlong*)0x56000078)
externintUART_Select(uint8no);
externvoidUART_Init(void);
externvoidUART_SendByte(uint8data);
externvoidUART_SendStr(charconst*str);
externintUART_GetKey(void);
#endif
新建uart.c文件,用于具体实现上述函数,代码如下:
#include"config.h"
//串口初始化函数
voidUART_Init(void)
{
inti;
rGPHUP=rGPHUP|(0x03<<2);
rGPHCON=(rGPHCON&(~0x000000F0))|(0x000000A0);
rUFCON0=0x00;//禁止FIFO功能
rUMCON0=0x00;//AFC(流控制)禁能
rULCON0=0x03;//禁止IRDA,无奇偶校验,1位停止位,8位数据位
rUCON0=0x245;//使用PCLK来生成波特率,发送中断为电平触发模式,接收中断为边沿触发模式,禁止接收超时中断,使能接收错误中断,正常工作模式,中断或查询方式(非DMA)
rUBRDIV0=(int)(PCLK/16.0/UART_BPS+0.5)-1;//串口波特率设置
for(i=0;i<100;i++);
}
//串口发送字节函数
voidUART_SendByte(uint8data)
{
inti;
while(!
(rUTRSTAT0&0x02));//等待发送器为空
for(i=0;i<10;i++);
rUTXH0=data;//发送数据
}
//串口发送字符串函数
voidUART_SendStr(charconst*str)
{
while(*str!
='\0')
{
if(*str=='\n')UART_SendByte('\r');
UART_SendByte(*str++);//发送数据
}
}
//串口接收字节函数
intUART_GetKey(void)
{
inti;
while(!
(rUTRSTAT0&0x1));
for(i=0;i<10;i++);
return(rURXH0);
}
编写main.c,内容如下:
intmain(void)
{
charcmd[20];
uint8rece[256];
memset(cmd,'\0',20);
UART_Select(0);
UART_Init();
Clk_Init();
DelayNS(10);
UART_SendStr("串口初始化完成!
\r\n");
UART_SendStr("时钟初始化完成!
\r\n");
while
(1)
{
memset(cmd,'\0',20);
UART_Receive(cmd);
//UART_SendStr(cmd);
if(memcmp(cmd,"exit",4)==0)
break;
}
UART_SendStr("\r\nGOODBYE!
\r\n");
return0;
}
第四章总结
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,ARM嵌入式系统已经成为当今计算机应用中空前活跃的领域,在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握嵌入式的开发技术是十分重要的。
回顾起此次ARM课程设计,我仍感慨颇多,在接近四星期的日子里,可以说得是苦多于甜,但是可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说不懂一些元器件的使用方法,对汇编语言掌握得不好……通过这次课程设计之后,一定把以前所学过的知识重新温故。
参考文献
[1]黄智伟,邓月明,王彦.ARM9嵌入式系统设计基础教程.北京:
北京航空航天大学出版社,2008.
[2]杨铸,唐攀.深入浅出嵌入式底层软件开发.北京:
北京航空航天大学出版社,2011
[3]周立功.ARM嵌入式系统软件开发实例.北京:
北京航空航天大学出版社,2004
[4]袁志勇,王景存.嵌入式系统原理与应用技术.北京:
北京航空航天大学出版社,2009
指导教师评语:
指导教师签名:
年月日
成绩评定
项目
权重
成绩
1、设计过程中出勤、学习态度等方面
0.1
2、设计技术水平
0.4
3、编程风格
0.2
4、设计报告书写及图纸规范程度
0.3
总成绩