SQStatus2.c -- Display/Save/Verify SynqNet Topology using SynqNet
Info Structure
/* SQStatus2.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.
*/
/*
:Display/Save/Verify SynqNet Topology using SynqNet Info Structure
This program demonstrates how to verify a SynqNet network topology. Your
application code should always verify that the network topology is as expected.
This step is required for safe machine operation.
This program only displays and verifies basic SynqNet node topology information.
It does NOT check the drive/motor specific details. Depending on your system
installation and configuration, additional steps may be required to verify the
individual network devices. Please consult your drive/motor manufacturer
documentation for details.
If the -save <filename> option is selected, the topology info is saved to a text file.
The saved text file can be used to verify the SynqNet topology at system startup
using the -verify <filename> option. This option saves the current topology info to
a temporary file, then compares the temporary file to the saved file. A failure or
success is reported after the verify check.
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.
*/
#include <stdlib.h>
#include <stdio.h>
#include "stdmpi.h"
#include "stdmei.h"
#include "apputil.h"
#if defined(ARG_MAIN_RENAME)
#define main SQStatus2Main
argMainRENAME(main, SQStatus2)
#endif
/* Command line arguments and defaults */
long confirm = 0;
long synqNetNumber = 0;
char *saveFilename = NULL;
char *verifyFilename = NULL;
Arg argList[] = {
{ "-confirm", ArgTypeNONE, &confirm, },
{ "-synqNet", ArgTypeLONG, &synqNetNumber, },
{ "-save", ArgTypeTEXT, &saveFilename, },
{ "-verify", ArgTypeTEXT, &verifyFilename, },
{ NULL, ArgTypeINVALID, NULL, }
};
long
networkInfoOutput(MEISynqNet synqNet,
char *fileName);
long
networkInfoVerify(MEISynqNet synqNet,
char *filename);
int
main(int argc,
char *argv[])
{
MPIControl control;
MPIControlType controlType;
MPIControlAddress controlAddress;
MEISynqNet synqNet;
long returnValue;
long argIndex;
/* Parse command line for Control type and address */
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;
}
}
/* Check for unknown/invalid command line arguments */
if ((argIndex < argc) ||
(synqNetNumber < 0) ||
(synqNetNumber >= MEIXmpMaxSynqNets) ||
((saveFilename != NULL) && (verifyFilename != NULL))) {
meiPlatformConsole("usage: %s %s\n",
"\t\t[-confirm]\n"
"\t\t[-synqNet (0 .. %d)]\n"
"\t\t[-save filename | -verify filename]\n",
argv[0],
ArgUSAGE,
MEIXmpMaxSynqNets - 1);
exit(MPIMessageARG_INVALID);
}
/* Create control object */
control =
mpiControlCreate(controlType,
&controlAddress);
msgCHECK(mpiControlValidate(control));
/* Initialize the controller */
returnValue = mpiControlInit(control);
/* check for configuration mismatch */
if (returnValue == MEISynqNetMessageTOPOLOGY_MISMATCH) {
meiPlatformConsole("\n\nWARNING: %s\n\n",
mpiMessage(returnValue, NULL));
}
else {
msgCHECK(returnValue);
}
/* Create SynqNet Object */
synqNet =
meiSynqNetCreate(control,
synqNetNumber);
msgCHECK(meiSynqNetValidate(synqNet));
/* Display current topology */
networkInfoOutput(synqNet, NULL);
if (confirm) {
printf("\n\nSaving network topology to flash...");
returnValue =
meiSynqNetFlashTopologySave(synqNet, NULL);
msgCHECK(returnValue);
}
else {
if (saveFilename != NULL) {
char in;
/* verify with user */
printf("\n\nIs this network topology correct? (y/n)");
in = getchar();
/* save topology to file */
if ((in == 'y') ||
(in == 'Y')) {
networkInfoOutput(synqNet, saveFilename);
printf("\nNetwork topology saved to file: %s\n\n", saveFilename);
}
}
if (verifyFilename != NULL) {
returnValue =
networkInfoVerify(synqNet, verifyFilename);
if (returnValue == -1) {
printf("Verify failed\n\n");
}
else {
printf("Verify Successful!!\n\n");
}
}
}
/* Delete object handles */
returnValue = meiSynqNetDelete(synqNet);
msgCHECK(returnValue);
returnValue = mpiControlDelete(control);
msgCHECK(returnValue);
return ((int)returnValue);
}
long
networkInfoOutput(MEISynqNet synqNet,
char *fileName)
{
MEISynqNetInfo netInfo;
MEISqNode sqNode;
MEISqNodeInfo nodeInfo;
long bytes;
long index;
long returnValue;
FILE *stream = stdout;
/* open file for output */
if (fileName != NULL) {
stream = fopen( fileName, "w" );
}
/* Read SynqNet Info */
returnValue =
meiSynqNetInfo(synqNet, &netInfo);
msgCHECK(returnValue);
bytes = fprintf(stream, "SynqNet Information\n\n");
if (netInfo.nodeCount) {
/* Display SynqNet Info */
for (index = netInfo.nodeOffset;
index < netInfo.nodeOffset + netInfo.nodeCount;
index++) {
sqNode =
meiSqNodeCreate(meiSynqNetControl(synqNet), index);
msgCHECK(meiSqNodeValidate(sqNode));
returnValue =
meiSqNodeInfo(sqNode, &nodeInfo);
msgCHECK(returnValue);
bytes +=
fprintf(stream,
" Node %ld Information\n"
" Motor Count : %d\n"
" Motor Offset : 0x%x\n",
index,
nodeInfo.motorCount,
nodeInfo.motorOffset);
bytes +=
fprintf(stream,
" NodeType : 0x%8.8x\n"
" NodeOption : 0x%8.8x\n"
" Unique Id : %d\n"
" Serial Number: %s\n"
" Model Number : %s\n"
" Switch Id : 0x%x\n"
" FPGA Number : 0x%x\n"
" FPGA Version : 0x%x\n\n",
nodeInfo.id.nodeType,
nodeInfo.id.option,
nodeInfo.id.unique,
nodeInfo.id.serialNumber,
nodeInfo.id.modelNumber,
nodeInfo.id.switchId,
nodeInfo.fpga.vendorDevice,
nodeInfo.fpga.version);
}
}
else {
printf("No SynqNet Blocks found.\n");
}
/* close output file */
if (fileName != NULL) {
fclose( stream );
}
return (bytes);
}
long
networkInfoVerify(MEISynqNet synqNet,
char *fileName)
{
long returnValue = MPIMessageOK;
long bytes, i;
char chr1, chr2;
FILE *stream1, *stream2;
/* save current topology to temp file */
bytes =
networkInfoOutput(synqNet, "tmpfile.txt");
/* open files */
stream1 = fopen( "tmpfile.txt", "r" );
stream2 = fopen( fileName, "r" );
/* compare files */
for(i=0;i<bytes;i++) {
chr1=fgetc(stream1);
chr2=fgetc(stream2);
if (chr1 != chr2) {
returnValue = -1;
break;
}
}
return (returnValue);
}
|