首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于ARM体系的嵌入式系统BSP的程序设计方案 03

基于ARM体系的嵌入式系统BSP的程序设计方案 03

存储器的地址分配是很灵活的,可以将I/O操作映射成内存操作,也可以通过映射对某些不可访问的地址空间进行保护等。进行存储器初始化设计时,一定要根据应用程序的具体要求来完成地址分配。对地址管理通过MMU即存储器管理单元实现。

在arm系统中,MMU通过页式虚拟存储管理,将虚拟空间和物理空间分别分成一个个固定大小的页,并建立两者之间的映射关系,从而实现虚拟地址到物理地址的转换。MMU还可完成存储器访问权限的控制和虚拟存储器空间缓冲特性的设置。

以下是实现MMU的部分代码:

for=(i=1;i<0x1000;i++){

pagetable=(i<<20)|MMU_SECDESC;

} //建立页表,每页大小为1MB,页表偏移序号是物理地址的高12位;

for(addr=SDRAM_BASE;addr<(SDRAM_BASE+SDRAM_SIZE/2);addr+=SIZE_1M)

pagetable[addr>>20]=addr|MMU_SECDESE|

MMU_CACHEABLE|MMU_BUFFERABLE;

//将SDRAM_BASE至(SDRAM_BASE+SDRAM_SIZE/2)空间的设置为不可CACHE和不可BUFFER的

for(addr=SDRAM_BASE+SDRAM_SIZE/2;addr<(SDRAM_BASE+SDRAM_SIZE);addr+=SIZE_1M)

pagetable[addr>>20]=(addr+0x1000000)|

MMU_SECDESC|MMU_CACHEABLE|MMU_BUFFERABLE;

//将这段空间的地址映射关系设置为VA(虚拟地址)=PA(物理地址)+0x1000000

pagetable[0]=(0x42f00000)|MMU_SECDESC|MMU_CACHEABLE|MMU_BUFFERABLE;

//将SDRAM的虚拟地址0x42f00000映射到0处

1.5 初始化各模式下的堆栈指针

因为arm处理器有7种执行状态,每一种状态的堆栈指针寄存器(SP)都是独立的(System和User三项式使用相同SP寄存器)。因此,对程序中需要用到的每一种模式都要给SP寄存器定义一个堆栈地址。方法是改变状态寄存器(CPSR)内的状态位,使处理器切换到不同的状态,然后给SP赋值。这里列出的代码定义了三种模式的SP指针,其中,I_Bit表示IRQ的中断禁止位;F_Bit表示FIQ的中断禁止位:

@;Set up SVC stack to be 4K on top of zero-init data

LDR r1,=installStack

ADDsp,r1,#2048

@;Set up IRQ and FIQ stacks

MOV r0,#(Mode_IRQ32|I_Bit)

MSRcpsr,r0

MOV r0,r0

ADDsp,r1,#2048*2

MOV r0,#(Mode_FIQ32|I_Bit |F_Bit)

MSR cpsr,r0

MOV r0,r0

ADDsp,r1,#2048*3

一般堆栈的大小要根据需要而定,但是要尽可能给堆栈分配快速和高带宽的存储器。堆栈性能的提高对系统性能的影响是非常明显的。

1.6 初始化有特殊要求的端口、设备

有些关键的I/O部件必须在使能IRQ和FIQ之前进行初始化。因为如果在使能IRQ和FIQ之前没有进行初始化,可以产生假的异常中断信号。程序中初始化了HMS30C7202的串口1用来调试程序与其它设备通信。串口1是一个通用全双工异步接收/发送器(UART),它支持16C550的大部分功能。UART有接收缓冲/发送保持寄存器、波特率除数锁存器、中断允许寄存器等9个寄存器。对串口1的初始化主要是对各寄存器的设置,其实现代码如下所示:

_outb(ser_base+0x30,1);

_outw(0x8002301c,0xffff9f9f) ;GPIO PORT A Enable

Register

_outw(0x800230A4,0x6060) ;GPIO PORT A MultiFunction elect-Register

serial_outb(SERIAL_LCR,0x80);

serial_outb(SERIAL_LCR,0x80);

serial_outb(SERIAL_DLL,baud_data[cur_baud]);

serial_outb(SERIAL_DLM,0x0);

serial_outb(SERIAL_LCR,0x03);

seial_outb(SERIAL_FCR,0x01);

serial_outb(SERIAL_IER,0x00);

serial_outb(SERIAL_MCR,0x03);
返回列表