MX Foundation 4
Asynchronous Events

An application can register condition(s) to be monitored by the receive firmware.

When a callback handler is defined, the condition(s) are reported to the application asynchronously from the firmware to the handler.

The way to define an handler is as follows:

After this registration, the application can read acquisition data as usual and/or received asynchronous events through the callback handler.

The receive queue can also be read from the callback handler if necessary.

If MXF_ASYNCEVENT_COND_RX_MSG condition is set for specific IDs, each ID will use one of the 256 messages spot available. (see Messages ID)

List of Conditions

The event conditions that can be monitored are as follows:

Condition Description
MXF_ASYNCEVENT_COND_RX_MSG Specific message available in the buffer.
MXF_ASYNCEVENT_COND_RX_ERROR Receive errors on the RX port.
MXF_ASYNCEVENT_COND_RXACQ_BUFFER_THRESHOLD Acquisition buffer threshold exceeded.

Example

In the example below a condition handler is defined for monitoring MXF_ASYNCEVENT_COND_RXACQ_BUFFER_THRESHOLD condition and CAN acquisition channel started for receiving data.

#define BUFFER_SIZE 4096
uint32 asyncEventHandler(HMXF_ASYNCEVENT asyncEvent, void *param)
{
HMXF_CHANNEL channel;
uint64 i, maxCount=64, pendingCount, status;
uint32 rc=MAXT_SUCCESS;
uint64 dev, mod, port;
// Builds the list of pending events to process
rc = mxfAsyncEventPendingGet(asyncEvent, maxCount, &pendingCount, pendingList);
for (i=0; i < pendingCount && !rc; i++)
{
switch(pendingList[i].condID)
{
// The buffer is almost full, we should then read the data with mxfCanBusRxAcqRead().
case MXF_ASYNCEVENT_COND_RXACQ_BUFFER_THRESHOLD:
{
HMXF_BUFFER buffer;
uint64 msgCount, byteCount;
uint64 msg;
uint32 rc=MAXT_SUCCESS;
buffer = pendingList[i].condition.rxAcqBufferThreshold.buffer;
// Reads the records
rc = mxfCanBusRxAcqRead(buffer, 0, BUFFER_SIZE, &status, &msgCount, &byteCount, recCan);
break;
}
// A receive error was detected
case MXF_ASYNCEVENT_COND_RX_ERROR:
channel = pendingList[i].condition.rxErr.channel;
status = pendingList[i].condition.rxErr.status;
rc = mxfChannelLocationGet(channel, &dev, &mod, &port);
if(!rc)
printf("Status 0x%08llx received on channel %llu.%llu.%llu\n", status, dev, mod, port);
break;
default:
printf("Unknown condID 0x%llx)", pendingList[i].condID);
break;
}
}
return rc;
}
int main()
{
HMXF_SERVER server;
MXF_ASYNCEVENT_CONDITION asyncEventInfo[2];
HMXF_DEVICE device=NULL;
HMXF_MODULE module=NULL;
HMXF_CHANNEL channel=NULL;
HMXF_BUFFER buffer=NULL;
HMXF_ASYNCEVENT asyncEvent=NULL;
uint64 count;
uint32 rc;
MXF_CANBUS_DATAREC *hostBuffer=NULL;
// Connects to services and initialize environment
rc = mxfServerConnect("0.0.0.0", "", "", FALSE, &server);
// Initializes the server.
if (!rc)
{
rc = mxfSystemInit(server);
if (!rc)
{
// Gets the device handle.
rc = mxfSystemDeviceAllGet(server, MXF_DEVICE_ALL, 1, &count, &device);
if (!rc)
rc = mxfDeviceModuleAllGet(device, MXF_MODULE_CANBUS, 1, &count, &module);
}
}
// Obtains the first CAN channel (logical #0).
if (!rc)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_CANBUS, MXF_SCLASS_ALL, 1, &count, &channel);
if (!rc)
// Allocates RX acquisition buffers
rc = mxfRxAcqBufferAlloc(channel, BUFFER_SIZE, &buffer, NULL);
// Allocates host buffer
if(!rc)
{
hostBuffer = (MXF_CANBUS_DATAREC *)malloc(BUFFER_SIZE);
if(!hostBuffer)
rc = MAXT_ERROR_MEM;
}
if (!rc)
// Registers the callback handler service function
rc = mxfAsyncEventHandlerInit(server, asyncEventHandler, hostBuffer, &asyncEvent);
memset(&asyncEventInfo, 0, sizeof(asyncEventInfo));
// Acquisition threshold; the callback gets called when the receive FIFO is
// almost full >=4 until it gets to < 1 word (almost empty).
asyncEventInfo[0].condID = MXF_ASYNCEVENT_COND_RXACQ_BUFFER_THRESHOLD;
asyncEventInfo[0].condition.rxAcqBufferThreshold.buffer=buffer;
// Receive message in error; the callback gets called when a data word in error is detected
asyncEventInfo[1].condID = MXF_ASYNCEVENT_COND_RX_ERROR;
asyncEventInfo[1].condition.rxErr.channel = channel;
// Enables Acquisition threshold interrupt
if (!rc)
rc = mxfAsyncEventConditionsSet(asyncEvent, TRUE, 2, asyncEventInfo);
// Starts the acquisition process
if (!rc)
rc = mxfRxAcqModeSet(buffer, MXF_RXACQ_MODE_LINEAR);
if (!rc)
rc = mxfRxAcqStart(buffer, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
// At this point a transmission must be running
if (!rc)
mxfSleep(5000);
if (buffer)
mxfRxAcqStop(buffer);
if (!rc)
rc = mxfAsyncEventConditionsSet(asyncEvent, FALSE, 2, asyncEventInfo);
// Checks for any errors
if (rc)
printf("Error code=0x%lX\n", rc);
if (asyncEvent)
if (device)
}
Updated 10/23/2023