diff -r db68cb0e6bdc -r 7575050a80c5 modbus/mb_runtime.c --- 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;} + + +