record3.c -- Interrupt-driven display of data recorder records from specified axis (default 0)
/* record3.c */
/* Copyright(c) 1991-2002 by Motion Engineering, Inc. All rights reserved.
*
* This software contains proprietary and confidential information of
* Motion Engineering Inc., and its suppliers. Except as may be set forth
* in the license agreement under which this software is supplied, use,
* disclosure, or reproduction is prohibited without the prior express
* written consent of Motion Engineering, Inc.
*/
#if defined(MEI_RCS)
static const char MEIAppRCS[] =
"$Header: /MainTree/XMPLib/XMP/app/record3.c 12 7/23/01 2:36p Kevinh $";
#endif
/*
:Interrupt-driven display of data recorder records from specified axis (default 0)
Warning! This is a sample program to assist in the integration of the
XMP motion controller with your application. It may not contain all
of the logic and safety features that your application requires.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main record3Main
argMainRENAME(main, record3)
#endif
/* Command line arguments and defaults */
long period = 0; /* every sample */
long recordCount = 100;
long fullCount = -1;
Arg argList[] = {
{ "-period", ArgTypeLONG, &period, },
{ "-records", ArgTypeLONG, &recordCount, },
{ "-full", ArgTypeLONG, &fullCount, },
{ NULL, ArgTypeINVALID, NULL, }
};
int
main(int argc,
char *argv[])
{
MPIControl control; /* motion controller handle */
MPIAxis axis[MEIXmpMAX_Axes]; /* axis handles */
MPIRecorder recorder; /* data recorder handle */
MPINotify notify; /* event notification handle */
MPIEventMgr eventMgr; /* event manager handle */
MPIEventMask eventMask;
Service service; /* service thread */
long axisCount;
long axisNumber[MEIXmpMAX_Axes]; /* axis numbers */
MPIRecorderStatus recorderStatus;
MPIRecorderRecord *record;
register MEIRecorderRecord *recordPtr;
long returnValue; /* return value from library */
long index;
long recordingDone;
long recordIndex;
MPIControlType controlType;
MPIControlAddress controlAddress;
long argIndex;
argIndex =
argControl(argc,
argv,
&controlType,
&controlAddress);
/* Parse command line for application-specific arguments */
while (argIndex < argc) {
long argIndexNew;
argIndexNew = argSet(argList, argIndex, argc, argv);
if (argIndexNew <= argIndex) {
argIndex = argIndexNew;
break;
}
else {
argIndex = argIndexNew;
}
}
if (argIndex >= argc) {
axisCount = 1;
axisNumber[0] = 0;
}
else {
axisCount = argc - argIndex;
if (axisCount > MEIXmpMAX_Axes) {
axisCount = MEIXmpMAX_Axes;
}
for (index = 0; index < axisCount; index++) {
axisNumber[index] = meiPlatformAtol(argv[argIndex++]);
meiASSERT((axisNumber[index] >= 0) &&
(axisNumber[index] < MEIXmpMAX_Axes));
}
}
if (argIndex < argc) {
meiPlatformConsole("usage: %s %s\n"
"\t\t[-period (%d)]\n"
"\t\t[-records (%d)]\n"
"\t\t[-full (%d)]\n"
"\t\t[axisNumber ...]\n",
argv[0],
ArgUSAGE,
period,
recordCount,
fullCount);
exit(MPIMessageARG_INVALID);
}
/* Create motion controller object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize motion controller */
returnValue = mpiControlInit(control);
msgCHECK(returnValue);
for (index = 0; index < axisCount; index++) {
axis[index] =
mpiAxisCreate(control,
axisNumber[index]);
msgCHECK(mpiAxisValidate(axis[index]));
}
/* Create and configure recorder object */
recorder =
mpiRecorderCreate(control);
msgCHECK(mpiRecorderValidate(recorder));
returnValue =
mpiRecorderRecordConfig(recorder,
(MPIRecorderRecordType)MEIRecorderRecordTypeAXIS,
axisCount,
axis);
msgCHECK(returnValue);
returnValue =
mpiRecorderStatus(recorder,
&recorderStatus,
NULL);
msgCHECK(returnValue);
if (fullCount < 0) {
fullCount =
recorderStatus.recordCountMax -
(recorderStatus.recordCountMax / 4);
}
/* Allocate memory for record buffer */
record =
(MPIRecorderRecord *)meiPlatformAlloc(sizeof(*record) *
recordCount);
meiASSERT(record != NULL);
/* Request notification of all events from recorder */
mpiEventMaskCLEAR(eventMask);
mpiEventMaskRECORDER(eventMask); /* macro */
returnValue =
mpiRecorderEventNotifySet(recorder,
eventMask,
NULL);
msgCHECK(returnValue);
/* Create event notification object for recorder */
notify =
mpiNotifyCreate(eventMask,
recorder);
msgCHECK(mpiNotifyValidate(notify));
/* Create event manager object */
eventMgr =
mpiEventMgrCreate(control);
msgCHECK(mpiEventMgrValidate(eventMgr));
/* Add notify to event manager's list */
returnValue =
mpiEventMgrNotifyAppend(eventMgr,
notify);
msgCHECK(returnValue);
/* Create service thread */
service =
serviceCreate(eventMgr,
-1, /* default (max) priority */
-1); /* -1 => enable interrupts */
meiASSERT(service != NULL);
/* Start Recorder and wait for Event */
returnValue =
mpiRecorderStart(recorder,
recordCount,
period, /* period (milliseconds) */
fullCount);
msgCHECK(returnValue);
recordPtr = (MEIRecorderRecord *)record;
recordingDone = FALSE;
while (recordingDone == FALSE) {
MPIEventStatus eventStatus;
returnValue =
mpiNotifyEventWait(notify,
&eventStatus,
MPIWaitFOREVER);
msgCHECK(returnValue);
switch (eventStatus.type) {
case MPIEventTypeRECORDER_FULL:
case MPIEventTypeRECORDER_DONE: {
long countGet;
returnValue =
mpiRecorderRecordGet(recorder,
recordCount,
(MPIRecorderRecord *)recordPtr,
&countGet);
msgCHECK(returnValue);
recordPtr += countGet;
if (eventStatus.type == MPIEventTypeRECORDER_DONE) {
recordingDone = TRUE;
}
break;
}
default: {
meiASSERT(FALSE);
break;
}
}
}
returnValue = mpiRecorderStop(recorder);
meiASSERT(returnValue == MPIRecorderMessageSTOPPED);
/* Ouput all records to console */
for (recordIndex = 0,
recordPtr = (MEIRecorderRecord *)record;
recordIndex < recordCount;
recordIndex++,
recordPtr++) {
printf("record[%d]:\n",
recordIndex);
for (index = 0; index < axisCount; index++) {
printf("axis %d sample %d\tcommand %d\tactual %d\tdac %.4f\n",
axisNumber[index],
recordPtr->axis[index].sample,
recordPtr->axis[index].command,
recordPtr->axis[index].actual,
recordPtr->axis[index].dac);
}
}
/* Delete recorder */
returnValue = mpiRecorderDelete(recorder);
msgCHECK(returnValue);
/* Free recorder buffer */
returnValue =
meiPlatformFree(record,
(sizeof(*record) * recordCount));
meiASSERT(returnValue == MPIMessageOK);
/* Delete remaining objects */
for (index = 0; index < axisCount; index++) {
returnValue = mpiAxisDelete(axis[index]);
msgCHECK(returnValue);
}
returnValue = serviceDelete(service);
msgCHECK(returnValue);
returnValue = mpiEventMgrDelete(eventMgr);
msgCHECK(returnValue);
returnValue = mpiNotifyDelete(notify);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}