converted to msg driver format
This commit is contained in:
@@ -49,12 +49,16 @@
|
||||
#include <task_params.h>
|
||||
#include <module_types.h>
|
||||
#include <drvSup.h>
|
||||
#include <devSup.h>
|
||||
#include <dbDefs.h>
|
||||
#include <link.h>
|
||||
#include <callback.h>
|
||||
#include <fast_lock.h>
|
||||
|
||||
#include <drvMsg.h>
|
||||
#include <drvRs232.h>
|
||||
|
||||
static msgDrvBlock drv232Block;
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
@@ -62,103 +66,157 @@
|
||||
#define RSLINK_OPT VX_FP_TASK|VX_STDIO
|
||||
#define RSLINK_STACK 5000
|
||||
|
||||
static long report232(), init232(), qXact();
|
||||
static int rsTask();
|
||||
|
||||
static struct rsLink rsLink[NUM_TY_LINKS];
|
||||
|
||||
struct drvRs232Set drvRs232 = {
|
||||
3,
|
||||
report232,
|
||||
init232,
|
||||
qXact
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
report232()
|
||||
report()
|
||||
{
|
||||
printf("Report for R/S-232 driver\n");
|
||||
printf("Report for RS-232 driver\n");
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
/* static*/ long
|
||||
init232(parm)
|
||||
static long
|
||||
init(parm)
|
||||
int parm;
|
||||
{
|
||||
int link;
|
||||
|
||||
if (parm == 0)
|
||||
{
|
||||
link = 0;
|
||||
while (link < NUM_TY_LINKS)
|
||||
{
|
||||
rsLink[link].ttyFd = -1; /* set the link to INVALID */
|
||||
link++;
|
||||
}
|
||||
}
|
||||
printf("Init for RS-232 driver\n");
|
||||
return(OK);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is called to allocate any structures needed to hold
|
||||
* device-specific data that is added to the msgXact structure.
|
||||
*
|
||||
* It is also responsible for filling in the msgXact.phwpvt pointer.
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
genLink(link)
|
||||
int link;
|
||||
genXact(pparmBlock, plink, pmsgXact)
|
||||
msgParmBlock *pparmBlock;
|
||||
struct link *plink;
|
||||
msgXact *pmsgXact;
|
||||
{
|
||||
char name[20];
|
||||
long status;
|
||||
int j;
|
||||
long stat = ERROR;
|
||||
|
||||
printf("devRs232drv: genLink(%d)\n");
|
||||
printf("rs232-genXact entered\n");
|
||||
|
||||
/* Make sure link number is valid and that the link is not initialized */
|
||||
if (checkLink(link) != 1)
|
||||
return(ERROR);
|
||||
|
||||
/* init all the prioritized queue lists */
|
||||
for(j=0; j<RS_NUM_PRIO; j++)
|
||||
pmsgXact->phwpvt = pparmBlock->pmsgHwpvt;
|
||||
while ((pmsgXact->phwpvt != NULL) && (stat == ERROR))
|
||||
{
|
||||
rsLink[link].queue[j].head = NULL;
|
||||
rsLink[link].queue[j].tail = NULL;
|
||||
FASTLOCKINIT(&(rsLink[link].queue[j].lock));
|
||||
FASTUNLOCK(&(rsLink[link].queue[j].lock));
|
||||
if ((((dev232Link *)(pmsgXact->phwpvt->pmsgLink->p))->link == plink->value.gpibio.link)
|
||||
&& (((dev232Link *)(pmsgXact->phwpvt->pmsgLink->p))->port == plink->value.gpibio.addr))
|
||||
stat = OK;
|
||||
else
|
||||
pmsgXact->phwpvt = pparmBlock->pmsgHwpvt->next;
|
||||
}
|
||||
rsLink[link].txEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
rsLink[link].nukeEm = 0;
|
||||
if (stat != OK)
|
||||
{ /* Could not find a msgHwpvt for the right link, create a new one */
|
||||
if ((pmsgXact->phwpvt = drvMsg_genHwpvt(pparmBlock, plink)) == NULL)
|
||||
return(ERROR);
|
||||
}
|
||||
pmsgXact->finishProc = NULL;
|
||||
pmsgXact->psyncSem = NULL;
|
||||
|
||||
sprintf(name, "/tyCo/%d", link);
|
||||
if ((rsLink[link].ttyFd = open (name, O_RDWR, 0)) == -1)
|
||||
{
|
||||
printf("devRs232 can not open tty port %s\n", name);
|
||||
return(ERROR);
|
||||
}
|
||||
/* set to 9600 baud, unbuffered mode */
|
||||
(void) ioctl (rsLink[link].ttyFd, FIOBAUDRATE, 9600);
|
||||
(void) ioctl (rsLink[link].ttyFd, FIOSETOPTIONS, OPT_TANDEM | OPT_7_BIT);
|
||||
|
||||
sprintf(name, "RS232-%d", link);
|
||||
if (taskSpawn(name, RSLINK_PRI, RSLINK_OPT, RSLINK_STACK, rsTask, link) == ERROR)
|
||||
{
|
||||
printf("devRs232: Failed to start transmitter task for link %d\n", link);
|
||||
status = ERROR;
|
||||
}
|
||||
else
|
||||
status = OK;
|
||||
|
||||
if (status == ERROR)
|
||||
{
|
||||
close(rsLink[link].ttyFd);
|
||||
rsLink[link].ttyFd = -1;
|
||||
}
|
||||
|
||||
return(status);
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is called to allocate any structures needed to hold
|
||||
* device-specific data that is added to the msgHwpvt structure.
|
||||
*
|
||||
* It is also responsible for filling in the msgHwpvt.pmsgLink pointer.
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
genHwpvt(pparmBlock, plink, pmsgHwpvt)
|
||||
msgParmBlock *pparmBlock;
|
||||
struct link *plink; /* I/O link structure from record */
|
||||
msgHwpvt *pmsgHwpvt;
|
||||
{
|
||||
int stat = ERROR;
|
||||
printf("rs232-genHwpvt entered\n");
|
||||
|
||||
pmsgHwpvt->pmsgLink = drv232Block.pmsgLink;
|
||||
while ((pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR))
|
||||
{
|
||||
if ((((dev232Link *)(pmsgHwpvt->pmsgLink->p))->link == plink->value.gpibio.link)
|
||||
&& (((dev232Link *)(pmsgHwpvt->pmsgLink->p))->port == plink->value.gpibio.addr))
|
||||
stat = OK;
|
||||
else
|
||||
pmsgHwpvt->pmsgLink = pmsgHwpvt->pmsgLink->next;
|
||||
}
|
||||
if (stat != OK)
|
||||
{
|
||||
if ((pmsgHwpvt->pmsgLink = drvMsg_genLink(pparmBlock->pdrvBlock, plink)) == NULL)
|
||||
return(ERROR);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is called to allocate any structures needed to hold
|
||||
* device-specific data that is added to the msgLink structure.
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
genLink(pmsgLink, plink, opCode)
|
||||
msgLink *pmsgLink;
|
||||
struct link *plink;
|
||||
int opCode;
|
||||
{
|
||||
char name[20];
|
||||
|
||||
switch (opCode) {
|
||||
case MSG_GENLINK_CREATE:
|
||||
|
||||
if ((pmsgLink->p = malloc(sizeof(dev232Link))) == NULL)
|
||||
return(ERROR);
|
||||
|
||||
((dev232Link *)(pmsgLink->p))->link = plink->value.gpibio.link;
|
||||
((dev232Link *)(pmsgLink->p))->port = plink->value.gpibio.addr;
|
||||
|
||||
sprintf(name, "/tyCo/%d", plink->value.gpibio.addr);
|
||||
if ((((dev232Link *)(pmsgLink->p))->ttyFd = open(name, O_RDWR, 0)) != -1)
|
||||
return(OK);
|
||||
|
||||
free(pmsgLink->p);
|
||||
return(ERROR);
|
||||
|
||||
case MSG_GENLINK_ABORT:
|
||||
return(free(pmsgLink->p));
|
||||
}
|
||||
return(ERROR);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is called to verify the validity of the link information
|
||||
* given in a link.value structure (defined in link.h)
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
checkLink()
|
||||
{
|
||||
return(ERROR);
|
||||
}
|
||||
static long
|
||||
checkEvent(pdrvBlock, pmsgLink, pxact)
|
||||
msgDrvBlock *pdrvBlock;
|
||||
msgLink *pmsgLink;
|
||||
msgXact *pxact;
|
||||
{
|
||||
return(MSG_EVENT_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if FALSE
|
||||
/******************************************************************************
|
||||
*
|
||||
* Check to see if a link number is valid or not.
|
||||
@@ -175,177 +233,14 @@ int link;
|
||||
if ((link < 1) || (link >= NUM_TY_LINKS))
|
||||
return(-1);
|
||||
|
||||
if (rsLink[link].ttyFd == -1)
|
||||
if (rsLink[link] == NULL)
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
xactListAddHead(plist, pnode)
|
||||
struct xact232 *pnode;
|
||||
struct xactList *plist;
|
||||
|
||||
drv232Write()
|
||||
{
|
||||
pnode->prev = NULL;
|
||||
pnode->next = plist->head;
|
||||
|
||||
if (plist->head != NULL)
|
||||
plist->head->prev = pnode;
|
||||
|
||||
if (plist->tail == NULL)
|
||||
plist->tail = pnode;
|
||||
|
||||
plist->head = pnode;
|
||||
|
||||
return(0);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
xactListAddTail(plist, pnode)
|
||||
struct xact232 *pnode;
|
||||
struct xactList *plist;
|
||||
{
|
||||
pnode->next = NULL; /* No next node if this is the TAIL */
|
||||
pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */
|
||||
|
||||
if (plist->tail != NULL)
|
||||
plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */
|
||||
|
||||
if (plist->head == NULL)
|
||||
plist->head = pnode;
|
||||
|
||||
plist->tail = pnode; /* this is the 'new' tail node */
|
||||
|
||||
return(0);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
xactListDel(plist, pnode)
|
||||
struct xact232 *pnode;
|
||||
struct xactList *plist;
|
||||
{
|
||||
if (pnode->next != NULL)
|
||||
pnode->next->prev = pnode->prev;
|
||||
|
||||
if (pnode->prev != NULL)
|
||||
pnode->prev->next = pnode->next;
|
||||
|
||||
if (plist->head == pnode)
|
||||
plist->head = pnode->next;
|
||||
|
||||
if (plist->tail == pnode)
|
||||
plist->tail = pnode->prev;
|
||||
|
||||
return(0);
|
||||
}
|
||||
/******************************************************************************
|
||||
*
|
||||
* Transactions are all the same:
|
||||
* send string (0 to many bytes long) then, read back a response
|
||||
* string (0 to many bytes long w/optional terminator)
|
||||
*
|
||||
******************************************************************************/
|
||||
static long
|
||||
qXact(xact, prio)
|
||||
struct xact232 *xact;
|
||||
int prio;
|
||||
{
|
||||
int linkStat;
|
||||
|
||||
printf("xact(%08.8X): devRs232drv xact request entered\n");
|
||||
|
||||
if ((linkStat = checkLink(xact->link)) == -1)
|
||||
{
|
||||
xact->status = XACT_BADLINK;
|
||||
return(ERROR);
|
||||
}
|
||||
if (linkStat == 1)
|
||||
{
|
||||
if (genLink(xact->link) == ERROR)
|
||||
{
|
||||
xact->status = XACT_BADLINK;
|
||||
return(ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if ((prio < 0) || (prio >= RS_NUM_PRIO))
|
||||
{
|
||||
xact->status = XACT_BADPRIO;
|
||||
return(ERROR);
|
||||
}
|
||||
FASTLOCK(&(rsLink[xact->link].queue[prio].lock));
|
||||
xactListAddTail(&(rsLink[xact->link].queue[prio]), xact);
|
||||
FASTUNLOCK(&(rsLink[xact->link].queue[prio].lock));
|
||||
semGive(rsLink[xact->link].txEventSem);
|
||||
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Some code to use for testing purposes */
|
||||
int ttyFd;
|
||||
|
||||
int
|
||||
tst(port)
|
||||
int port;
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
sprintf(buf, "/tyCo/%d", port);
|
||||
ttyFd = open (buf, O_RDWR, 0);
|
||||
|
||||
/* set to 9600 baud, unbuffered mode */
|
||||
(void) ioctl (ttyFd, FIOBAUDRATE, 9600);
|
||||
(void) ioctl (ttyFd, FIOSETOPTIONS, OPT_TANDEM | OPT_7_BIT);
|
||||
|
||||
printf("opened %s, fd = %d\n", buf, ttyFd);
|
||||
}
|
||||
|
||||
int
|
||||
wr(str)
|
||||
char *str;
|
||||
{
|
||||
return(write(ttyFd, str, strlen(str)));
|
||||
}
|
||||
|
||||
int
|
||||
rd()
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
read(ttyFd, buf, sizeof(buf));
|
||||
printf("Got >%s<\n", buf);
|
||||
return(OK);
|
||||
}
|
||||
|
||||
rsTask(link)
|
||||
int link;
|
||||
{
|
||||
int len;
|
||||
int prio;
|
||||
struct xact232 *xact;
|
||||
unsigned char *ch;
|
||||
|
||||
printf("R/S-232 link task started for link %d\n", link);
|
||||
|
||||
while (1)
|
||||
{
|
||||
semTake(rsLink[link].txEventSem, WAIT_FOREVER);
|
||||
for(prio=0; prio < RS_NUM_PRIO; prio++)
|
||||
{
|
||||
FASTLOCK(&(rsLink[link].queue[prio].lock));
|
||||
if ((xact = rsLink[link].queue[prio].head) != NULL)
|
||||
{
|
||||
xactListDel(&(rsLink[link].queue[prio]), xact);
|
||||
FASTUNLOCK(&(rsLink[link].queue[prio].lock));
|
||||
|
||||
/* Perform the transaction operation */
|
||||
xact->status = XACT_OK; /* All well, so far */
|
||||
|
||||
@@ -353,7 +248,7 @@ int link;
|
||||
if (len == -1)
|
||||
len = strlen(xact->txMsg);
|
||||
|
||||
if(xact->txLen > 0)
|
||||
if(len > 0)
|
||||
{
|
||||
if (write(rsLink[link].ttyFd, xact->txMsg, len) != len)
|
||||
{
|
||||
@@ -361,20 +256,26 @@ int link;
|
||||
xact->status = XACT_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
drv232Read()
|
||||
{
|
||||
if ((xact->rxLen > 0) && (xact->status == XACT_OK))
|
||||
{
|
||||
if (xact->rxEoi != -1)
|
||||
{
|
||||
len = xact->rxLen;
|
||||
ch = xact->rxMsg;
|
||||
while ((*ch != xact->rxEoi) && (len > 0))
|
||||
eoi = xact->rxEoi & 0xff;
|
||||
*ch = eoi + 1; /* make sure gets into loop on first */
|
||||
while (len > 0)
|
||||
{
|
||||
read(rsLink[link].ttyFd, ch, 1);
|
||||
if (*ch == eoi)
|
||||
break;
|
||||
ch++;
|
||||
len--;
|
||||
}
|
||||
if (*ch != xact->rxEoi)
|
||||
if (*ch != eoi)
|
||||
xact->status = XACT_LENGTH;
|
||||
}
|
||||
else
|
||||
@@ -384,16 +285,62 @@ int link;
|
||||
len -= read(rsLink[link].ttyFd, xact->rxMsg, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish the xact opetation */
|
||||
if (xact->finishProc != NULL)
|
||||
callbackRequest(xact);
|
||||
|
||||
if (xact->psyncSem != NULL)
|
||||
semGive(*(xact->psyncSem));
|
||||
}
|
||||
else
|
||||
FASTUNLOCK(&(rsLink[link].queue[prio].lock));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* create an interactive RS232 transaction from the console */
|
||||
|
||||
static SEM_ID iSem;
|
||||
static int firstFlag = 1;
|
||||
rsx(l, ch)
|
||||
int l;
|
||||
unsigned char *ch;
|
||||
{
|
||||
struct xact232 xact;
|
||||
unsigned char rxBuf[100];
|
||||
|
||||
if (firstFlag)
|
||||
{
|
||||
iSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
firstFlag = 0;
|
||||
}
|
||||
xact.finishProc = NULL;
|
||||
xact.psyncSem = &iSem;
|
||||
|
||||
xact.link = l;
|
||||
xact.txMsg = ch;
|
||||
xact.txLen = -1;
|
||||
|
||||
xact.rxMsg = rxBuf;
|
||||
xact.rxEoi = '\r';
|
||||
xact.rxLen = sizeof(rxBuf);
|
||||
|
||||
rxBuf[0] = '\0';
|
||||
if (qXact(&xact, RS_Q_LOW) == ERROR)
|
||||
return(ERROR);
|
||||
|
||||
semTake(iSem, WAIT_FOREVER);
|
||||
|
||||
printf("Sent >%s< got >%s<\n", ch, rxBuf);
|
||||
return(xact.status);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static msgDrvBlock drv232Block = {
|
||||
report,
|
||||
init,
|
||||
NULL,
|
||||
genXact,
|
||||
genHwpvt,
|
||||
genLink,
|
||||
checkLink,
|
||||
checkEvent,
|
||||
NULL,
|
||||
"RS232",
|
||||
RSLINK_PRI,
|
||||
RSLINK_OPT,
|
||||
RSLINK_STACK,
|
||||
NULL
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user