Project

General

Profile

RE: Cannot run multiple times my ARM/DSP application » arm_main.cpp

Edwin McKay, 05/09/2016 12:32 PM

 
/**
* \file: main.cpp
*
* \brief ARM side main routine for DSP Hello World application.
* The ARM sets itself up, sends a message to the DSP,
* and then waits for a return message before exiting.
*
* o 0
* | / Copyright (c) 2005-2010
* (CL)---o Critical Link, LLC
* \
* O
*/

#include "dspapp.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ipc_inbound.h"
#include "ipc_outbound.h"

using namespace MityDSP;

enum MsgCommand {
eReadFromARM,
eWriteToARM,
eReadFromDSP,
eWriteToDSP
};

enum MsgTypes {
eGlobalFixture,
eLibrary,
eGlobalUser,
eGlobalSerialPort,
eGlobalScannerJog,
eFeature,
eFeatureData,
eFeatureDataSource,
eFeatureExpressions,
eFeatureFixture,
eFeatureMeasurement,
eFeatureSegmentList,
eGlobalDigitalInputs,
eGlobalDigitalOutputs,
eGlobalFactory,
eDebugText
};

typedef struct {
MsgTypes type;
MsgCommand command;
} Header;

typedef struct {
Header header;
char textMessage[100]; // 100 bytes for now
} DebugText;

typedef struct {
Header header;
char fixtureName[33];
int fixtureID;
int fixtureTencoderpe;
int fixtureURR;
int fixtureHomeMethod;
int fixtureZeroMethod;
int fixtureMotion;
int fixtureDirection;
int fixtureOrientation;
double fixtureLinearTravel;
double fixtureRotaryTravel;
int motorPresent;
int motorPort;
int motorRotation;
double motorGearRatioIn;
double motorGearRationOut;
int motorType;
int motorMaxSpeed;
int motorStepsPerRevolution;
char motorAcceleration[16]; // todo
int encoderPresent;
int encoderPort;
int encoderRotation;
double encoderGearRatioIn;
double encoderGearRationOut;
int encoderResolution;
int encoderIndexPresent;
int encoderIndexInput;
int encoderIndexIsHome;
int encoderIndexIsEndOfTravel;
int encoderQuadratureMode;
int homeSensorPresent;
int homeSensorInput;
int homeSensorType;
int homeSensorDirection;
int endOfTravelSensorPresent;
int endOfTravelSensorInput;
int endOfTravelSensorType;
int endOfTravelSensorDirection;
char inputMapping[5]; // todo
char outputMapping[8]; // todo
double pulleyDiam;
int pulleyUnits;
} GlobalFixture_str ;

typedef struct {
Header header;
int SerialNumber;
double AnalogCalMinValue;
double AnalogCalMaxValue;
double AnalogCalGain;
double AnalogOffset;
int LowPowerScannerType;
int LowPowerValue;
int CalibrationUnits;
double CalibrationSmallPart;
double CalibrationLargePart;
double CalibrationmValue;
double CalibrationbValue;
char CalibrationDate[20];
} GlobalFactory_str ;

typedef struct {
Header header;
int DigInputID;
int ActivationType;
int FunctionID;
} GlobalDigitalInputs_str ;

typedef struct {
Header header;
int DigOutputID;
int Polarity;
int Latched;
int ServerID;
} GlobalDigitalOutputs_str ;

typedef struct {
Header header;
int SerialPortID;
int BaudRate;
int ParityBits;
int DataBits;
int StopBits;
int FlowControl;
int ProtocolFlag;
int DataFlag;
} GlobalSerialPort_str ;

typedef struct {
Header header;
int FeatureID;
int LibraryToFeatureKey;
char Name[16];
int AdvanceMode;
int AdvanceDelay;
double SizeOffset;
double PositionOffset;
int URRUnits;
int URRResolution;
int URRRounding;
int DataSourceExpressionType;
int DataSource_op;
int Sequence;
double ToleranceRejectPlus;
double ToleranceRejectMinus;
double ToleranceWarningPlus;
double ToleranceWarningMinus;
double ToleranceNominal;
bool ToleranceRejectEnablePlus;
bool ToleranceRejectEnableMinus;
bool ToleranceWarningEnablePlus;
bool ToleranceWarningEnableMinus;
int UseFixtureToCollectData;
int UseFixtureForAutoPositioning;
double UserSingleMasterSize;
} Feature_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
char Label[16];
int DisplayLine;
int SerialPortSelected;
int UseAsLimits;
} FeatureData_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
int TermType;
double TermConstanst;
int TermFeatureID;
int TermID;
} FeatureDataSource_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
int Segment ;
} FeatureSegmentList_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
int Type;
int EdgeCount;
int GlassMode;
int InternalRefFlag;
int LowerRefFlag;
int UpperRefFlag;
int PartSegmentIndex;
int PartModeFlag;
int SamplingMode;
int AveragingMode;
int AveragingPeriod;
int GoodScans;
int EnterDelayMode;
int EnterDelayPeriod;
char FormatString[34];
int PolledFlag;
} FeatureMeasurement_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
int LineOrder;
char ExpressionText[50];
} FeatureExpressions_str ;

typedef struct {
Header header;
int FeatureToDataKey;
int LibraryToDataKey;
int FixtureID;
int DisableMotorAfterMove;
int IDODWALLComputeWall;
int MeasurementMode;
int UsageMode;
int AutomaticShankDiamFlag;
double Speed;
int StepMode;
int ReturnPosition;
int NumberOfMeasurementPositions;
double TotalDistance;
double StartPosition;
double ShankDiameter;
} FeatureFixture_str ;

typedef struct {
Header header;
int ScannerJogID;
double mOffset;
double bOffset;
double LowSize;
double HighSize;
} GlobalScannerJog_str ;

typedef struct {
Header header;
char LanguageName[20];
char LanguagePrefix[5];
char Password[8];
int PowerUpLocked;
int AllowNominalChanges;
int AllowRemastering;
int AllowLibraryChanges;
int AdvancedScreenOperation;
int AutoScrollEnable;
int AudibleAlarm;
int FlipScreen180;
int ScannerDoubleDiff;
int LatchScanErrors;
int IgnoreScanErrors;
char IPAddress[20];
int ButtonsDefined;
int ButtonID_1;
int ButtonID_2;
int ButtonID_3;
} GlobalUser_str ;

typedef struct {
Header header;
int LibraryID;
char LibraryName[16];
double UserDualPointMasterSize1;
double UserDualPointMasterSize2;
double AlarmDuration;
int AlarmEnable;
int SQCBatchSize;
int SQCBatchClearAtEndOfBatch;
int SQCBatchPrintAtEndOfBatch;
int FeatureCount;
int SerialDOFAutoSendFlag;
int SerialDOFAutoSendDelay;
int SerialDOFDateTimeFlag;
int SerialDOFLabelFlag;
int SerialDOFHeaderType;
int SerialDOFRequestorType;
char SerialDOFRequestorString[5];
int SerialDOFSeparatorType;
char SerialDOFSeparatorString[5];
int SerialDOFTerminatorType;
char SerialDOFTerminatorString[5];
int SerialDOFDecimalFlag;
int SerialDOFSignFlag;
double LegacySlideCounterPerInch;
int ReportSelected1;
int ReportSelected2;
int ReportSelected3;
int ReportSelected4;
char ReportUserTitle[33];
int ReportPrinterPort;
int ReportDisableHeaderAndFooter;
int ReportDisableFormFeed;
int URRUnits;
int URRResolution;
int URRRounding;
} Library_str ;

typedef union {
Header header;
DebugText debugMsg;
Library_str library;
GlobalFixture_str globalFixture;
GlobalUser_str globalUser;
GlobalScannerJog_str globalScannerJog;
FeatureFixture_str featureFixture;
FeatureExpressions_str featureExpressions;
FeatureMeasurement_str featureMeasurement;
FeatureSegmentList_str featureSegmentList;
FeatureDataSource_str featureDataSource;
FeatureData_str featureData;
Feature_str feature;
GlobalFactory_str globalFactory;
GlobalDigitalInputs_str globalDigitalInputs;
GlobalDigitalOutputs_str globalDigitalOutputs;
GlobalSerialPort_str globalSerialPort;
} allTypes;

allTypes messageA2D; // message data between DSP and ARM
Library_str library; // message one this side.

// Forward declarations
int handleInboundMessage(void *Buffer, uint16_t Length, void *UserArg);
int handleInboundMessageBM(void *Buffer, uint16_t Length, void *UserArg);

volatile bool gbDone = false;

int main(int argc, char* argv[])
{
// tcDspApp class for booting and loading the DSP
tcDspApp* lpDspApp = NULL;
// Used to setup handling of inbound messages from DSP
tcIPCInbound* lpMessageInbound = NULL;
// Used to send messages to the DSP
tcIPCOutbound* lpMessageOutbound = NULL;
// Message to send to the DSP
char lpMessage[] = "Hello DSP";
// Pointer to buffer obtained from dsplink
char* lpMessageBuffer = NULL;
// Message from standard input
char lpUsrMsg[180] = {0};

// Check application usage
if (argc < 2)
{
fprintf(stderr, "usage: HelloWorld dsp_image.out\n");
return -1;
}

// Create the DspApp object
lpDspApp = new tcDspApp();
if (lpDspApp != NULL) {
fprintf(stderr, "DSP app was created\n");
} else {
fprintf(stderr, "DSP app was not created\n");
}

// Load the DSP.out file
fprintf(stderr, "Loading file %s\n", argv[1]);
int retCode;
retCode = lpDspApp->LoadApp(argv[1], true, argc>2?1:0);

fprintf(stderr, "Return code from Load App = %d\n", retCode);
fprintf(stderr, "Starting application.\n");

// Create the object to handle incoming messages from the DSP
lpMessageInbound = new tcIPCInbound((char*)"GPPMSGQ1");

if (NULL != lpMessageInbound)
{
// Register the callback for handling messages from the DSP
lpMessageInbound->Register(handleInboundMessageBM, (void*)NULL);

// Intialize the inbound controller to create the thread that handles the callbacks
lpMessageInbound->Initialize();
} else {
fprintf(stderr, "lpMessageInBound was null for some reason\n");
}

// Create the object used to send messages to the DSP
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");

// Wait for the DSP to finish initialization (really just waiting for first message, which indicates DSP set up ok)
while(false == gbDone) {
sleep(3); //fprintf(stderr, "waiting for DSP\n");
}

// Reset bool in preparation for next received message from DSP
gbDone = false;

// Get a buffer for a message to the DSP
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));

allTypes messageA2D;
messageA2D.library.header.command = eWriteToDSP;
messageA2D.library.header.type = eLibrary;
messageA2D.library.FeatureCount = 0;
messageA2D.library.SQCBatchSize = 9;

// Copy the message to the dsplink buffer
memcpy(lpMessageBuffer, &messageA2D, sizeof(messageA2D));
// Send the message to the DSP
fprintf(stderr, "Sending a message to the DSP.\n");
lpMessageOutbound->SendMessage(lpMessageBuffer);

/* original sample code....
* // Copy the message to the dsplink buffer
strcpy(lpMessageBuffer, lpMessage);

// Send the message to the DSP
fprintf(stderr, "Sending a message to the DSP.\n");
lpMessageOutbound->SendMessage(lpMessageBuffer);
****************** */
// Wait for a message to be received from the DSP or for user to quit
fprintf(stderr, "Waiting for DSP response \n");
int counter=0; // lets send a few messages back and forth and then quit
while (gbDone == false ) {
counter++;
// fprintf(stderr, "after first one looping %d\n", counter);
}
gbDone = false; // reset flag

// send the Library msg back to the DSP, it will send it back to us automatically.
fprintf(stderr, "after second one looping %d\n", counter);
// Create the object used to send messages to the DSP
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
if (NULL != lpMessageOutbound)
{
fprintf(stderr, "\n");
}
// Get a buffer for a message to the DSP
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
if (lpMessageBuffer) {
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
lpMessageOutbound->SendMessage(lpMessageBuffer);
} else {
fprintf(stderr, "did not get 2nd message buffer for some reason\n");
gbDone = true;
}
while (gbDone == false ) {
counter++;
}
gbDone = false; // reset flag

fprintf(stderr, "after third one looping %d\n", counter);
// send the Library msg back to the DSP, it will send it back to us automatically.
// Get a buffer for a message to the DSP
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
if (lpMessageBuffer) {
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
lpMessageOutbound->SendMessage(lpMessageBuffer);
} else {
fprintf(stderr, "did not get 3rd message buffer for some reason\n");
gbDone = true;
}
while (gbDone == false ) {
counter++;
//fprintf(stderr, "after third one looping %d\n", counter);
}
gbDone = false; // reset flag

// Wait for a message to be received from the DSP or for user to quit
fprintf(stderr, "Waiting for DSP response (type \'q\' to quit)...\n");
while(gbDone == false && lpUsrMsg[0] != 'q')
{
fgets(lpUsrMsg, 180, stdin);
}

/*int counter=0;
while(counter++ < 2000) {
sleep(3);
fprintf(stderr, "waiting sending serial messages via DSP? %d\n", i);
}*/

fprintf(stderr, "Exiting application.\n");

// Stop the DSP application from running
lpDspApp->StopApp();

// Cleanup
// Commented out because deletes throw Assert errors.
//delete lpDspApp;
//delete lpMessageInbound;
//delete lpMessageOutbound;

return 0;
}

/**
* Handle inbound messages from the DSP.
*
* \param apBuffer Pointer to the buffer containing the message.
* \param anLength The length of the message.
* \param apUserArg User defined argument.
*
* \return 0.
*/
int handleInboundMessage(void *apBuffer, uint16_t anLength, void *apUserArg)
{
fprintf(stderr, "ARM received a message from the DSP:\n");

// Print the message we received
fprintf(stderr, "\tDSP Message = \"%s\" len = %d\n", (char *)apBuffer, anLength);

// Notify the main function that we have received a message from the DSP and are done
gbDone = true;

return 0;
}

/**
* Handle inbound messages from the DSP.
*
* \param apBuffer Pointer to the buffer containing the message.
* \param anLength The length of the message.
* \param apUserArg User defined argument.
*
* \return 0.
*/
int handleInboundMessageBM(void *apBuffer, uint16_t anLength, void *apUserArg)
{
fprintf(stderr, "handleInboundMessageBM:ARM received a message from the DSP:\n");

// Print the message we received
fprintf(stderr, "\tDSP Messagelen = %d\n", anLength);
allTypes messageA2D;
memcpy(&messageA2D, (char *)apBuffer, sizeof(messageA2D));
switch (messageA2D.header.type) {
case eLibrary:
// for fun just print some values recv'd from the DSP
fprintf(stderr, "messageA2D.library.FeatureCount = %d\n", messageA2D.library.FeatureCount);
fprintf(stderr, "messageA2D.library.SQCBatchSize = %d\n", messageA2D.library.SQCBatchSize);

memcpy(&library, &messageA2D, sizeof(messageA2D)); // save a local copy of the library data...
fprintf(stderr, "after doing memcpy at %d\n", __LINE__);
break;
case eDebugText:
// print message from DSP.
fprintf(stderr, "Message: %s\n", messageA2D.debugMsg.textMessage );
break;
};

// Notify the main function that we have received a message from the DSP and are done
gbDone = true;

fprintf(stderr, "handleInboundMessageBM:leaving ...\n");
return 0;
}

(2-2/3)