EventLog.c -- Event Logging Application
/* EventLog.c */
/* Copyright(c) 1991-2006 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.
*/
/*
:Event Logging Application
This application logs all events generated by a single controller. To end
the application, simply press a key. To save the output to a file,
please redirect the output using a pipe (type "EventLog > logOfEvents.txt")
NOTE: This application does not change any configuration on the controller.
If the controller is not configured to report events, then this application
will report nothing. Please refer to the sample application EventReport.c
to see how to enable reporting of all events.
Warning! This is a sample program to assist in the integration of an
MEI motion controller with your application. It may not contain all
of the logic and safety features that your application requires.
The msgCHECK(...) macros used in the following sample code are intended
to convey our strong belief that ALL error return codes should be checked.
Actual application code should use specific error handling techniques (other
than msgCHECKs) best suited to your internal error recovery methods.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
/* Perform basic command line parsing. (-control -server -port -trace) */
void basicParsing(int argc,
char *argv[],
MPIControlType *controlType,
MPIControlAddress *controlAddress)
{
long argIndex;
/* Parse command line for Control type and address */
argIndex = argControl(argc, argv, controlType, controlAddress);
/* Check for unknown/invalid command line arguments */
if (argIndex < argc) {
fprintf(stderr,"usage: %s %s\n", argv[0], ArgUSAGE);
exit(MPIMessageARG_INVALID);
}
}
/* Create and initialize MPI objects */
void programInit(MPIControl *control,
MPIControlType controlType,
MPIControlAddress *controlAddress,
MPIEventMgr *eventMgr,
MPINotify *notify)
{
MEIEventMgrServiceConfig serviceConfig;
MPIEventMask eventMask;
long returnValue;
/* Obtain a control handle */
*control =
mpiControlCreate(controlType, controlAddress);
msgCHECK(mpiControlValidate(*control));
/* Initialize the controller */
returnValue =
mpiControlInit(*control);
msgCHECK(returnValue);
/* Obtain a notify handle */
mpiEventMaskCLEAR(eventMask);
mpiEventMaskALL(eventMask);
meiEventMaskALL(eventMask);
*notify =
mpiNotifyCreate(eventMask, NULL);
msgCHECK(mpiNotifyValidate(*notify));
/* Obtain an eventMgr handle */
*eventMgr =
mpiEventMgrCreate(*control);
msgCHECK(mpiEventMgrValidate(*eventMgr));
returnValue =
mpiEventMgrNotifyAppend(*eventMgr, *notify);
msgCHECK(returnValue);
/* Retrieve events from all processes */
returnValue =
meiEventMgrServiceConfigGet(*eventMgr, &serviceConfig);
msgCHECK(returnValue);
serviceConfig.allProcesses = TRUE;
returnValue =
meiEventMgrServiceConfigSet(*eventMgr, &serviceConfig);
msgCHECK(returnValue);
}
/* Perform certain cleanup actions and delete MPI objects */
void programCleanup(MPIControl *control,
MPIEventMgr *eventMgr,
MPINotify *notify)
{
long returnValue;
/* Delete eventMgr handle */
returnValue =
mpiEventMgrDelete(*eventMgr);
msgCHECK(returnValue);
*eventMgr = MPIHandleVOID;
/* Delete notify handle */
returnValue =
mpiNotifyDelete(*notify);
msgCHECK(returnValue);
*notify = MPIHandleVOID;
/* Delete control handle */
returnValue =
mpiControlDelete(*control);
msgCHECK(returnValue);
*control = MPIHandleVOID;
}
/*
Identifies the source (type and index) of an event
(from the MPIEventStatus structure)
This is particularly useful when attempting to identify which axis produced
an event in a different process or when identifying the axis without
comparing MPIAxis handles.
identifyEventSource() will return MPIMessageARG_INVALID if status is NULL or
if both sourceType and sourceIndex are NULL. Otherwise, the function will
succeed and return MPIMessageOK.
Possible values for sourceType:
sourceType Value Event Source Type
---------------- -----------------
MEIXmpSignalID_MOTOR Motor object
MEIXmpSignalID_AXIS Axis
MEIXmpSignalID_MS Motion Supervisor
MEIXmpSignalID_PS Program Sequencer (Non-user commanded events)
MEIXmpSignalID_DR Data Recorder
MEIXmpSignalID_USER User Commanded Event in a Program Sequencer
NOTE: As of Feb 2002, only one Data Recorder exists per controller, so
when the source is the data recorder, sourceIndex will filled with the
value of zero.
*/
long identifyEventSource(MPIEventStatus* status,
MEIXmpSignalID* sourceType,
long* sourceIndex)
{
if (status==NULL)
{
return MPIMessageARG_INVALID;
}
if ((sourceType==NULL) && (sourceIndex==NULL))
{
return MPIMessageARG_INVALID;
}
if (sourceType!=NULL)
{
*sourceType =
((((MEIEventStatusInfo*)status->info)->signalID) &
MEIXmpSignalID_MASK);
}
if (sourceIndex!=NULL)
{
*sourceIndex =
((((MEIEventStatusInfo*)status->info)->signalID) &
MEIXmpSignalID_INDEX) >> 16;
}
return MPIMessageOK;
}
/* Display event information */
void reportEvent(MPIEventStatus* status)
{
MEIXmpSignalID sourceType;
long sourceIndex;
long returnValue;
returnValue =
identifyEventSource(status, &sourceType, &sourceIndex);
msgCHECK(returnValue);
/* Report event source */
switch (sourceType)
{
case MEIXmpSignalID_MOTOR:
if (sourceIndex<10)
{
printf("Motor[%1d] : ",sourceIndex);
}
else
{
printf("Motor[%2d] : ",sourceIndex);
}
break;
case MEIXmpSignalID_AXIS:
if (sourceIndex<10)
{
printf("Axis[%1d] : ",sourceIndex);
}
else
{
printf("Axis[%2d] : ",sourceIndex);
}
break;
case MEIXmpSignalID_MS:
if (sourceIndex<10)
{
printf("Motion[%1d] : ",sourceIndex);
}
else
{
printf("Motion[%2d] : ",sourceIndex);
}
break;
case MEIXmpSignalID_DR:
printf("Data Recorder[%2d] : ",sourceIndex);
break;
case MEIXmpSignalID_PS:
if (sourceIndex<10)
{
printf("Sequence[%1d] : ",sourceIndex);
}
else
{
printf("Sequence[%2d] : ",sourceIndex);
}
break;
case MEIXmpSignalID_USER:
if (sourceIndex<10)
{
printf("User (PS[%1d]) : ",sourceIndex);
}
else
{
printf("User (PS[%2d]): ",sourceIndex);
}
break;
default:
printf("Unknown Source: ",sourceIndex);
}
/* Report event type */
printf("%42s ", mpiEventTypeName(status->type));
/* Report event sample */
printf("Sample %10u ",((MEIEventStatusInfo*)status->info)->data.sampleCounter);
/* Report additional information */
switch (sourceType)
{
case MEIXmpSignalID_MOTOR:
printf("Enc Position %11d\n",
((MEIEventStatusInfo*)status->info)->data.motor.encoderPosition);
break;
case MEIXmpSignalID_AXIS:
printf("Axis Position %11d\n",
((MEIEventStatusInfo*)status->info)->data.axis.actualPosition);
break;
default:
printf("\n");
}
}
/* Gather and display events */
void reportEventsUntilUserRequestsExit(MPIEventMgr eventMgr, MPINotify notify)
{
MPIEventStatus eventStatus;
long returnValue;
fprintf(stderr, "Press any key to exit...\n");
/* Collect motion events */
while (meiPlatformKey(MPIWaitPOLL) < 0)
{
/* Obtain firmware event(s) (if any) */
returnValue =
mpiEventMgrService(eventMgr,
MPIHandleVOID);
msgCHECK(returnValue);
/* Poll for motion event */
returnValue =
mpiNotifyEventWait(notify,
&eventStatus,
(MPIWait)MPIWaitMSEC*20);
if (returnValue != MPIMessageTIMEOUT)
{
reportEvent(&eventStatus);
}
}
}
int main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MPIEventMgr eventMgr;
MPINotify notify;
/* Perform basic command line parsing. (-control -server -port -trace) */
basicParsing(argc,
argv,
&controlType,
&controlAddress);
/* Create and initialize MPI objects */
programInit(&control,
controlType,
&controlAddress,
&eventMgr,
¬ify);
/* Gather and display events */
reportEventsUntilUserRequestsExit(eventMgr, notify);
/* Perform certain cleanup actions and delete MPI objects */
programCleanup(&control,
&eventMgr,
¬ify);
return MPIMessageOK;
}
|