Add some plc funcs and options.

This commit is contained in:
Anders Sandstrom
2021-03-02 13:51:59 +01:00
parent 9e729db05e
commit 35427374f6
6 changed files with 104 additions and 16 deletions

View File

@@ -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"<if name> : 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..
};

View File

@@ -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

View File

@@ -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_;

View File

@@ -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) */

View File

@@ -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);

View File

@@ -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
*