MX Foundation 4
Basic Acquisition

The way to set a basic acquisition receive application is as follows:

  • A physical channel must be obtained using the mxfModuleChannelGet() function or with the mxfModuleChannelAllGet() function by specifying the MXF_SCLASS_ALL subclass.
  • A RX Virtual Link must be created using mxfA664VlCreate() with the VL parameters stored in a MXF_A664_VL_PARAM structure.
  • A RX COM port must be created using mxfA664PortCreate() with the port parameters stored in a MXF_A664_PORT_PARAM structure.
  • The acquisition buffer is automatically allocated and its buffer can be obtained using the mxfRxAcqBufferGet() function.
  • The acquisition mode can be set using the mxfRxAcqModeSet() function.

    Two modes of acquisition are defined;

    Condition Description
    MXF_RXACQ_MODE_LINEAR In this mode the acquisition stops when the buffer is full.
    MXF_RXACQ_MODE_CIRCULAR In this mode the acquisition buffer is circular and never stops receiving. Whenever the acquisition queue becomes full, the acquisition process will discard the newest received record.
  • The acquisition must be started using the mxfRxAcqStart() function.
  • The mxfA664RxAcqRead() function is used to read the messages from the buffer and place them in the record structure. mxfA664NextDataRecordPtrGet() can be used to cycle through records and display them.

The MXF_A664_DATAREC structure must be used for reading an ARINC 664 message with acquisition service.

Example

ar664_com_queuing_basic.c
The snippets below demonstrate the basic steps needed to setup a basic acquisition application.

#define DATARECS_BUFFER_SIZE_MAX 64*1024
#define SRC_IP_ADRS "10.0.0.111"
#define SRC_UDP_PORT 1234
#define DST_IP_ADRS "10.0.0.222"
#define DST_UDP_PORT 5678
HMXF_SERVER server = 0;
HMXF_PORT portRx = 0;
HMXF_VL vlRx = 0;
HMXF_BUFFER rxBuffer = 0;
HMXF_MODULE module = 0;
HMXF_DEVICE device = 0;
HMXF_CHANNEL phyChn = 0;
MXF_A664_DATAREC* rxRec = NULL;
uint32 srcIpAdrs = 0, dstIpAdrs = 0;
uint64 usedBytes, freeBytes;
uint64 msgCount = 0;
uint32 recordIdx, dataIdx;
uint32 vlid = 100;
uint32 rc;
uint64 count = 0;
uint64 frameType = MXF_A664_FRAME_TYPE_ARINC664;
uint64 recordIdx, dataIdx;
uint64 status, msgsCount, bytesCount;
uint32 dataSize;
// Initialize server, allocate base resources
rc = mxfSystemInit(server);
// Get the first device handle
if (!rc)
rc = mxfSystemDeviceGet(server, 0, &device);
// Get the first A664 module
if (!rc)
rc = mxfDeviceModuleAllGet(device, MXF_MODULE_A664, 1, &count, &module);
// Obtain the first ARINC 664 Phy channel (Phy logical #0)
if (!rc && count)
rc = mxfModuleChannelAllGet(module, MXF_CLASS_A664, MXF_SCLASS_ALL, 1, &count, &phyChn);
...
// Create the reception (RX) virtual link
if (!rc)
{
memset(&vlParam, 0, sizeof(MXF_A664_VL_PARAM));
vlParam.VLId = vlid;
vlParam.frameType = frameType;
vlParam.direction = MXF_A664_VL_DIR_RX;
vlParam.frameSizeMax = 512;
vlParam.dir.Rx.Mac.skewMax = 4 * 1000 * 1000;
vlParam.dir.Rx.Mac.rmPSNRange = 2;
rc = mxfA664VlCreate(phyChn, &vlParam, &vlRx);
}
// Create COM RX port
if (!rc)
{
inet_pton(AF_INET, DST_IP_ADRS, &srcIpAdrs);
inet_pton(AF_INET, SRC_IP_ADRS, &dstIpAdrs);
memset(&portParam, 0, sizeof(MXF_A664_PORT_PARAM));
portParam.portType = MXF_A664_PORT_TYPE_COM;
portParam.family = MXF_A664_PORT_FAMILY_IPV4;
portParam.mode = MXF_A664_PORT_MODE_QUEUING;
portParam.dir.Rx.network = MXF_A664_NETSELECT_ALL;
portParam.dir.Rx.maxBuffers = 16;
portParam.dir.Rx.bufferSize = 1518;
portParam.type.COM.destAddress.port = DST_UDP_PORT;
portParam.type.COM.destAddress.version.IPv4.address = ntohl(dstIpAdrs);
portParam.type.COM.srcAddress.port = SRC_UDP_PORT;
portParam.type.COM.srcAddress.version.IPv4.address = ntohl(srcIpAdrs);
rc = mxfA664PortCreate(vlRx, &portParam, &portRx);
}
// Get buffer handle automatically allocated for the port
if (!rc)
rc = mxfRxAcqBufferGet(portRx, &rxBuffer);
if (!rc)
{
rxRec = malloc(DATARECS_BUFFER_SIZE_MAX);
memset(rxRec, 0, DATARECS_BUFFER_SIZE_MAX);
if (!rxRec)
rc = MAXT_ERROR_MEM;
}
// Set acquisition mode
if (!rc)
rc = mxfRxAcqModeSet(rxBuffer, MXF_RXACQ_MODE_LINEAR);
// Start acquisition, check status
if (!rc)
rc = mxfRxAcqStart(rxBuffer, MXF_RXACQ_FLAG_DEFAULT, 0, 0);
if (!rc)
{
rc = mxfRxAcqBufferStatusGet(rxBuffer, &status, &msgCount, &usedBytes, &freeBytes);
if (!rc && (status & MXF_RXACQ_STATUS_RUNNING))
printf("Acquisition Running\n\n");
}
...
// Read and display records
rc = mxfA664RxAcqRead(rxBuffer, 0, DATARECS_BUFFER_SIZE_MAX, &status, &msgsCount, &bytesCount, rxRec);
if (!rc)
printf("%llu records received\n\n", msgsCount);
recPtr = rxRec;
for (recordIdx = 0; recordIdx < msgsCount && !rc; recordIdx++)
{
printf(" %03llu: timeTag=%012llu, Size=%u", recordIdx, recPtr->timeTag, recPtr->dataSize);
printf("\n data=");
dataSize = recPtr->dataSize;
for (dataIdx = 0; dataIdx < dataSize; dataIdx++)
{
printf("%02X ", recPtr->data[dataIdx]);
if (!((dataIdx + 1) % 8) && (dataIdx + 1 < recPtr->dataSize))
printf("\n ");
}
printf("\n\n");
mxfA664NextDataRecordPtrGet(recPtr, &recPtr);
}
...
// Terminate Acquisition
if (!rc)
rc = mxfRxAcqStop(rxBuffer);
if (!rc)
rc = mxfRxAcqClear(rxBuffer);
if (!rc)
rc = mxfRxAcqBufferFree(rxBuffer);
// Free COM ports
if (!rc)
rc = mxfA664PortRelease(portRx);
// Free VL(s)
if (!rc)
rc = mxfA664VlRelease(vlRx);
// Free datarec buffers
if (rxRec)
free(rxRec);
...
Updated 10/23/2023