From 35427374f64faa1617760d1f6985b7d694c0903d Mon Sep 17 00:00:00 2001 From: Anders Sandstrom Date: Tue, 2 Mar 2021 13:51:59 +0100 Subject: [PATCH] Add some plc funcs and options. --- .../src/ecmcPluginSocketCAN.c | 50 +++++++++++++++---- .../src/ecmcSocketCAN.cpp | 24 +++++++-- .../src/ecmcSocketCAN.h | 5 +- .../src/ecmcSocketCANDefs.h | 1 + .../src/ecmcSocketCANWrap.cpp | 28 +++++++++++ .../src/ecmcSocketCANWrap.h | 12 ++++- 6 files changed, 104 insertions(+), 16 deletions(-) diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcPluginSocketCAN.c b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcPluginSocketCAN.c index a39ff6a..fe8222b 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcPluginSocketCAN.c +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcPluginSocketCAN.c @@ -153,10 +153,14 @@ int canEnterRT(){ int canExitRT(void){ return 0; } +// Plc function for connect to can +double can_connect() { + return (double)connectSocketCAN(); +} -// Plc function for clear of buffers -double can_clear(double index) { - return (double)0; +// Plc function for connected to connected +double can_connected() { + return (double)getSocketCANConnectd(); } // Register data for plugin so ecmc know what to use @@ -168,7 +172,10 @@ struct ecmcPluginData pluginDataDef = { // Description .desc = "SocketCAN plugin for use with ecmc.", // Option description - .optionDesc = "", + .optionDesc = "\n "ECMC_PLUGIN_DBG_PRINT_OPTION_CMD"<1/0> : Enables/disables printouts from plugin, default = disabled (=0).\n" + " "ECMC_PLUGIN_IF_OPTION_CMD" : Sets can interface (example: can0, vcan0..).\n" + " "ECMC_PLUGIN_CONNECT_OPTION_CMD"<1/0> : Auto connect to if at startup, default = autoconnect (=1).\n" + , // Plugin version .version = ECMC_EXAMPLE_PLUGIN_VERSION, // Optional construct func, called once at load. NULL if not definded. @@ -183,17 +190,17 @@ struct ecmcPluginData pluginDataDef = { .realtimeExitFnc = canExitRT, // PLC funcs .funcs[0] = - { /*----fft_clear----*/ + { /*----can_connect----*/ // Function name (this is the name you use in ecmc plc-code) - .funcName = "can_clear", + .funcName = "can_connect", // Function description - .funcDesc = "double can_clear(index) : Clear/reset can[index].", + .funcDesc = "double can_connect() : Connect to can if (from config str).", /** * 7 different prototypes allowed (only doubles since reg in plc). * Only funcArg${argCount} func shall be assigned the rest set to NULL. **/ - .funcArg0 = NULL, - .funcArg1 = can_clear, + .funcArg0 = can_connect, + .funcArg1 = NULL, .funcArg2 = NULL, .funcArg3 = NULL, .funcArg4 = NULL, @@ -205,7 +212,30 @@ struct ecmcPluginData pluginDataDef = { .funcArg10 = NULL, .funcGenericObj = NULL, }, - .funcs[1] = {0}, // last element set all to zero.. + .funcs[1] = + { /*----can_connected----*/ + // Function name (this is the name you use in ecmc plc-code) + .funcName = "can_connected", + // Function description + .funcDesc = "double can_connected() : Connected to can if.", + /** + * 7 different prototypes allowed (only doubles since reg in plc). + * Only funcArg${argCount} func shall be assigned the rest set to NULL. + **/ + .funcArg0 = can_connected, + .funcArg1 = NULL, + .funcArg2 = NULL, + .funcArg3 = NULL, + .funcArg4 = NULL, + .funcArg5 = NULL, + .funcArg6 = NULL, + .funcArg7 = NULL, + .funcArg8 = NULL, + .funcArg9 = NULL, + .funcArg10 = NULL, + .funcGenericObj = NULL, + }, + .funcs[2] = {0}, // last element set all to zero.. // PLC consts .consts[0] = {0}, // last element set all to zero.. }; diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.cpp b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.cpp index 3ed11ef..41749a9 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.cpp +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.cpp @@ -65,8 +65,10 @@ ecmcSocketCAN::ecmcSocketCAN(char* configStr, // Init cfgCanIFStr_ = NULL; cfgDbgMode_ = 0; + cfgAutoConnect_ = 1; destructs_ = 0; socketId_ = -1; + connected_ = 0; memset(&ifr_,0,sizeof(struct ifreq)); memset(&rxmsg_,0,sizeof(struct can_frame)); memset(&txmsg_,0,sizeof(struct can_frame)); @@ -83,8 +85,11 @@ ecmcSocketCAN::ecmcSocketCAN(char* configStr, if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_read, this) == NULL) { throw std::runtime_error("Error: Failed create worker thread."); } - - initCAN(); + + if(cfgAutoConnect_) { + connect(); + } + initAsyn(); } @@ -115,6 +120,12 @@ void ecmcSocketCAN::parseConfigStr(char *configStr) { cfgDbgMode_ = atoi(pThisOption); } + // ECMC_PLUGIN_CONNECT_OPTION_CMD (1/0) + if (!strncmp(pThisOption, ECMC_PLUGIN_CONNECT_OPTION_CMD, strlen(ECMC_PLUGIN_CONNECT_OPTION_CMD))) { + pThisOption += strlen(ECMC_PLUGIN_DBG_PRINT_OPTION_CMD); + cfgAutoConnect_ = atoi(pThisOption); + } + // ECMC_PLUGIN_IF_OPTION_CMD (Source string) else if (!strncmp(pThisOption, ECMC_PLUGIN_IF_OPTION_CMD, strlen(ECMC_PLUGIN_IF_OPTION_CMD))) { pThisOption += strlen(ECMC_PLUGIN_IF_OPTION_CMD); @@ -130,7 +141,7 @@ void ecmcSocketCAN::parseConfigStr(char *configStr) { } } -void ecmcSocketCAN::initCAN(){ +void ecmcSocketCAN::connect() { if((socketId_ = socket(PF_CAN, SOCK_RAW, CAN_RAW)) == -1) { throw std::runtime_error( "Error while opening socket."); @@ -147,8 +158,13 @@ void ecmcSocketCAN::initCAN(){ if(bind(socketId_, (struct sockaddr *)&addr_, sizeof(addr_)) == -1) { throw std::runtime_error( "Error in socket bind."); - return; + return; } + connected_ = 1; +} + +int ecmcSocketCAN::getConnected() { + return connected_; } // Read socket worker diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.h b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.h index b42be31..ddbef73 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.h +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCAN.h @@ -53,15 +53,18 @@ class ecmcSocketCAN : public asynPortDriver { size_t nElements, size_t *nIn); virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value); + void connect(); + int getConnected(); int writeCAN(); // Add args later private: void parseConfigStr(char *configStr); void initAsyn(); - void initCAN(); static std::string to_string(int value); char* cfgCanIFStr_; // Config: can interface can0, vcan0.. int cfgDbgMode_; + int cfgAutoConnect_; int destructs_; + int connected_; struct can_frame rxmsg_; struct can_frame txmsg_; struct ifreq ifr_; diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANDefs.h b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANDefs.h index dede4d7..12b07e4 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANDefs.h +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANDefs.h @@ -17,6 +17,7 @@ // Options #define ECMC_PLUGIN_DBG_PRINT_OPTION_CMD "DBG_PRINT=" #define ECMC_PLUGIN_IF_OPTION_CMD "IF=" +#define ECMC_PLUGIN_CONNECT_OPTION_CMD "CONNECT=" /** Just one error code in "c" part of plugin (error handled with exceptions i c++ part) */ diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.cpp b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.cpp index ee6894a..258dd54 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.cpp +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.cpp @@ -49,6 +49,34 @@ int createSocketCAN(char* configStr) { return 0; } +int connectSocketCAN() { + if(can){ + try { + can->connect(); + } + catch(std::exception& e) { + printf("Exception: %s.\n",e.what()); + return ECMC_PLUGIN_SOCKETCAN_ERROR_CODE; + } + } + else { + return ECMC_PLUGIN_SOCKETCAN_ERROR_CODE; + } +} + +int getSocketCANConnectd() { + if(can){ + try { + return can->getConnected(); + } + catch(std::exception& e) { + printf("Exception: %s.\n",e.what()); + return 0; + } + } + return 0; +} + void deleteSocketCAN() { if(can) { delete (can); diff --git a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.h b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.h index 006dca7..e682a86 100644 --- a/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.h +++ b/ecmc_plugin_socketcan/ecmc_plugin_socketcanApp/src/ecmcSocketCANWrap.h @@ -27,7 +27,17 @@ extern "C" { * * \return 0 if success or otherwise an error code.\n */ -int createSocketCAN(char *configStr); +int createSocketCAN(char *configStr); + +/** \brief Connect to SocketCAN interface\n + */ + +int connectSocketCAN(); + +/** \brief Connected to can interface\n + */ + +int getSocketCANConnectd(); /** \brief Delete SocketCAN object\n *