vxWorks driver architecture

The structure of the driver includes three parts: initialization part, function part and interrupt service routine ISR. The initialization part initializes the hardware, allocates the resources required by the device, and completes all system-related settings. If it is a character device, first call iosDrvlnstall() to install the driver, hang the interrupt vector and ISR, and then call iosDevAdd() to add the driver to the IO system: if it is a block device, first hang the interrupt vector and ISR above, allocate a device structure in memory, and then initialize the structure. When the user wants to use the device, first call the device initialization part myInit() (usually placed in sysLib.C), and then call the device creation function myDevCreate() to return a pointer to a BLK_DEV structure for file system initialization functions such as
dosFsDevInit(). . The following is the initialization sample code of the block device:
struct MyDevice{ //custom device structure
BLK_DEV dev; must be at the beginning of the structure
Int interrupt; the interrupt number used by the device
....
}
int mylnit(){ //initialization function
MyDevicelnit ();//Hardware initialization function
MyDevice* Device =(MyDevice*)malloc(sizeof(MyDevice));
//Allocate memory for device structure
Device->dev. bd_blkRd = Read;//Initialize the device structure
Device->dev_blkWrt=Write;
intConnect(imToVec(9), my_ISR);//Connect the interrupt vector and interrupt service routine ISR
)
  The ISR handles hardware interrupts, manages specific hardware input and output, and communicates with the rest of the driver. The first instruction in the ISR is used to read the interrupt service register of the APIC to notify the CPU that an interrupt request has been received.
my_ISR(int va1)//Interrupt interrupt service function
sysOutByte(0xa0, 0x02);//Interrupt response
.....
semGive(my_sem);//Notify other programs that the interrupt processing is completed
}
   The function function part completes the function specified by the system, For character devices, these functions are the specified 7 standard functions; for block devices, they are the function functions specified in the BLK_DEV or SEQ_DEV structure. It should be noted that when the system calls the block standard function, the device structure pointer passed is the pointer to the BLK_DEV structure in the device structure. Since BLK_DEV is defined at the beginning of the device structure, the pointer is actually the device structure pointer.
STATUS Read (MyDevice* pDev, int startBlk, int numBlk, char*pBuf)
{
........
SemTake(my sem, WAI1 OREVER); //Wait for the completion of the device IO execution

)


Vxworks kernel driver basic structure:
Three tables: 1. System device table 2. System driver table 3. File descriptor table

    Vxworks internally uses the DEV_HDR data structure to represent each device:
Typedef struct
{
   DL_NODE node;
   Short      drvnum;
   Char       *name;
}
    该结构中给出了链接指针(用以将该结构串入队列中)、驱动索引号、设备节点名称。内核提供这个结构较为简单,只存储了一些设备的关键信息。底层驱动对其驱动的设备都有一个自定义数据结构表示,其中包含了驱动设备寄存器基地址,中断号,可能的数据缓冲区,保存内核回调函数的指针,以及一些标志位。最关键的一点是DEV_HDR必须是自定义数据结构的第一个成员变量,因为这个用户自定义结构最后需要添加到系统设备队列中,必须能够在用户定义结构与DEV_HDR结构之间进行转换,而将DEV_HDR结构设置为用户自定义结构的第一个成员变量就可以达到目的。

typedef struct
{
       DEV_HDR     pFCcardHdr;
       BOOL        created;
       char *      buf_virts;
       UINT32      iobase;
       UINT32      membase;
       char        irq;
       UINT32      irqvec;
       UINT32      Bus;
       UINT32      Device;
       UINT32      Func;
}DRV_CTRL;

    系统提供了iosDevAdd(DEV_HDR *pDevHdr, char *name, int drvnum)用于驱动程序调用注册一个设备。第三个参数是设备对应的驱动程序索引号。这个驱动号是iosDrvInstall函数的返回值,在设备初始化函数中,我们首先调用iosDrvInstall注册驱动,然后使用iosDrvInstall 函数返回的驱动号调用 iosDevAdd添加设备到系统中通过这两步设备就可以被用户程序使用了。
    用户调用open函数打开一个设备文件时,系统将以传入的文件路径名匹配系统设备的设备节点名,匹配方式是最佳匹配。
 
系统驱动表:
    系统驱动表包含了当前注册到I/O子系统下的所有驱动。这些驱动可以直接驱动硬件工作的驱动层。系统驱动表底层实现是一个数组,数组元素数目在内核初始化过程中指定。I/O子系统提供iosDrvInstall供驱动程序注册,iosDrvInstall原型如下:
Int iosDrvInstall
(
  FUNCPTR  pCreate,   FUNCPTR  pDelete,  
  FUNCPTR  pOpen,    FUNCPTR  pClose,  
  FUNCPTR  pRead,   FUNCPTR  pWrite,  FUNCPTR  pIoctl /*pointer to driver ioctl function*/
)

    一个设备驱动在初始化过程中一方面完成硬件设备寄存器配置,另一方面就是向I/O子系统注册驱动和设备。一个驱动并不需要实现上述所有函数,无须实现的函数直接传递NULL指针就可以了。iosDrvInstall 函数的基本实现即遍历drvTable数组,查询一个空闲表项,用传入的函数地址对各成员变量进行初始化。
 
系统文件描述符表
    文件描述符表表项索引被用做文件描述符ID,即open函数返回值。对于文件描述符,需要注意:标准输入、标准输出、标准错误输出虽然使用0,1,2三个文件描述符,但是可能在系统文件描述符表中只占用一个表项,即都使用同一个表项。Vxworks内核将0,1,2三个标准文件描述符与系统文件描述符表中的内容分开进行管理。
    系统文件描述符中的内容主要是针对硬件设备,使用一次open函数调用就占用一个表项:
int fd = open(DevName, 2,0);

    应用程序每调用一次open函数,系统文件描述符表中就增加一个有效表项,直到数组满为止。此时open函数调用将以失败返回,因此注意如果需要反复打开设备的话,一定要在设备不用的时候调用close函数关闭该描述符指向的设备,并在每次调用open函数之后检查返回的文件描述符是否合法。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326162757&siteId=291194637