2006年下半年,我们在自己设计的BCNG2440开发板上移植了VXWORKS。移植的过程参考了网络上一些BSP代码,与现有的代码不同的是,我们的BSP实现了内存的重映射,中断向量的重新分配;以及cache和MMU的开启。移植的目的是用于一个数据采集系统,ARM从FPGA读取解调数据,通过100M网络发送到服务器。经过测试,使用UDP发送速率达到了43Mbps,使用TCP发送速率为20Mbps。之前,我们在类似的项目中使用了MPC8260为CPU,当时TCP最高速率也只达到了20多Mbps,因此,我们认为在某些项目中使用ARM替代MPC8260是可行的。
异常处理问题
通常来讲,在嵌入式系统启动之初,CPU将从0地址处(或ffff0000处)开始执行代码,因此初始时将ROM映射在0(或ffff0000)地址处,当进行完必要的初始化并启动异常处理机制后,会将RAM映射到0(或ffff0000)地址处,而将ROM映射到其它地址。
这是因为发生异常时,CPU会跳转到0地址开始处执行异常向量表。由于RAM的访问速度远远高于ROM,因此将RAM映射到0地址后,可以减少异常处理的延迟时间还有其他好处,动态和灵活等。
地址重映射可通过不同的方式实现,例如MPC8260可通过重新为每个memory bank
ARM的体系结构规定在异常发生时,要从0
对于BOOTROM来说,不会使用到MMU,访问地址0就是访问ROM,因此需要将异常向量表建立在启动ROM的开始处。
基本思想是在Flash存储器的起始地址硬编码异常入口,仿vxWorks建立异常向量表。异常发生时,经Flash存储器入口,跳转到自定义函数,再跳转到RAM中异常入口,再调用vxWorks提供的异常处理函数。中断处理流程和中断向量表如下图示意。新异常向量表和原VxWorks设计完全一样。
romInit.c(下面是处理IRQ异常的例子,其它见源代码):
_romInit:
_ARM_FUNCTION(romIRQ)
L$_promIRQ:
.long
#define S3C_EXC_BASE
config.c中定义:
#define S3C_EXC_BASE
sysLib.c:
添加以下函数声明
void s3cExcVecSet(void);
IMP
IMP
IMP
IMP
IMP
添加函数s3cExcVecSet()
void s3cExcVecSet(void)
{
*((volatile int*)(S3C_EXC_BASE + 0x0)) = i;
i = (int)&excEnterSwi;
*((volatile int*)(S3C_EXC_BASE + 0x4)) = i;
i = (int)&excEnterPrefetchAbort;
*((volatile int*)(S3C_EXC_BASE + 0x8)) = i;
i = (int)&excEnterDataAbort;
*((volatile int*)(S3C_EXC_BASE + 0xc)) = i;