Add connect worker thread

This commit is contained in:
Anders Sandstrom
2021-03-02 14:10:26 +01:00
parent 35427374f6
commit 6bf428552f
3 changed files with 50 additions and 8 deletions

View File

@@ -39,6 +39,17 @@ void f_worker_read(void *obj) {
canObj->doReadWorker();
}
// Start worker for socket connect()
void f_worker_connect(void *obj) {
if(!obj) {
printf("%s/%s:%d: Error: Worker connect thread ecmcSocketCAN object NULL..\n",
__FILE__, __FUNCTION__, __LINE__);
return;
}
ecmcSocketCAN * canObj = (ecmcSocketCAN*)obj;
canObj->doConnectWorker();
}
/** ecmc ecmcSocketCAN class
* This object can throw:
* - bad_alloc
@@ -81,13 +92,19 @@ ecmcSocketCAN::ecmcSocketCAN(char* configStr,
}
// Create worker thread for reading socket
std::string threadname = "ecmc." ECMC_PLUGIN_ASYN_PREFIX;
std::string threadname = "ecmc." ECMC_PLUGIN_ASYN_PREFIX".read";
if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_read, this) == NULL) {
throw std::runtime_error("Error: Failed create worker thread.");
throw std::runtime_error("Error: Failed create worker thread for read().");
}
// Create worker thread for connecting socket
threadname = "ecmc." ECMC_PLUGIN_ASYN_PREFIX".connect";
if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_connect, this) == NULL) {
throw std::runtime_error("Error: Failed create worker thread for connect().");
}
if(cfgAutoConnect_) {
connect();
connectPrivate();
}
initAsyn();
@@ -141,7 +158,14 @@ void ecmcSocketCAN::parseConfigStr(char *configStr) {
}
}
void ecmcSocketCAN::connect() {
// For connect commands over asyn or plc. let worker connect
void ecmcSocketCAN::connectExternal() {
if(!connected_) {
doConnectEvent_.signal(); // let worker start
}
}
void ecmcSocketCAN::connectPrivate() {
if((socketId_ = socket(PF_CAN, SOCK_RAW, CAN_RAW)) == -1) {
throw std::runtime_error( "Error while opening socket.");
@@ -176,7 +200,9 @@ void ecmcSocketCAN::doReadWorker() {
break;
}
// Wait for new CAN frame
// Wait for new CAN frame
// TODO MUST CHECK RETRUN VALUE OF READ!!!!!
read(socketId_, &rxmsg_, sizeof(rxmsg_));
if(cfgDbgMode_) {
@@ -190,6 +216,19 @@ void ecmcSocketCAN::doReadWorker() {
}
}
// Read socket worker
void ecmcSocketCAN::doConnectWorker() {
while(true) {
if(destructs_) {
break;
}
doConnectEvent_.wait();
connectPrivate();
}
}
// Test can write function
int ecmcSocketCAN::writeCAN() {
struct can_frame frame;

View File

@@ -45,26 +45,29 @@ class ecmcSocketCAN : public asynPortDriver {
ecmcSocketCAN(char* configStr,
char* portName);
~ecmcSocketCAN();
void doReadWorker();
void doConnectWorker();
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value,
size_t nElements, size_t *nIn);
virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value);
void connect();
void connectExternal();
int getConnected();
int writeCAN(); // Add args later
private:
void parseConfigStr(char *configStr);
void initAsyn();
static std::string to_string(int value);
void connectPrivate();
char* cfgCanIFStr_; // Config: can interface can0, vcan0..
int cfgDbgMode_;
int cfgAutoConnect_;
int destructs_;
int connected_;
epicsEvent doConnectEvent_;
struct can_frame rxmsg_;
struct can_frame txmsg_;
struct ifreq ifr_;

View File

@@ -52,7 +52,7 @@ int createSocketCAN(char* configStr) {
int connectSocketCAN() {
if(can){
try {
can->connect();
can->connectExternal();
}
catch(std::exception& e) {
printf("Exception: %s.\n",e.what());