modbus/mb_runtime.c
changeset 2654 7575050a80c5
parent 2647 990004083eb8
child 2655 d2b2ee04bfa1
--- a/modbus/mb_runtime.c	Thu May 28 11:15:22 2020 +0100
+++ b/modbus/mb_runtime.c	Mon Jun 01 08:54:26 2020 +0100
@@ -493,14 +493,27 @@
 int __init_%(locstr)s (int argc, char **argv){
 	int index;
 
-	for (index=0; index < NUMBER_OF_CLIENT_NODES;index++)
+	for (index=0; index < NUMBER_OF_CLIENT_NODES;index++) {
 		client_nodes[index].mb_nd = -1;
-	for (index=0; index < NUMBER_OF_SERVER_NODES;index++)
+        /* see comment in mb_runtime.h to understad why we need to initialize these entries */
+        switch (client_nodes[index].node_address.naf) {
+            case naf_tcp:
+                client_nodes[index].node_address.addr.tcp.host    = client_nodes[index].str1;
+                client_nodes[index].node_address.addr.tcp.service = client_nodes[index].str2;
+                break;
+            case naf_rtu:
+                client_nodes[index].node_address.addr.rtu.device  = client_nodes[index].str1;
+                break;
+        }
+    }
+
+	for (index=0; index < NUMBER_OF_SERVER_NODES;index++) {
 		// mb_nd with negative numbers indicate how far it has been initialised (or not)
 		//   -2  --> no modbus node created;  no thread  created
 		//   -1  -->    modbus node created!; no thread  created
 		//  >=0  -->    modbus node created!;    thread  created!
 		server_nodes[index].mb_nd = -2; 
+	}
 
 	/* modbus library init */
 	/* Note that TOTAL_xxxNODE_COUNT are the nodes required by _ALL_ the instances of the modbus
@@ -815,3 +828,113 @@
 	return res;
 }
 
+
+
+
+
+/**********************************************/
+/** Functions for Beremiz web interface.     **/
+/**********************************************/
+
+/*
+ * Beremiz has a program to run on the PLC (Beremiz_service.py)
+ * to handle downloading of compiled programs, start/stop of PLC, etc.
+ * (see runtime/PLCObject.py for start/stop, loading, ...)
+ * 
+ * This service also includes a web server to access PLC state (start/stop)
+ * and to change some basic confiuration parameters.
+ * (see runtime/NevowServer.py for the web server)
+ * 
+ * The web server allows for extensions, where additional configuration
+ * parameters may be changed on the running/downloaded PLC.
+ * Modbus plugin also comes with an extension to the web server, through
+ * which the basic Modbus plugin configuration parameters may be changed
+ * 
+ * These parameters are changed _after_ the code (.so file) is loaded into 
+ * memmory. These changes may be applied before (or after) the code starts
+ * running (i.e. before or after __init_() ets called)! 
+ * 
+ * The following functions are never called from other C code. They are 
+ * called instead from the python code in runtime/Modbus_config.py, that
+ * implements the web server extension for configuring Modbus parameters.
+ */
+
+
+/* The number of Cient nodes (i.e. the number of entries in the client_nodes array)
+ * The number of Server nodes (i.e. the numb. of entries in the server_nodes array)
+ * 
+ * These variables are also used by the Modbus web config code to determine 
+ * whether the current loaded PLC includes the Modbus plugin
+ * (so it should make the Modbus parameter web interface visible to the user).
+ */
+const int __modbus_plugin_client_node_count = NUMBER_OF_CLIENT_NODES;
+const int __modbus_plugin_server_node_count = NUMBER_OF_SERVER_NODES;
+const int __modbus_plugin_param_string_size = MODBUS_PARAM_STRING_SIZE;
+
+
+
+/* NOTE: We could have the python code in runtime/Modbus_config.py
+ *       directly access the server_node_t and client_node_t structures,
+ *       however this would create a tight coupling between these two
+ *       disjoint pieces of code.
+ *       Any change to the server_node_t or client_node_t structures would
+ *       require the python code to be changed accordingly. I have therefore 
+ *       opted to create get/set functions, one for each parameter.
+ * 
+ *       We also convert the enumerated constants naf_ascii, etc...
+ *       (from node_addr_family_t in modbus/mb_addr.h)
+ *       into strings so as to decouple the python code that will be calling
+ *       these functions from the Modbus library code definitions.
+ */
+const char *addr_type_str[] = {
+        [naf_ascii] = "ascii",
+        [naf_rtu  ] = "rtu",
+        [naf_tcp  ] = "tcp"    
+};
+
+
+#define __safe_strcnpy(str_dest, str_orig, max_size) {  \
+    strncpy(str_dest, str_orig, max_size);              \
+    str_dest[max_size - 1] = '\0';                      \
+}
+
+
+/* NOTE: The host, port and device parameters are strings that may be changed 
+ *       (by calling the following functions) after loading the compiled code 
+ *       (.so file) into memory, but before the code starts running
+ *       (i.e. before __init_() gets called).
+ *       This means that the host, port and device parameters may be changed
+ *       _before_ they get mapped onto the str1 and str2 variables by __init_(),
+ *       which is why the following functions must access the str1 and str2 
+ *       parameters directly.
+ */
+const char *       __modbus_get_ClientNode_config_name(int nodeid)  {return client_nodes[nodeid].config_name;                    }
+const char *       __modbus_get_ClientNode_host       (int nodeid)  {return client_nodes[nodeid].str1;                           }
+const char *       __modbus_get_ClientNode_port       (int nodeid)  {return client_nodes[nodeid].str2;                           }
+const char *       __modbus_get_ClientNode_device     (int nodeid)  {return client_nodes[nodeid].str1;                           }
+int                __modbus_get_ClientNode_baud       (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.baud;     }
+int                __modbus_get_ClientNode_parity     (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.parity;   }
+int                __modbus_get_ClientNode_stop_bits  (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.stop_bits;}
+u64                __modbus_get_ClientNode_comm_period(int nodeid)  {return client_nodes[nodeid].comm_period;                    }
+const char *       __modbus_get_ClientNode_addr_type  (int nodeid)  {return addr_type_str[client_nodes[nodeid].node_address.naf];}
+                                                                                                                        
+const char *       __modbus_get_ServerNode_config_name(int nodeid)  {return server_nodes[nodeid].config_name;                    }
+const char *       __modbus_get_ServerNode_host       (int nodeid)  {return server_nodes[nodeid].node_address.addr.tcp.host;     }
+const char *       __modbus_get_ServerNode_port       (int nodeid)  {return server_nodes[nodeid].node_address.addr.tcp.service;  }
+const char *       __modbus_get_ServerNode_device     (int nodeid)  {return server_nodes[nodeid].node_address.addr.rtu.device;   }
+int                __modbus_get_ServerNode_baud       (int nodeid)  {return server_nodes[nodeid].node_address.addr.rtu.baud;     }
+int                __modbus_get_ServerNode_parity     (int nodeid)  {return server_nodes[nodeid].node_address.addr.rtu.parity;   }
+int                __modbus_get_ServerNode_stop_bits  (int nodeid)  {return server_nodes[nodeid].node_address.addr.rtu.stop_bits;}
+const char *       __modbus_get_ServerNode_addr_type  (int nodeid)  {return addr_type_str[server_nodes[nodeid].node_address.naf];}
+
+
+void __modbus_set_ClientNode_host       (int nodeid, const char * value)  {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
+void __modbus_set_ClientNode_port       (int nodeid, const char * value)  {__safe_strcnpy(client_nodes[nodeid].str2, value, MODBUS_PARAM_STRING_SIZE);}
+void __modbus_set_ClientNode_device     (int nodeid, const char * value)  {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
+void __modbus_set_ClientNode_baud       (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.baud      = value;}
+void __modbus_set_ClientNode_parity     (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.parity    = value;}
+void __modbus_set_ClientNode_stop_bits  (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.stop_bits = value;}
+void __modbus_set_ClientNode_comm_period(int nodeid, u64          value)  {client_nodes[nodeid].comm_period                     = value;}
+                                                                                                                        
+
+