uClinux嵌入系统中外部硬件设备的快速调试方法

作者: 佚名   发布日期:2006-01-02 12:45   查看数:104   出自:互联网



2 快速设备访问

在C语言中,用指针可以对内存地址单元进行直接访问,因此在设计中可以采用指针对外部设备进行快速操作。
2.1 地址映像
为了访问外部设备,首先应将外设的寄存器映像到MCF5272的内存,与内存统一编址。为此,需要修改相应代码。
用于COLDFIRE MCF5272的嵌入式μClinux启动代码由两部分组成:

μClinux/linux/arch/m68knommu/platform/5272/MOTOROLA/crt0_rom.S
μClinux/linux/arch/m68knommu/platform/5272/sysinit.c

其中crt0_rom.S由汇编写成,完成CPU的初始化设置,这是整个软件体系的最开始执行的代码入口,CPU一加电就跳到这里执行;sysinit.c为C语言代码,完成MCF5272的集成模块SIM(如串口、时钟、通用I/O等)、 SDRAM、FLASH和其它外设接口、片选等的初始化设置。
MCF5272的片选CS0~CS7的寄存器CSBR0~CSBR7和 CSOR0~CSOR7可将外设备寄存器的地址映像到内存储空间,这样可以采用对内存空间的访问来达到访问外部设备。其中寄存器CSBR指明了映像的内存起始地址、映像的内存容量、总线宽度等;寄存器CSOR用于配置访问控制。片选CS0用于启动存储器ROM(FLASH)。

在C语言文件sysinit.c中修改代码以实现外设的寄存器映像功能。应用片选CS2实现的代码如下:
MCF5272_WR_CS_CSBR2(imm,0xffa00001);//寄存器内存开始地址:0xffa00000
MCF5272_WR_CS_CSOR2(imm,0xfff00014);//片选2

其中imm为无符号字符指针,代表了MCF5272系统集成模块(SIM)中的寄存器地址。

2.2 实现访问函数
通过修改启动代码,将外部设备的寄存器单元映像到内存单元后,就可以使用访问内存的宏和指针快速访问外部设备的寄存器。有两类实现设备快速访问的函数。

2.2.1 使用宏定义
(1)对设备的该函数read_register()实现
#define read_register(IMM,OFFSET,SIZE)Mcf5272iord(IMMP,OFFSET,SIZE)

(2)对设备的写函数write_register()实现
#define write_register(IMM,OFFSET,SIZE,DAT)Mcf5272iowr(IMMP,OFFSET,SIZE,DATA)

其中Mcf5272_iord和Mcf5272_iowr为宏。在sysinit.h中有下列宏定义:

(a)用于计算地址的宏
#define Mcf5272_addr(IMM,OFFSET)((void *)&((unsigned char *)IMMP[OFFSET]))

表示基地址为IMM,偏移地址为OFFSET的内存地址。宏返回物理地址。

(b)访问内存的宏
#define Mcf5272_iord(IMMP,OFFSET,SIZE)
(*(volatile uint ## SIZE *)(Mcf5272_addr)(IMMP,OFFSET)))
#define Mcf5272_iowr(IMMP,OFFSET,SIZE,DATA)
(*(volatile uint ## SIZE *)(Mcf5272_addr(IMMP,OFFSET))=(DATA))

分别表示读内存地址单元内容、将数据DATA写入内存地址单元。地址单元的基地址为IMM,偏移地址为OFFSET。SIZE表示每次读写操作的数据度,取值可为8、16、32,分别表示每次操作8位、16位、32位的总线数据。
2.2.2 采用指针直接定义

(1)对设备的读函数inb()、inw()、inl()实现

#define inb(addr)(*(volatile unsigned chart*)(addr))

#define inw(addr)(*(volatile unsignedshort*)(addr))

#define inl(addr)(*(volatile unsigned long*)(addr))

分别是8位、16位、32位数据总线的读函数。

(2)对设备的写函数outb()、outw()、outl()实现

#define outb(data,addr)((*(volatile unsigned char*)(addr))=(data))

#define outw(data,addr)((*(volatile unsigned short*)(addr))=(data))

#define outl(data,addr)((*(volatile unsigned short*)(addr))=(data))

#define outl(data,addr)((*(volatile unsigned long*)(addr))=(data))

分别是8位、16位、32位数据总线的写函数。
第1页第2页第3页
相关文章(最新&最热)