491 |
491 |
492 int __cleanup_%(locstr)s (); |
492 int __cleanup_%(locstr)s (); |
493 int __init_%(locstr)s (int argc, char **argv){ |
493 int __init_%(locstr)s (int argc, char **argv){ |
494 int index; |
494 int index; |
495 |
495 |
496 for (index=0; index < NUMBER_OF_CLIENT_NODES;index++) |
496 for (index=0; index < NUMBER_OF_CLIENT_NODES;index++) { |
497 client_nodes[index].mb_nd = -1; |
497 client_nodes[index].mb_nd = -1; |
498 for (index=0; index < NUMBER_OF_SERVER_NODES;index++) |
498 /* see comment in mb_runtime.h to understad why we need to initialize these entries */ |
|
499 switch (client_nodes[index].node_address.naf) { |
|
500 case naf_tcp: |
|
501 client_nodes[index].node_address.addr.tcp.host = client_nodes[index].str1; |
|
502 client_nodes[index].node_address.addr.tcp.service = client_nodes[index].str2; |
|
503 break; |
|
504 case naf_rtu: |
|
505 client_nodes[index].node_address.addr.rtu.device = client_nodes[index].str1; |
|
506 break; |
|
507 } |
|
508 } |
|
509 |
|
510 for (index=0; index < NUMBER_OF_SERVER_NODES;index++) { |
499 // mb_nd with negative numbers indicate how far it has been initialised (or not) |
511 // mb_nd with negative numbers indicate how far it has been initialised (or not) |
500 // -2 --> no modbus node created; no thread created |
512 // -2 --> no modbus node created; no thread created |
501 // -1 --> modbus node created!; no thread created |
513 // -1 --> modbus node created!; no thread created |
502 // >=0 --> modbus node created!; thread created! |
514 // >=0 --> modbus node created!; thread created! |
503 server_nodes[index].mb_nd = -2; |
515 server_nodes[index].mb_nd = -2; |
|
516 } |
504 |
517 |
505 /* modbus library init */ |
518 /* modbus library init */ |
506 /* Note that TOTAL_xxxNODE_COUNT are the nodes required by _ALL_ the instances of the modbus |
519 /* Note that TOTAL_xxxNODE_COUNT are the nodes required by _ALL_ the instances of the modbus |
507 * extension currently in the user's project. This file (MB_xx.c) is handling only one instance, |
520 * extension currently in the user's project. This file (MB_xx.c) is handling only one instance, |
508 * but must initialize the library for all instances. Only the first call to mb_slave_and_master_init() |
521 * but must initialize the library for all instances. Only the first call to mb_slave_and_master_init() |
813 } |
826 } |
814 |
827 |
815 return res; |
828 return res; |
816 } |
829 } |
817 |
830 |
|
831 |
|
832 |
|
833 |
|
834 |
|
835 /**********************************************/ |
|
836 /** Functions for Beremiz web interface. **/ |
|
837 /**********************************************/ |
|
838 |
|
839 /* |
|
840 * Beremiz has a program to run on the PLC (Beremiz_service.py) |
|
841 * to handle downloading of compiled programs, start/stop of PLC, etc. |
|
842 * (see runtime/PLCObject.py for start/stop, loading, ...) |
|
843 * |
|
844 * This service also includes a web server to access PLC state (start/stop) |
|
845 * and to change some basic confiuration parameters. |
|
846 * (see runtime/NevowServer.py for the web server) |
|
847 * |
|
848 * The web server allows for extensions, where additional configuration |
|
849 * parameters may be changed on the running/downloaded PLC. |
|
850 * Modbus plugin also comes with an extension to the web server, through |
|
851 * which the basic Modbus plugin configuration parameters may be changed |
|
852 * |
|
853 * These parameters are changed _after_ the code (.so file) is loaded into |
|
854 * memmory. These changes may be applied before (or after) the code starts |
|
855 * running (i.e. before or after __init_() ets called)! |
|
856 * |
|
857 * The following functions are never called from other C code. They are |
|
858 * called instead from the python code in runtime/Modbus_config.py, that |
|
859 * implements the web server extension for configuring Modbus parameters. |
|
860 */ |
|
861 |
|
862 |
|
863 /* The number of Cient nodes (i.e. the number of entries in the client_nodes array) |
|
864 * The number of Server nodes (i.e. the numb. of entries in the server_nodes array) |
|
865 * |
|
866 * These variables are also used by the Modbus web config code to determine |
|
867 * whether the current loaded PLC includes the Modbus plugin |
|
868 * (so it should make the Modbus parameter web interface visible to the user). |
|
869 */ |
|
870 const int __modbus_plugin_client_node_count = NUMBER_OF_CLIENT_NODES; |
|
871 const int __modbus_plugin_server_node_count = NUMBER_OF_SERVER_NODES; |
|
872 const int __modbus_plugin_param_string_size = MODBUS_PARAM_STRING_SIZE; |
|
873 |
|
874 |
|
875 |
|
876 /* NOTE: We could have the python code in runtime/Modbus_config.py |
|
877 * directly access the server_node_t and client_node_t structures, |
|
878 * however this would create a tight coupling between these two |
|
879 * disjoint pieces of code. |
|
880 * Any change to the server_node_t or client_node_t structures would |
|
881 * require the python code to be changed accordingly. I have therefore |
|
882 * opted to create get/set functions, one for each parameter. |
|
883 * |
|
884 * We also convert the enumerated constants naf_ascii, etc... |
|
885 * (from node_addr_family_t in modbus/mb_addr.h) |
|
886 * into strings so as to decouple the python code that will be calling |
|
887 * these functions from the Modbus library code definitions. |
|
888 */ |
|
889 const char *addr_type_str[] = { |
|
890 [naf_ascii] = "ascii", |
|
891 [naf_rtu ] = "rtu", |
|
892 [naf_tcp ] = "tcp" |
|
893 }; |
|
894 |
|
895 |
|
896 #define __safe_strcnpy(str_dest, str_orig, max_size) { \ |
|
897 strncpy(str_dest, str_orig, max_size); \ |
|
898 str_dest[max_size - 1] = '\0'; \ |
|
899 } |
|
900 |
|
901 |
|
902 /* NOTE: The host, port and device parameters are strings that may be changed |
|
903 * (by calling the following functions) after loading the compiled code |
|
904 * (.so file) into memory, but before the code starts running |
|
905 * (i.e. before __init_() gets called). |
|
906 * This means that the host, port and device parameters may be changed |
|
907 * _before_ they get mapped onto the str1 and str2 variables by __init_(), |
|
908 * which is why the following functions must access the str1 and str2 |
|
909 * parameters directly. |
|
910 */ |
|
911 const char * __modbus_get_ClientNode_config_name(int nodeid) {return client_nodes[nodeid].config_name; } |
|
912 const char * __modbus_get_ClientNode_host (int nodeid) {return client_nodes[nodeid].str1; } |
|
913 const char * __modbus_get_ClientNode_port (int nodeid) {return client_nodes[nodeid].str2; } |
|
914 const char * __modbus_get_ClientNode_device (int nodeid) {return client_nodes[nodeid].str1; } |
|
915 int __modbus_get_ClientNode_baud (int nodeid) {return client_nodes[nodeid].node_address.addr.rtu.baud; } |
|
916 int __modbus_get_ClientNode_parity (int nodeid) {return client_nodes[nodeid].node_address.addr.rtu.parity; } |
|
917 int __modbus_get_ClientNode_stop_bits (int nodeid) {return client_nodes[nodeid].node_address.addr.rtu.stop_bits;} |
|
918 u64 __modbus_get_ClientNode_comm_period(int nodeid) {return client_nodes[nodeid].comm_period; } |
|
919 const char * __modbus_get_ClientNode_addr_type (int nodeid) {return addr_type_str[client_nodes[nodeid].node_address.naf];} |
|
920 |
|
921 const char * __modbus_get_ServerNode_config_name(int nodeid) {return server_nodes[nodeid].config_name; } |
|
922 const char * __modbus_get_ServerNode_host (int nodeid) {return server_nodes[nodeid].node_address.addr.tcp.host; } |
|
923 const char * __modbus_get_ServerNode_port (int nodeid) {return server_nodes[nodeid].node_address.addr.tcp.service; } |
|
924 const char * __modbus_get_ServerNode_device (int nodeid) {return server_nodes[nodeid].node_address.addr.rtu.device; } |
|
925 int __modbus_get_ServerNode_baud (int nodeid) {return server_nodes[nodeid].node_address.addr.rtu.baud; } |
|
926 int __modbus_get_ServerNode_parity (int nodeid) {return server_nodes[nodeid].node_address.addr.rtu.parity; } |
|
927 int __modbus_get_ServerNode_stop_bits (int nodeid) {return server_nodes[nodeid].node_address.addr.rtu.stop_bits;} |
|
928 const char * __modbus_get_ServerNode_addr_type (int nodeid) {return addr_type_str[server_nodes[nodeid].node_address.naf];} |
|
929 |
|
930 |
|
931 void __modbus_set_ClientNode_host (int nodeid, const char * value) {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);} |
|
932 void __modbus_set_ClientNode_port (int nodeid, const char * value) {__safe_strcnpy(client_nodes[nodeid].str2, value, MODBUS_PARAM_STRING_SIZE);} |
|
933 void __modbus_set_ClientNode_device (int nodeid, const char * value) {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);} |
|
934 void __modbus_set_ClientNode_baud (int nodeid, int value) {client_nodes[nodeid].node_address.addr.rtu.baud = value;} |
|
935 void __modbus_set_ClientNode_parity (int nodeid, int value) {client_nodes[nodeid].node_address.addr.rtu.parity = value;} |
|
936 void __modbus_set_ClientNode_stop_bits (int nodeid, int value) {client_nodes[nodeid].node_address.addr.rtu.stop_bits = value;} |
|
937 void __modbus_set_ClientNode_comm_period(int nodeid, u64 value) {client_nodes[nodeid].comm_period = value;} |
|
938 |
|
939 |
|
940 |