3 design and implementation of micro-drive
The micro-drive in the class/micro drive model directly controls the external device. As long as the micro-drive creates the specified function, the application can be easily invoked via the DIO adapter module, the PIO adapter module, or the (and) Gio class driver. These specified functions include channel-bound functions (MD-BINDDEV), channel creation/deletion functions (Mdcreatechan/md-deletechan), I/O request-sending functions (Mdsubmitchan), Interrupt service functions (ISRs), and device control functions (Mdcontrolchan). These specified functions will be placed in the corresponding position in the micro-driven Function Interface table (IOM_FXNS) for applications to be invoked through the adapter module or the Gio class driver. The structure of the Function interface table is as follows:
typedef struct IOM_FXNS
{
Iom_tmdbinddev Mdbinddev;
Iom-tmdunbinddev Mdunbinddev;
Iom-tmdcontrolchan Mdcontrolchan;
Iom_tmdcreatechan Mdcreatechan;
Iom_tmddeletechan Mddeletechan;
Iom_tmdsubmitchan Mdsubmitchan;
}iom_fxns;
3. 1 Bound channel functions
When the Dsp/bios device is initialized, each bound function (Mdbinddev) that is registered to the micro-drive is invoked. Binding functions typically implement the following functions: Initializing peripherals based on configured device parameters and possible global device data, suspending the interrupt service function (ISRs), and obtaining resources such as caching, Mcbsps, Mcasps, and DMA.
If the micro-drive uses multiple external devices, the Dsp/bios calls the binding function for each peripheral. The device parameter devid is used to differentiate devices. If a device is supported, the binding function must check if a device binding is already in existence.
Micro-drive Use the input/output data pointer (DEVP) If you use static data to reduce dynamic data allocations for real-time processing. The input/output data pointer is passed to the channel creation function (Mdcreatechan).
3. 2 channel creation/deletion function
From an application standpoint, there must be a logical communication channel between the application and the external device to exchange data. The application creates one or more logical channel objects through a micro-drive as the logical channel for the application. The channel creation function (Mdcreatechan) creates the channel object as needed and sets the initial value to the channel object. The channel deletion function (Md-deletechan) deletes the created channel object. Although each micro-driven channel object data structure is slightly different, some fields are required, such as channel mode, waiting I/O package sequences, and callback functions. The following is a common channel object data structure:
typedef struct CHANOBJ {
Bool inuse/* If true, the channel is open/*
INT Mode/* Channel mode/*
Iom_packet *datapacket;/*I/O Pack * *
Que_obj pendlist,/* waiting I/o packet sequence * *
Uns *bufptr/* Current cache pointer/*
Uns bufcnt/* Unhandled Cache number * *
Iom_tiomcallback CBFXN/* Callback function * *
PTR cbarg/* Callback function parameter Address * *
}chanobj,*chanhandle;
3. 3 I/O request send function
The I/O request send function (Mdsubmitchan) in the micro-drive is used to process the command fields in the Iom_packet package. Depending on the command field, the micro-drive will process the command or return an error message (IOM_ENOTIMPL).
The micro-drive supported command fields are: Iom_read, Iom_write, Iom_abort, and Iom_flush. The input channel created by the micro-drive executes the input task by the Iom_read command, and the output channel created by the Iom_write command performs the output task. To discard or refresh an I/O request that has been sent, you can use the Iom_bort or IOM flush command. When discarded, all input and output requests in the I/O request package queue are discarded. When refreshed, all I/O output packets are executed sequentially, and all input I/O packages are discarded.
3. 4 Interrupt Service function
The micro-driven interrupt function is to handle trigger events for external devices, such as periodic interrupts. Interrupts usually indicate that the peripheral has sampled or processed data, or can be used to provide synchronous signals for DMA, and the micro-drive must handle these interrupts. Typically, interrupt service functions in micro-drive ISRs must complete the following functions: Column Iom_packet request, set next transfer or service request, call class-driven callback function to ensure synchronization with the application, and return to Iom_packet.
3. 5 Device Control function
The control operations supported by micro-drive vary depending on the external device. IOM defines a number of common control codes for driver invocation. The control code unique to a particular device must be written by itself, and its eigenvalues must be greater than 128 (Iom_cntl_user). The common code of control currently supported by IOM is:
Iom_chan_reset: Restores the created channel instance back to its original state.
Iom_chan timedout: This control code will timeout when an application or class driver times out. For example, a timeout iom_packet may be driven by a return class if the callback function is not executed.
Iom_device_rese: The external device is restored to its original state, which affects all channel instances created for this external device.
The control code and control operations supported by the micro-drive must tell the application developer who uses the micro-driver, particularly to indicate whether the code is targeted to the object (for channel instances or device instances). For example, the control code that changes the baud rate of a peripheral must be specified for a channel or all channels, or it may easily cause errors to the application.
4 class/Micro Drive model Driver application Example--C64X series Dsp/bios PCI device driver
4. 1 design and compilation of micro-drive
(1) Design Mdbinddev part of the program code:
Static Int Mdbinddev (Ptr *devp,int devid,ptr devparams)
{
......
Que_new (&device. Hishprioque)/* Set up IOM package queue * *
Que_new (&device. Lowprioque);
......
Hwiattrs. Ccmask=irqask_none;
/* Initialize PCI interrupt/*
Hwiattrs. Arg=null;
Irq_map (1rq_evidspint,intrld);
Hwi_dispatchplug (Intrid, (FXN) isr,-1,&hwiattrs);
}
(2) Design Mdcreatechah part of the program code
Static Int Mdcreatechan (Ptr *chanp,ptr devp,string name,
Int mode,ptr Chanparams,iom_tiom
Callback cbfxn,ptr Cbarg)
{
......
Chan=mem_alloc (0,sizeof (Chanobj), 0);
Chan->queue=&device. Hghprioque;
/* Channel Initialization * *
......
if (device. opencount==0) {
Pci_intenable (Pci_evt_pcimaster);
/*PCI device interrupt initialization. */
......
Irq_enable (Irq_evt_dspint);
}
*chanp=chan/* Return to create Channel * *
}
(3) Design Mdsubmitchan part of the program code
Static Int Mdsubmitchan (Ptr chanp,iom_packet *ppacket)
{
Chanhandle chan= (chanhandle) CHANP;
/* Mount created channel * *
......
Req= (c64xx_pci_request*) packet->addr;
/*I/O Request Package Address * *
req->reserved=chan;
......
/* processing read and write request package * *
if (packet->cmd==iom_read‖packet->cmd==
Iom_write) {
Imask=hwi_disable ();
Que_enqueue (Chan->queue,packet)
......
}
... * * Request package to handle other functions
Removepackets (Chan,packet->cmd);
/* Remove processed request Packages * *
}
The structure of the Interrupt service function (ISRs) and the Device control function (Mdcontrolchan) is similar to the structure of the I/O request send function (Mdsubmitchan), which is no longer described in this article.
4. 2 Registration of micro-drive in Dsp/bios
Open the Dsp/bios Configuration tool, as shown in Figure 3. Right-click the User-defined devices icon, select the Insert option, and rename it to Pcichan. Right-click Pcichan, select the Properties option, and register as shown in Figure 4.
4. 3 Writing class Driver
The class driver of this example uses the generic input output module, first right click on the Gio Manager in Figure 3, select Start Gio. In the application, the Gio_create function uses a micro-drive Pcichan to create a channel instance that completes the application's read and write operations to the PCI device by calling the Gio_submit function. The source code is as follows:
(1) Create channel
Cio-handle Pcichan;
C64xx_pci_attrs Pcichanparam;
C64xx_pci_request pcichanrequest;
C64xx_pci_devparams Pcichandevparam;
Gio_appcallback Pcichancallback;
Pcichan=gio_create ("/pcichan", iom_inout,&status,null,null);
(2) Send read request package
Pcichanrequest. Srcaddr= (PTR) Bitsbuffer;
Pcichanrequest. Dstaddr= (PTR) M_dspcontrol. CSTARTADDR;
Pcichanrequest. bytecnt=length+20;
Pcichanrequest. Options=pci_write;
Pcichanreqsize=sizeof (pcichanrequest);
Status=gio_submit (Pcichan,iom_write,&pcichanre-quest,&pcichanreqsize,null);
Through the above three steps, the Dsp/bios drive design of PCI device is basically finished. Applications can use a class-driven rifle to use PCI devices, which greatly improves drive productivity and simplifies the control of PCI peripherals.