| LAT Communication Board Driver: Software Architecture and Interfaces | ||
|---|---|---|
| Prev | Chapter 2. Interrupt Mode Driver | Next |
As shown in Figure 2-1 and Figure 2-3 the LCBD routes unsolicited data based upon the LATp protocol. This implies an interface by which the user registers a handler for a particular LATp protocol.
Once the handler is invoked the user needs interfaces for navigating the unsolicited data and for freeing the circular buffer memory used by the unsolicited data.
The LCBD provides an interface for registering a default unsolicited data handler in addition to registering handlers based on specific LATp protocol. The declaration of a call back handler is shown below:
The declaration of the registration function for the default call back handler is shown below:
The declaration of the registration function for the LATp source address call back handler is shown below:
The user needs a way to navigate the unsolicited data inside of the call back handler. From the LCB_msg item the user can extract the following information about the unsolicited data:
Data Length
Error Status
LATp Cell Header
Pointer to bulk data
The LCB_msg structure is defined below:
typedef struct __LCB_msg {
unsigned short error;
unsigned short length;
unsigned short cellHeader;
unsigned short reserved1;
unsigned int bulkData[];
} LCB_msg;
unsigned short err = msg->error;
unsigned short len = msg->length;
unsigned short ch = msg->cellHeader;
unsigned int *data = msg->bulkData;
|
Alternatively the details of the above structure could remain hidden and inlined GET methods used instead:
The unsolicited data arrives in a circular buffer managed by the LCB (write pointer) and the LCBD (read pointer). Within the handler function the user controls when the unsolicited data is freed by calling the LCB_msgFree() routine shown below.
It is important that the user return the memory to the circular buffer as quickly as possible. If the user operation will "take a long time" the user is obligated to make a copy of the unsolicited data and return the unsolicited data memory immediately. It remains to be seen what "a long time" is.
Below is an example of a quick handler:
int my_LCB_HandlerQuick( LCB_msg *msg, void *usrData) {
int status = OK;
if ( msg->error) {
status = msg->error;
}
else {
// our processing is quick, so just do it
status = processData( usrData, msg->bulkData);
}
// free unsolicited data
LCB_msgFree( msg);
return status;
}
|
Below is an example of a slow handler, which makes a copy of the unsolicited data.
int my_LCB_HandlerSlow( LCB_msg *msg, void *usrData) {
int status = OK;
if ( msg->error) {
// free unsolicited data
status = msg->error;
LCB_msgFree( msg);
}
else {
// our processing is slow, so make a copy using memcpy.
// copy data to previously allocated memory, pointed to
// by the "copy_mem" pointer.
memcpy( copy_mem, (void *)msg, msg->length);
// free the unsolicited data
LCB_msgFree( msg);
// process the copy
status = processData( usrData, copy_mem);
}
return status;
}
|