/*添加了对串行口UART的初始化,配置了UART的一些控制寄存器,并设置了波特率,部分代码如下*/
InitUART:
#define UART_BRD (( 50750000 / (115200 * 16)) - 1)
mov r2,#UART_BRD /*设置串口的波特率 */
/*初始化堆栈指针*/
ldr sp, L$_STACK_ADDR
mov FP, #0
在建立堆栈之后,系统就具备了高级语言的执行条件,后续的代码就可以用C语言来实现了。
/*使程序跳转至C语言程序段代码如下*/
#if (ARM_THUMB)
ldr r12,L$_rStrtInRom
orr r12,r12, #1
bx r12
#else
ldr pc,L$_rStrtInRom /*跳转到romStart()中执行*/ #endif
CPU将执行权转移给romStart()之后。该函数就使内存清空,然后把整个引导映像复制到内存中,最后将CPU的控制权交给usrInit()。
修改sysLib.c
文件sysLib.c提供VxWorks和应用程序间的板级联系,这里重点介绍一下内存映射函数。
目标系统开启了MMU模块,BSP在sysLib.c文件里面就定义了一个sysPhysMemDesc[ ]表。部分代码如下所示:
PHYS_MEM_DESC sysPhysMemDesc [] =
{ (void*) (ROM_BASE_ADRS+0xf0000000), (void *) (ROM_BASE_ADRS),
ROUND_UP(ROM_SIZE_TOTAL*2,PAGE_SIZE),
VM_STATE_MASK_VALID|VM_STATE_MASK_WRITABLE|VM_STATE_MASK_CACHEABLE,
VM_STATE_VALID|VM_STATE_WRITABLE_NOT|VM_STATE_CACHEABLE_NOT
}
上面一小段代码是对ROM_BASE_ADRS 的内存映射,ROM_BASE_ADRS+0xf0000000是要映射的虚拟地址,ROM_BASE_ADRS是硬件设计时定义的实际物理地址,ROUND_UP(ROM_SIZE_TOTAL*2,PAGE_SIZE)是映射长度,VM_STATE_MASK_VALID|VM_STATE_MASK_WRITABLE|VM_STATE_MASK_CACHEABLE是可初始化的地址状态,VM_STATE_VALID|VM_STATE_WRITABLE_NOT|VM_STATE_CACHEABLE_NOT是实际初始化的地址状态。
若添加新的外设,该外设对应的内存空间必须在sysPhysMemDesc[]中配置。通过这样的配置就完成了内存映射和MMU的开启。
修改dm9kEnd.c
由于S3C2440使用的是DM9000网卡。要做好DM9000网卡的END驱动首先要初始化网卡的数据结构dm9kDevICe,这个数据结构如下:
typedef struct dm9kDevice
{
END_OBJ endObj; /*继承类 */
int unit; /*设备单元号 */
UINT32 flags; /* 本地标志信号*/
int ivec; /* 中断向量 */
int ilevel; *中断级 */
……
} DM9K_DRV_CTRL
数据结构中的END_OBJ类型成员、网卡单元号、中断号和中断向量是网卡驱动中必须包含的成员元素。
驱动的部分接口函数,主要包括网卡加载函数dm9kEndLoad、网卡启动函数dm9kStart、停止网卡函数dm9kStop、网卡控制函数dm9kIoctl、网卡卸载函数dm9kUnload、网卡发送函数dm9kSend、获取组播地址函数dm9kMCastGet、启动轮询模式函数dm9kPollStart、关闭轮询模式函数dm9kPollStop、轮询模式发送函数dm9kPollSend、轮询模式接收函数dm9kPollRcv等,通过对这些接口函数编写功能,实现网卡驱动。
在编写驱动的过程中,还必须注意:由于目标板用一种100PIN的DM9000芯片,这种芯片除了有CMD信号之外,还有6根地址片选信号SA4~SA9,根据SA4~SA9对应的CPU地址线和数据手册上引脚定义,可以计算出网卡的端口地址,如果SA4~SA9对应CPU地址的addr4~addr9,那么网卡端口基址就是0x18000300,这样可以计算出网卡的基地址。
图2 VxWorks COM1口的打印信息