如何编写vxworks的驱动程序,这个问题要好好想想
1,drv
硬件手册,--主要芯片寄存器;--工作流程;--中断方式;--数据发送方式;--初始化顺序。尤其要注意板卡有很多种工作模式。 板卡的主要功能;寄存器的分类(具体的数量);
NI,TNT4882提供一个单芯片Talker/Listener 接口到GPIB。电路上/寄存器上包含(1)Turbo488 ASIC(2)NAT4882 IEEE 488.2 ASIC。后者又包含NEC mPD7210 和 TI TMS9914A寄存器。为了快速传递数据包括(1)FIFO缓冲器(2)HS488功能电路。
CPU接口特性/总线接口特性
• FIFO缓冲器,• Byte-to-word 压缩解压,• DMA接口(– Cycle steal– Burst– Time limited),• 32-bit 内部传输字节计数器,特殊的最后字节电路减少软件过载,• Interrupts(– Interrupts can be individually enabled and cleared– Many interrupting conditions are available),• Programmable timer interrupts for general-purpose timing use,• Device-status indicator pins///• On-chip ISA interface glue circuitry,• Generic interfacing to other buses
三种工作结构/内在的硬件结构
(1)one-chip mode,(2)Turbo+7210 mode, (3)Turbo+9914 mode. 结构决定那一套寄存器及其位对主机接口起作用, 以及 FIFOs如何和GPIB接口.
数据发送方式
7210:写数据到GPIB时, 主机接口写数据到TNT4882的FIFO。一个传输状态机传输数据,从FIFO到NAT4882电路,然后 NAT4882 电路通过GPIB发送数据。从GPIB读数据时,NAT4882电路从GPIB读字节,传输状态机传输数据,从NAT4882到FIFO,然后主机接口从FIFO读取数据。9914:和7210相像。one-chip mode:直接连接到GPIB端口,无需传输状态机。
address map/interface register
one-chip mode/tubor+7210 mode,register;0~1F,共32个字节;16个Read;21个Write;8个R/W;有的寄存器读写属性是分开的,有的只能写(5-ACCWR,7-INTR,D-HSSEL,13-HIER,15-MISC),有的寄存器读写是一样的属性。(如何分辨,是否ISA模式)
generic Pin/ISA Pin
The information in this chapter supplements the information contained in the TNT4882 Single-Chip IEEE 488.2 Talker/Listener ASIC data sheet.
vxworks驱动程序
基本框架--字符设备驱动程序,模板;首先系统启动代码调用驱动程序安装函数,该函数通过函数安装驱动程序,然后启动代码将调用设备创建函数创建设备,该函数通过调用函数为系统创建设备。经过上述操作后,用户可以调用vxworks的标准io接口函数对设备进行操作,例如打开、关闭、读,写等,不过这些操作最终由驱动程序完成。
设备描述符结构
LOCAL int gpibDrvNum=0;
typedef struct
{
DEV_HRD devHdr;
BOOL isCreat;
BOOL isOpen;
UINT32 RegMEMBase;
UINT32 ioAddr;
...
SEL_WAKEUP_LIST selWakeupList;
BOOL ReadyToRead;
BOOL ReadyToWrite;
}
gpib_DEV;
设备驱动程序装载函数
STATUS gpibDrv()
{
if(gpibDrvNum>0)
return(OK);
...
if((gpibDrvNum=iosDrvInstall(gpibOpen,NULL,gpibOpen,gpibClose,gpibRead,gpibWrite,gpibIoctl))==ERROR)
{
return(ERROR);
}
return(OK);
}
设备创建函数
STATUS gpibDevCreat(char * devName)
{
gpib_DEV *pgpibDev;
if(gpibDrvNum<1)
{
errno=S_ioLib_NO_DRIVER;
return(ERROR);
}
if((pgpibDev=(gpib_DEV *)malloc(sizeof(gpibDev)))==NULL)
return(ERROR);
bzero(pgpibDev,sizeof(gpib_Dev));
selWakeupListInit(&pgpib->selWakeupList);
...
if(iosDevAdd(&pgpibDev->devHdr,devName,gpibDrvNum)==ERROR)
{
free((char *)pgpibDev);
return(ERROR);
}
return(OK);
}
打开函数
读函数
写函数
io控制函数
设备关闭函数
int gpibClose(int gpibDevId)
{
gpib_Dev* pgpibDev=(gpib_DEV*)gpibDevId;
if(pgpibDev==(gpib_DEV *)NULL)
{
errnoSet(S_gpib_NOMEM);
return(ERROR);
}
.../*设备相关操作*/
.../*释放相关资源*/
free(pgpibDev);/*释放资源*/
}
卸载设备函数
STATUS gpibDelete(char *devName)
{
DEV_HDR *pDevHdr;
char * pNameTail;
pDevHdr=iosDevFind(devName,&pNameTail);/*查找设备*/
if(pDevHdr==NULL||*pNameTail!='/0')
return(ERROR);
.../*释放设备所占用资源,例如:信号量、唤醒等待该设备的任务等*/
iosDevDelete(pDevHdr);/*卸载设备*/
return(OK);
}
设备中断管理函数
LOCAL ULONG gpibIntHandler(int gpibDevId)
{
gpib_DEV* pgpibDev=(gpib_DEV*)gpibDevId;
.../*读取中断状态*/
pgpibDev->ReadyToRead=TRUE;/*如果可以接收*/
pgpibDev->ReadyToWrite=FALSE;
.../*清除相应中断*/
}
板卡初始化流程
芯片初始化,顺序如下:
1. 复位TNT4882的Turbo488电路.
2. 置TNT4882 为Turbo+7210模式. TNT4882 必须是Turbo+7210模式在你进行第三步之前.
3. 配置TNT4882 为one-chip mode.
4. Make sure that the local Power-On (pon) message is asserted.
5. Configure the TNT4882 for GPIB operation.
6. Clear the local pon message to begin GPIB operation.
2,dev
3,dbd
4,db
5,opi
6,从设计开始讨论整个流程