After several months of doing more pressing work, I've finally been able to revist this issue with some test code. The main test function looks like the code below. The issue here is that the viMoveAsync always returns VI_SUCCESS_SYNC, so it seems that something is preventing the asnyc move from happening. Unless I can determine what needs to change to allow async moves, the normal viMove() is less trouble. Is it a Linux issue, some additional source/dest space definition issue, soem other init function that needs to be added, should the source space be allocated with viMalloc, locked, whatever. Assuming everything can be made to work async, there seems to be more overhead, so that the must be some message length below which it is more advantageous to use viMove(), and some where it is more useful to do viMoveAsync(). If there are no guideline son this, I will have to do some timing experiments.
Also, viMoveAsync() returns a jobID, but there does not seem to be any association between the jobID and the viWaitEvent() call -- that is, there does not seem to be a way to wait for a *particular* viMoveAsync() transfer to finish. I must be missing something.
void send_message(Board* this, const unsigned* message)
{
ViUInt16 srcSpace = VI_LOCAL_SPACE;
ViBusAddress srcOffset = (ViBusAddress)message;
ViUInt16 srcWidth = VI_WIDTH_32;
ViUInt16 destSpace = VI_A32_SPACE;
ViBusAddress destOffset = 0;
ViUInt16 destWidth = VI_WIDTH_32;
ViBusSize length = message[0] + 1;
ViEventType outEventType;
ViEvent outEvent;
ViStatus status;
#if 0
// synchronous move
status = viMove(this->session,
srcSpace, srcOffset, srcWidth,
destSpace, destOffset, destWidth,
length);
CHECK_STATUS(status);
#else
// make sure previous async move is complete (we're not really
// going to wait 1s)
if (this->jobId != VI_NULL)
{
status = viWaitOnEvent(this->session, VI_EVENT_IO_COMPLETION, 1000,
&outEventType, &outEvent);
if (status < VI_SUCCESS)
{
// if it hasn't finished by now, it's not gonna, kill it
status = viTerminate(this->session, VI_NULL, this->jobId);
CHECK_STATUS(status);
// now the I/O completion event should exist in the queue
status = viWaitOnEvent(this->session, VI_EVENT_IO_COMPLETION, 0,
&outEventType, &outEvent);
CHECK_STATUS(status);
assert(outEventType == VI_EVENT_IO_COMPLETION);
}
}
VALUE(outEvent, "%x");
// start async move
status = viMoveAsync(this->session,
srcSpace, srcOffset, srcWidth,
destSpace, destOffset, destWidth,
length, &this->jobId);
VALUE(status, "%x");
if (status != VI_SUCCESS && status != VI_SUCCESS_SYNC)
{
assert(status == VI_SUCCESS);
}
VALUE(this->jobId, "%x");
#endif
}
The relevent initialization snippets:
typedef struct Board
{
ViSession session;
ViJobId jobId;
} Board;
this->jobId = VI_NULL;
// open a VISA session to the device at logical address LA
sprintf(resource_string, "VXI0::%d::INSTR", LA);
access_mode = VI_NULL; // use defaults
timeout = VI_NULL; // wait forever (?)
status = viOpen(defaultRM, resource_string, access_mode, timeout,
&this->session);
CHECK_STATUS(status);
// create the async I/O completion event queue
status = viEnableEvent(this->session, VI_EVENT_IO_COMPLETION,
VI_QUEUE, VI_NULL);
CHECK_STATUS(status);