VxWorks下PC104CAN驱动程序设计.docx

上传人:b****4 文档编号:4306609 上传时间:2022-11-29 格式:DOCX 页数:15 大小:66.98KB
下载 相关 举报
VxWorks下PC104CAN驱动程序设计.docx_第1页
第1页 / 共15页
VxWorks下PC104CAN驱动程序设计.docx_第2页
第2页 / 共15页
VxWorks下PC104CAN驱动程序设计.docx_第3页
第3页 / 共15页
VxWorks下PC104CAN驱动程序设计.docx_第4页
第4页 / 共15页
VxWorks下PC104CAN驱动程序设计.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

VxWorks下PC104CAN驱动程序设计.docx

《VxWorks下PC104CAN驱动程序设计.docx》由会员分享,可在线阅读,更多相关《VxWorks下PC104CAN驱动程序设计.docx(15页珍藏版)》请在冰豆网上搜索。

VxWorks下PC104CAN驱动程序设计.docx

VxWorks下PC104CAN驱动程序设计

VxWorks下PC/104-CAN驱动程序设计

文章作者:

西北工业大学解月江秦龙勇谢拴勤中国民航飞行学院彭卫东

文章类型:

设计应用文章加入时间:

2003年9月24日2:

32

文章出处:

单片机及嵌入式系统应用

   摘要:

详细介绍实时多任务操作系统VxWorks环境下驱动程序的设计原理;针对驱动程序实现的困难,给出VxWorks下实现驱动程序的工作步骤。

文件以PC/104-CAN适配卡为例,简要介绍硬件结构,重点给出驱动程序实现的关键代码。

   关键词:

RTOSVxWorksPC/104CANI/O系统驱动系统

VxWorks是一款优秀的实时多任务操作系统,具有抢占式调试、中断延迟小等特点。

本文在简要介绍必备的硬件环境下,以VxWorks为平台,详细介绍驱动程序的开发。

1PC/104-CAN适配卡的硬件结构

PC/104-CAN适配卡主要由CAN控制器(SJA1000)、光电隔离(6N137),收发驱动器(82C250)及译码电路组成。

编程主要了解的是控制器SJA1000。

CAN适配卡原理如图1所示。

2CAN地址译码和中断选择

系统104主板的CPU为486DX,其对接口板访问有两种方式:

内存映射和I/O访问。

I/O寻址采用专门的指令,每次只能传送单个字节。

内存映射方式可以访问较大的地址空间并且指令丰富,便于实现快速交换数据。

本文讨论的CAN卡采用存映射模式工作,与486DX接口是104总线,它与ISA总线兼容。

对于IntelX86体系的CPU,ISA可以映射的空间为0xC8000~0xEFFFF。

使用比较器和地址选择开关组成可选端口地址译码电路,通过开关选通内存映射基地址(C8000H、C9000H、CA000H、…、EF000H),以避免与其它器件冲突。

CAN偏移地址分配如下:

00~FFHSJA1000的寄存器;

100H~1FFH对该范围内的任意地址进行写操作,均可导致CAN硬件复位。

SJA1000的INT引脚通过跳线选择IRQ3~7、IRQ9~12或IRQ15中的一个,避免与其它的适配卡冲突。

3PC/104-CAN适配卡驱动实现

3.1VxWorks驱动概述

VxWorks操作系统有两种方式实现驱动。

第一种方式是,把设备驱动程序作为独立任务实现,直接在顶层任务中实现硬件操作,完成特有专用的驱动程序。

第二种方式是,VxWorks的I/O系统将设备程序作为内核过程实现。

这种方式便于实现I/O子系统的层次模型,便于文件系统一起把设备作为特殊文件处理,提供统一的管理、统一的界面和统一的使用方法,并把设备、文件及网络通信组织成为一致的更高层次的抽象,为用户提供统一的系统服务和用户接口。

我们和这种驱动方式。

   作为I/O系统和硬件设备之间的连接层,VxWorks驱动就是屏蔽硬件操作,为I/O系统提供服务。

实现一个完整的驱动,必须了解VxWorks下I/O的三个基本元素:

File、Driver和Dervice。

File是为用户提供访问设备的统一接口;Driver是实现具体的基本控制函数,也就是实现I/O系统所需要的接口;而Device则是一个抽象的硬件设备,是一系列的结构体、变量和宏定义对实际物理设备的定义。

一般而言,实现一个驱动应该有三个基本的步骤:

①用编程语言完成对实际物理设备的抽象;②完成系统所需要的各类接口及自身的特殊接口;③将驱动集成到操作系统中。

之后还有一些调试工作。

3.2VxWorksI/O系统驱动程序框架

VxWorks为各种设备(包括字符设备、块设备、虚拟设备及网络设备)提供统一的访问接口,包括七种基本的I/O函数:

open(filename、flags、mode),create(filename、flags),read(fd、&buf、nBytes),write(fd、&buf、nBytes),ioctl(fd、command、arg),close(fd)及remove(filename)。

I/O系统所起的作用就是,把用户请求分配到与设备对应的驱动例程中去。

VxWorks系统中有一个驱动程序列表,其形式如表1所列。

表1设备驱动列表(调试时可利用iosDrvShow()查看)

驱动号码

create

remove

open

close

read

write

ioctl

1

 

 

 

 

 

 

 

2

caOpen

NULL

caOpen

caClose

caRead

caWrite

caIoctl

I/O系统的可动态调用iosDrvInstall()函数将设备的驱动例程(即XXOpen()、XXClose()、XXRead()等)加入到设备驱动列表中,如图2所示。

同样,系统中有一个设备列表,每个设备对应于设备列表中的一项,每一项包括设备名称和设备驱动号,同时包括一个设备描述的结构。

该结构第一个变量是DEV_HDR类型的变量DEV_HDR。

DEV_HDR的定义如下:

Typedefstruct

{

DL_NODEnode;/*设备列表节点*/

shortdrvNum;/*驱动号码*/

char*name;/*设备名*/

}DEV_HDR;

系统调用iosDevAdd(),可以将设备加入到设备列表中。

系统中将驱动和设备联系起来的就是文件描述符列表,每个文件描述符列表除了包括驱动号、设备ID外,还包括文件名、可用标志和指向DEV_HDR的指针。

系统每次成功执行open(),返回一个文件描述符,这样对于设备的read()、write()及ioctl()就可以通过文件描述符进行。

文件描述符表(调试时调用iosFdShow()查看)如下:

I/O系统的整体结构如图3所示。

系统启动时(一般挂接在usrroot()),XXDrv()和XXDevCreade()便将设备及其驱动加入相应的列表中。

3.3设备驱动程序的访问过程

下面以CAN驱动程序为例,说明驱动程序的访问过程。

(假定设备名“/can/1”并且以CAN设备驱动程序为例,上述中的XX在这里用Can代替。

①fd=open(“/can/1”,O_RDWR,0644)

②I/O系统在设备列表中寻找设备名为/can/1的设备项,找到相应的设备驱动号。

③I/O系统在文件描述符中保留一个文件描述符空间。

④I/O系统在设备驱动列表中找到对应的CanOpen(CAN_DEV*PCAN_DEV,UBYTE*remainder,intflags),该驱动例程返回设备描述符的指针。

⑤I/O系统将设备描述符的指针存储在文件描述符列表的DeviceID,同时将对应的设备驱动号存储在文件描述符的Drivernum项。

最后I/O系统返回该描述符项的索引(即为fd)。

⑥这样应用程序中的read()和write()等函数调用就可以根据fd找到相应的设备驱动号,进而找到相应的驱动例程。

4CAN驱动程序的实现

CAN驱动程序的实现即是完成下面七个函数的编写。

下面简要介绍其完成的功能,并用伪指令进行说明。

intdrv_num;;/*驱动号码*/

typedefstruct{

DEV_HDRpCANHDR;/*这个数据结构必须放在设备描述符的最初部分*/

/*其余与驱动有关数据*/

}CAN_DEV;/*CAN设备描述符*/

CAN_DEVcan_chan_dev;

STATUSCanDrv(void){

完成驱动的一些初始化;

intconnect();/*连接所选的IRQ与中断处理函数*/

sysIntEnablePIC();/*486DX允许中断*/

drv_num=iosDrvInstall(CanOpen,NULL,CanOpen,CanClose,CanRead,CanWrite,CanIoctl);/*将设备驱动例程装入设备列表中*/

}

/*iosDrvInstall()将设备的CAN驱动例程加入设备驱动列表中,7个参数为7个驱动例程的进入点(entrypoint),如果没有某个例程,则传递NULL。

*/

STATUSCanDevCreate(){

完成一些设备初始化

iosDevAdd(&Can_chan_dev.pCANHDR,“can0”,drv_num);/*将设备放入设备驱动列表中*/

}

intCanOpen(CAN_DEV*pCan_Dev,UBYTE*remainder,intflags){

CAN卡硬件复位

CAN卡关中断

CAN卡进入软件复位模式

设置CAN卡工作寄存器,如接收码寄存器和屏蔽码寄存器等

CAN卡开中断和进入操作模式

Return((int)pCan_Dev);/*注意必须返回设备描述结构指针*/

}

intCanRead(intCAN_DEV_ID,UBYTE*buf,intnBytes){

等待信号量(该信号量由中断处理例程释放)

从接收缓冲区读取数据

释放接收缓冲

返回接收数据数量

}

intCanWrite(intCAN_DEV_ID,UBYTE*buf,intnbyte){

查询发送缓冲是否可用

向发送缓冲区写数据

命令发送

查询发送完成标志

返回发送数据数量

}

voidinterrupt_handle_routin(intarg){

处理中断事件

发送(释放)信号量

}

限于篇幅,其它函数略。

图3I/O系统整体结构

5CAN驱动调试

硬件驱动的调试是件十分麻烦的事,经验十分重要。

这里简要介绍几个帮助调试的函数。

①可以调用iosDrvShow()、iosDevShow()及iosFdShow()查看相关内容,判断并将驱动及设备中入相应列表。

②使用logMsg()现实相关内容,以定位错误。

初期调试,示波器和信号灯是非常有用的,可以确定硬件的工作状况,从而有助于发现程序中的错误。

6小结

笔者采用两种方式完成了CAN卡驱动。

相对于第一种(笔者亦完成),第二种方式——VxWorks的I/O系统将设备程序作为内核过程实现,大大减少了系统的开销,实时性和可靠性有了很大的提高,并且为用户提供了统一的接口,使用十分方便。

开发驱动程序,辅助工具是非常有用的。

Windows下的开发工具就比较多,而在VxWorks下开发驱动的工具相对较少。

Windriver是一款不错的开发工具,可以开发VxWorks下的驱动程序(也可以开发其它操作系统下的驱动程序)。

正确、熟练地使用这些辅助工具,会使开发工作事半功倍。

μC/OS-II在凌阳单片机SPCE061A上的移植

文章作者:

张利桑伟张立

文章类型:

设计应用文章加入时间:

2003年11月11日15:

17

文章出处:

单片机及嵌入式系统应用

   摘要:

以凌阳单片机为例详细介绍μC/OS-II的移植方法;重点讲解在系统移植过程中一些难以理解的概念,并首次实现了μC/OS-II在凌阳SPCE061A单片机上的移植。

   关键词:

μC/OS-II凌阳单片机嵌入式系统

  目前,实时操作系统已广泛应用于工业控制的各个领域。

μC/OS-II作为一个实时内核,由于其源码公开、代码规范,广受开发人员的喜爱。

SPCE061A是凌阳公司继μ’nSPTM系列产品SPCE500A等之后新推出的一款16位单片机,内部集成A/D、D/A等多种接口电路,能很方便地嵌入工业控制的各种场合。

更重要的是,其内嵌2K字的SRAM和32K的FlashROM,因此,在不需要扩展外部存储器的情况下就可以实现μC/OS-II系统的移植。

1μC/OS-II实时操作系统介绍

  μC/OS-II是一种专门为微控制器设计的抢占式实时多任务操作系统,它以源代码的形式给出。

其内核主要提供进程管理、时间管理、内存管理等服务。

系统最多支持56个任务,每个任务均有一个独有的优先级。

由于其内核为抢先式,所以总是处于运行态最高优先级的任务占用CPU。

系统提供了丰富的API函数,实现进程之间的通信以及进程状态的转化。

2μC/OS-II系统结构分析与移植

  μC/OS-II的软件体系结构如图1所示。

从图1中可以看到,如果要使用μC/OS-II,必须为其编写OS_CPU.H、OS_CPU_C.C、OS_CPU_A.ASM三个文件。

这三个文件是与芯片的硬件特性有关的,它们主要提供任务切换与系统时钟的功能。

其它文件用C写成,它们为系统提供任务管理、任务之间通信、时间管理以及内存管理等功能。

  众所周知,μC/OS-II是一个多任务操作系统。

既然是多任务,就需要解决任务切换的问题。

任务切换是在进行系统移植过程需要解决的最主要的问题。

由于任务切换涉及到对芯片寄存器的操作,所以它主要用汇编语言写成,因此,对于不同的单片机,其任务切换的代码是不同的;但是只要理解其原理,就能举一反三,以不变应万变。

下文将重点讲解任务切换的原理。

多任务系统在运行时每个任务好像独立占用CPU一样,因此系统必须为每个任务开辟一块内存空间作为该任务的任务堆栈。

该堆栈的作用是保存任务被切换前时CPU各寄存器的值以及系统堆栈的数据。

根据以上讨论,可总结出在进行任务切换时需要完成的工作,主要步骤如下:

  ①将当前任务CPU所有的寄存器压栈;

  ②将CPU系统堆栈的数据全部拷贝到当前任务的任务堆栈中;

  ③得到下一个处于运行态优先级最高的任务的任务堆栈的指针;

  ④恢复下一个任务的CPU寄存器的值;

  ⑤恢复下一个任务的系统堆栈中的数据;

  ⑥通过中断返回指令或函数返回指令,间接修改PC寄存器的值来进行任务切换。

  在为μCOS-II编写任务切换代码时需要注意的是:

μCOS-II在每次发生中断后都会产生任务调度,但在中断结束后进行的任务切换,不能调用普通任务切换函数,这是因为在中断过程中往往伴随将CPU的状态寄存器压栈操作。

以凌阳单片机为例,在中断后,芯片将PC和SR寄存器的值压入堆栈,因此,在中断结束后进行的任务切换中必须对堆栈指针进行调整。

  在系统移植过程中另一个较为重要的部分是系统时钟。

μCOS-II要求系统能产生10~100Hz的时钟节拍。

该时钟节拍由硬件定时器产生。

仍以凌阳单片机为例,可选用时基信号TMB2产生128Hz中断,作为系统时钟节拍的产生源。

系统时钟中断服务子程序用汇编语言写成,由于其主要功能在用C编写的子函数中实现,因此,编写该服务子程序的难度不大。

3μC/OS-IIBSP代码的编写

  BSP(板级支持包)是介于底层硬件和操作系统之间的软件层,它对底层硬件进行封装,使得操作系统不再面对具体的硬件。

我们以凌阳SPACE061A单片机为例介绍BSP代码的编写。

3.1任务切换

  凌阳SPACE061A单片机有R1~R5五个通用寄存器,还有1个SR(CPU状态寄存器),再加上PC,总共有7个CPU内部寄存器在任务切换时需要保存。

μCOS-II系统调用OSCtxSw()来实现任务的切换,下面给出其部分代码:

_OSCtxSw:

PUSHALL//将所有寄存器压栈

OSIntCtxSw_in:

//求出系统堆栈的长度,并将其存入R2

R1=SP

R2=OSStkStart

R1+=1

R2=R2-R1

R1=[_OSTCBCμγ]//R1≤OSTCBStkPtr,R1为任

//务堆栈的头指针

R1=[R1]//首先将系统堆栈长度保存在任

//务堆栈中

[R1]=R2

R3=OSStkStart//得到堆栈的起始地址

//保存系统堆栈到任务堆栈

save_stack:

R3-=1

R1+=1

R4=[R3]

[R1]=R4

R2-=1

JNZsave_stack

CALL_OSTaskSwHook

R1=[_OSTCBHighRdy]

[_OSTCBCur]=R1

R1=[_OSPrioHighRdy]

[_OSPrioCur]=R1

JMPOSCtxSw_in

3.2μCOS-II系统时钟

  以凌阳SPCE061A单片机的TMB2时基信号作为系统时钟,每经历一个时钟节拍的时间将产生一次中断,在中断服务子程序中会调用OSTickISR()函数,汇编代码如下:

_OSTickISR:

PUSHALL

R1=0x0001

testR1,[P_INT_Ctrl]

JZOUT

R1=0x0001

[P_INT_Clear]=R1

CALL_OSIntEnter

CALL_OSTimeTick

CALL_OSIntExit

OUT:

R1=0x0001

[P_INT_Clear]=R1

POPALL

RETI

结语

  RTOS是当今嵌入式应用的热点。

应用RTOS,可以提高产品的可靠性,降低研发周期。

μCOS-II具有很好的实时性和很小的代码量,因此掌握μCOS-II的移植方法是相当重要的。

本文移植修改的源代码请参见本刊网络补充版()。

μC/OS-II在凌阳单片机SPCE061A上的移植

文章作者:

张利桑伟张立

文章类型:

设计应用文章加入时间:

2003年11月11日15:

17

文章出处:

单片机及嵌入式系统应用

   摘要:

以凌阳单片机为例详细介绍μC/OS-II的移植方法;重点讲解在系统移植过程中一些难以理解的概念,并首次实现了μC/OS-II在凌阳SPCE061A单片机上的移植。

   关键词:

μC/OS-II凌阳单片机嵌入式系统

  目前,实时操作系统已广泛应用于工业控制的各个领域。

μC/OS-II作为一个实时内核,由于其源码公开、代码规范,广受开发人员的喜爱。

SPCE061A是凌阳公司继μ’nSPTM系列产品SPCE500A等之后新推出的一款16位单片机,内部集成A/D、D/A等多种接口电路,能很方便地嵌入工业控制的各种场合。

更重要的是,其内嵌2K字的SRAM和32K的FlashROM,因此,在不需要扩展外部存储器的情况下就可以实现μC/OS-II系统的移植。

1μC/OS-II实时操作系统介绍

  μC/OS-II是一种专门为微控制器设计的抢占式实时多任务操作系统,它以源代码的形式给出。

其内核主要提供进程管理、时间管理、内存管理等服务。

系统最多支持56个任务,每个任务均有一个独有的优先级。

由于其内核为抢先式,所以总是处于运行态最高优先级的任务占用CPU。

系统提供了丰富的API函数,实现进程之间的通信以及进程状态的转化。

2μC/OS-II系统结构分析与移植

  μC/OS-II的软件体系结构如图1所示。

从图1中可以看到,如果要使用μC/OS-II,必须为其编写OS_CPU.H、OS_CPU_C.C、OS_CPU_A.ASM三个文件。

这三个文件是与芯片的硬件特性有关的,它们主要提供任务切换与系统时钟的功能。

其它文件用C写成,它们为系统提供任务管理、任务之间通信、时间管理以及内存管理等功能。

  众所周知,μC/OS-II是一个多任务操作系统。

既然是多任务,就需要解决任务切换的问题。

任务切换是在进行系统移植过程需要解决的最主要的问题。

由于任务切换涉及到对芯片寄存器的操作,所以它主要用汇编语言写成,因此,对于不同的单片机,其任务切换的代码是不同的;但是只要理解其原理,就能举一反三,以不变应万变。

下文将重点讲解任务切换的原理。

多任务系统在运行时每个任务好像独立占用CPU一样,因此系统必须为每个任务开辟一块内存空间作为该任务的任务堆栈。

该堆栈的作用是保存任务被切换前时CPU各寄存器的值以及系统堆栈的数据。

根据以上讨论,可总结出在进行任务切换时需要完成的工作,主要步骤如下:

  ①将当前任务CPU所有的寄存器压栈;

  ②将CPU系统堆栈的数据全部拷贝到当前任务的任务堆栈中;

  ③得到下一个处于运行态优先级最高的任务的任务堆栈的指针;

  ④恢复下一个任务的CPU寄存器的值;

  ⑤恢复下一个任务的系统堆栈中的数据;

  ⑥通过中断返回指令或函数返回指令,间接修改PC寄存器的值来进行任务切换。

  在为μCOS-II编写任务切换代码时需要注意的是:

μCOS-II在每次发生中断后都会产生任务调度,但在中断结束后进行的任务切换,不能调用普通任务切换函数,这是因为在中断过程中往往伴随将CPU的状态寄存器压栈操作。

以凌阳单片机为例,在中断后,芯片将PC和SR寄存器的值压入堆栈,因此,在中断结束后进行的任务切换中必须对堆栈指针进行调整。

  在系统移植过程中另一个较为重要的部分是系统时钟。

μCOS-II要求系统能产生10~100Hz的时钟节拍。

该时钟节拍由硬件定时器产生。

仍以凌阳单片机为例,可选用时基信号TMB2产生128Hz中断,作为系统时钟节拍的产生源。

系统时钟中断服务子程序用汇编语言写成,由于其主要功能在用C编写的子函数中实现,因此,编写该服务子程序的难度不大。

3μC/OS-IIBSP代码的编写

  BSP(板级支持包)是介于底层硬件和操作系统之间的软件层,它对底层硬件进行封装,使得操作系统不再面对具体的硬件。

我们以凌阳SPACE061A单片机为例介绍BSP代码的编写。

3.1任务切换

  凌阳SPACE061A单片机有R1~R5五个通用寄存器,还有1个SR(CPU状态寄存器),再加上PC,总共有7个CPU内部寄存器在任务切换时需要保存。

μCOS-II系统调用OSCtxSw()来实现任务的切换,下面给出其部分代码:

_OSCtxSw:

PUSHALL//将所有寄存器压栈

OSIntCtxSw_in:

//求出系统堆栈的长度,并将其存入R2

R1=SP

R2=OSStkStart

R1+=1

R2=R2-R1

R1=[_OSTCBCμγ]//R1≤OSTCBStkPtr,R1为任

//务堆栈的头指针

R1=[R1]//首先将系统堆栈长度保存在任

//务堆栈中

[R1]=R2

R3=OSStkStart//得到堆栈的起始地址

//保存系统堆栈到任务堆栈

save_stack:

R3-=1

R1+=1

R4=[R3]

[R1]=R4

R2-=1

JNZsave_stack

CALL_OSTaskSwHook

R1=[_OSTCBHighRdy]

[_OSTCBCur]=R1

R1=[_OSPrioHighRdy]

[_OSPrioCur]=R1

JMPOSCtxSw_in

3.2μCOS-II系统时钟

  以凌阳SPCE061A单片机的TMB2时基信号作为系统时钟,每经历一个时钟节拍的时间将产生一次中断,在中断服务子程序中会调用OSTickISR()函数,汇编代码如下:

_OSTickISR:

PUSHALL

R1=0x0001

testR1,[P_INT_Ctrl]

JZOUT

R1=0x0001

[P_INT_Clear]=R1

CALL_OSIntEnter

CALL_OSTimeTick

CALL_OSIntExit

OUT:

R1=0x0001

[P_INT_Clear]=R1

POPALL

RETI

结语

  RTOS是当今嵌入式应用的热点。

应用RTOS,可以提高产品的可靠性,降低研发周期。

μCOS-II具有很好的实时性和很小的代码量,因此掌握μCO

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1