Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions acsMotionApp/src/SPiiPlusAuxDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <iocsh.h>
#include <epicsThread.h>
#include <epicsExit.h>

// asynMotorController.h includes asynPortDriver.h
#include <asynMotorController.h>
Expand All @@ -23,6 +24,14 @@ static void SPiiPlusAuxIOThreadC(void *pPvt)
pAux->pollerThread();
}

static void shutdownCallback(void *pPvt)
{
SPiiPlusController *pC = static_cast<SPiiPlusController *>(pPvt);

pC->lock();
pC->shuttingDown_ = 1;
pC->unlock();
}

SPiiPlusAuxIO::SPiiPlusAuxIO(const char *ACSAuxPortName, const char* asynPortName, int numChannels, double pollPeriod)
: asynPortDriver(ACSAuxPortName, numChannels,
Expand All @@ -42,6 +51,9 @@ SPiiPlusAuxIO::SPiiPlusAuxIO(const char *ACSAuxPortName, const char* asynPortNam

pComm_ = new SPiiPlusComm(ACSCommPortName, asynPortName, numChannels);

/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
epicsAtExit(shutdownCallback, pC_);

/*
* MP4U controllers have significantly larger arrays for the AIN, AOUT, IN and OUT commands than the controller
* has I/O channels. Assume the user will specify a numChannels that is appropriate for their controller.
Expand Down Expand Up @@ -195,6 +207,12 @@ void SPiiPlusAuxIO::pollerThread()
while(1) {
lock();

// Stop the thread if the IOC is shutting down
if (shuttingDown_) {
unlock();
break;
}

// assume status is good
status = asynSuccess;

Expand Down
2 changes: 2 additions & 0 deletions acsMotionApp/src/SPiiPlusAuxDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class epicsShareClass SPiiPlusAuxIO : public asynPortDriver {
/* These are methods unique to SPiiPlusAuxIO */
asynStatus writeBits(epicsUInt32 chan, epicsUInt32 mask, epicsUInt32 value);
asynStatus writeAnalog(epicsUInt32 chan, epicsFloat64 value);

int shuttingDown_; /**< Flag indicating that IOC is shutting down. Stops poller */

protected:
SPiiPlusComm *pComm_;
Expand Down
35 changes: 33 additions & 2 deletions acsMotionApp/src/SPiiPlusDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <iocsh.h>
#include <epicsThread.h>
#include <epicsExit.h>
#include <epicsStdlib.h>
#include <epicsString.h>
#include <cantProceed.h>
Expand All @@ -34,6 +35,15 @@ static void SPiiPlusProfileThreadC(void *pPvt);
#define MIN(a,b) ((a)<(b)? (a): (b))
#endif

static void shutdownCallback(void *pPvt)
{
SPiiPlusController *pC = static_cast<SPiiPlusController *>(pPvt);

pC->lock();
pC->shuttingDown_ = 1;
pC->unlock();
}

SPiiPlusController::SPiiPlusController(const char* ACSPortName, const char* asynPortName, int numAxes,
double movingPollPeriod, double idlePollPeriod,
const char* virtualAxisList)
Expand All @@ -56,6 +66,9 @@ SPiiPlusController::SPiiPlusController(const char* ACSPortName, const char* asyn
std::stringstream cmd;
static const char *functionName="SPiiPlusController";

/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
epicsAtExit(shutdownCallback, this);

// Create parameters
createParam(SPiiPlusHomingMethodString, asynParamInt32, &SPiiPlusHomingMethod_);
createParam(SPiiPlusMaxVelocityString, asynParamFloat64, &SPiiPlusMaxVelocity_);
Expand Down Expand Up @@ -1805,9 +1818,27 @@ static void SPiiPlusProfileThreadC(void *pPvt)
/* Function which runs in its own thread to execute profiles */
void SPiiPlusController::profileThread()
{
double timeout;
int status;

/* Is the idle poll period frequent enough to stop the profileMove thread before the IOC stops? */
timeout = movingPollPeriod_;

while (true) {
epicsEventWait(profileExecuteEvent_);
runProfile();
/* Exit the thread if the IOC is shutting down */
lock();
if (shuttingDown_) {
unlock();
break;
} else {
unlock();
}

status = epicsEventWaitWithTimeout(profileExecuteEvent_, timeout);
if (status == epicsEventWaitOK) {
/* We got an event, rather than a timeout */
runProfile();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion acsMotionApp/src/SPiiPlusDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@



// drvInfo strings for extra parameters that the XPS controller supports
// drvInfo strings for extra parameters that the ACS controller supports
#define SPiiPlusHomingMethodString "SPIIPLUS_HOMING_METHOD"
#define SPiiPlusMaxVelocityString "SPIIPLUS_MAX_VELOCITY"
#define SPiiPlusMaxAccelerationString "SPIIPLUS_MAX_ACCELERATION"
Expand Down
Loading