modbus/mb_runtime.c
changeset 3733 d1acf20e8e7c
parent 2723 cde2e410b874
child 3859 098875cff39f
equal deleted inserted replaced
3625:bb1eff4091ab 3733:d1acf20e8e7c
   371 		/*
   371 		/*
   372 		struct timespec cur_time;
   372 		struct timespec cur_time;
   373 		clock_gettime(CLOCK_MONOTONIC, &cur_time);
   373 		clock_gettime(CLOCK_MONOTONIC, &cur_time);
   374 		fprintf(stderr, "Modbus client thread (%%d) - new cycle (%%ld:%%ld)!\n", client_node_id, cur_time.tv_sec, cur_time.tv_nsec);
   374 		fprintf(stderr, "Modbus client thread (%%d) - new cycle (%%ld:%%ld)!\n", client_node_id, cur_time.tv_sec, cur_time.tv_nsec);
   375 		*/
   375 		*/
       
   376 		
       
   377 		/* Variable use to specify delay to introduce between any two consecutive requests we send out to the same client
       
   378 		 * Initially set to 0 since we don't want to introduce a delay before the very first request.
       
   379 		 */
       
   380 		struct timespec inter_request_delay;
       
   381 		inter_request_delay.tv_sec  = 0;
       
   382 		inter_request_delay.tv_nsec = 0;
       
   383 		
   376 		int req;
   384 		int req;
   377 		for (req=0; req < NUMBER_OF_CLIENT_REQTS; req ++){
   385 		for (req=0; req < NUMBER_OF_CLIENT_REQTS; req ++){
   378 			/* just do the requests belonging to the client */
   386 			/* just do the requests belonging to the client */
   379 			if (client_requests[req].client_node_id != client_node_id)
   387 			if (client_requests[req].client_node_id != client_node_id)
   380 				continue;
   388 				continue;
   390             
   398             
   391             /*
   399             /*
   392             fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
   400             fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
   393                     client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
   401                     client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
   394             */
   402             */
       
   403 			
       
   404 			/* Insert a delay between any two consecutive requests to the same client
       
   405 			 * Needed because some clients will ignore our requests if we send them out too fast.
       
   406 			 *
       
   407 			 * Note that since we don't want to insert a delay before the very first request we will send, the inter_request_delay variable
       
   408 			 * is first initialised to 0. It will be set to the correct delay after the first (and second, third, etc..) request has completed.
       
   409 			 */
       
   410 			clock_nanosleep(CLOCK_MONOTONIC, 0 /* relative sleep */, &inter_request_delay, NULL);
   395             
   411             
   396 			int res_tmp = __execute_mb_request(req);
   412 			int res_tmp = __execute_mb_request(req);
   397 			client_requests[req].tn_error_code = 0; // assume success
   413 			client_requests[req].tn_error_code = 0; // assume success
   398 			switch (res_tmp) {
   414 			switch (res_tmp) {
   399 			  case PORT_FAILURE: {
   415 			  case PORT_FAILURE: {
   447              * knows how the communication is going.
   463              * knows how the communication is going.
   448              */
   464              */
   449             client_requests[req].flag_mb_error_code = client_requests[req].mb_error_code;
   465             client_requests[req].flag_mb_error_code = client_requests[req].mb_error_code;
   450             client_requests[req].flag_tn_error_code = client_requests[req].tn_error_code;
   466             client_requests[req].flag_tn_error_code = client_requests[req].tn_error_code;
   451             
   467             
   452             /* We have just finished excuting a client transcation request.
   468             /* We have just finished executing a client transaction request.
   453              * If the current cycle was activated by user request we reset the flag used to ask to run it
   469              * If the current cycle was activated by user request we reset the flag used to ask to run it
   454              */
   470              */
   455             if (0 != client_requests[req].flag_exec_req) {
   471             if (0 != client_requests[req].flag_exec_req) {
   456                 client_requests[req].flag_exec_req     = 0;
   472                 client_requests[req].flag_exec_req     = 0;
   457                 client_requests[req].flag_exec_started = 0;   
   473                 client_requests[req].flag_exec_started = 0;   
   458             }
   474             }
       
   475             
       
   476             /* We have just finished executing a client transaction request.
       
   477              * Set the inter request delay before we send the next request. Value of delay is set by user in beremiz GUI
       
   478              */
       
   479             inter_request_delay.tv_sec  =  client_nodes[client_node_id].req_delay / 1000; /* ms to seconds */
       
   480             inter_request_delay.tv_nsec = (client_nodes[client_node_id].req_delay %% 1000) * 1000 * 1000; /* ms to ns */
   459             
   481             
   460             //fprintf(stderr, "Modbus plugin: RUNNING<---> of Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
   482             //fprintf(stderr, "Modbus plugin: RUNNING<---> of Modbus request %%d  (periodic = %%d  flag_exec_req = %%d)\n", 
   461             //        req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
   483             //        req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req );
   462         }
   484         }
   463 
   485 
   954  * These parameters are changed _after_ the code (.so file) is loaded into 
   976  * These parameters are changed _after_ the code (.so file) is loaded into 
   955  * memmory. These changes may be applied before (or after) the code starts
   977  * memmory. These changes may be applied before (or after) the code starts
   956  * running (i.e. before or after __init_() ets called)! 
   978  * running (i.e. before or after __init_() ets called)! 
   957  * 
   979  * 
   958  * The following functions are never called from other C code. They are 
   980  * The following functions are never called from other C code. They are 
   959  * called instead from the python code in runtime/Modbus_config.py, that
   981  * called instead from the python code in modbus/web_settings.py, that
   960  * implements the web server extension for configuring Modbus parameters.
   982  * implements the web server extension for configuring Modbus parameters.
   961  */
   983  */
   962 
   984 
   963 
   985 
   964 /* The number of Cient nodes (i.e. the number of entries in the client_nodes array)
   986 /* The number of Cient nodes (i.e. the number of entries in the client_nodes array)
   972 const int __modbus_plugin_server_node_count = NUMBER_OF_SERVER_NODES;
   994 const int __modbus_plugin_server_node_count = NUMBER_OF_SERVER_NODES;
   973 const int __modbus_plugin_param_string_size = MODBUS_PARAM_STRING_SIZE;
   995 const int __modbus_plugin_param_string_size = MODBUS_PARAM_STRING_SIZE;
   974 
   996 
   975 
   997 
   976 
   998 
   977 /* NOTE: We could have the python code in runtime/Modbus_config.py
   999 /* NOTE: We could have the python code in modbus/web_settings.py
   978  *       directly access the server_node_t and client_node_t structures,
  1000  *       directly access the server_node_t and client_node_t structures,
   979  *       however this would create a tight coupling between these two
  1001  *       however this would create a tight coupling between these two
   980  *       disjoint pieces of code.
  1002  *       disjoint pieces of code.
   981  *       Any change to the server_node_t or client_node_t structures would
  1003  *       Any change to the server_node_t or client_node_t structures would
   982  *       require the python code to be changed accordingly. I have therefore 
  1004  *       require the python code to be changed accordingly. I have therefore 
  1015 const char *       __modbus_get_ClientNode_device     (int nodeid)  {return client_nodes[nodeid].str1;                           }
  1037 const char *       __modbus_get_ClientNode_device     (int nodeid)  {return client_nodes[nodeid].str1;                           }
  1016 int                __modbus_get_ClientNode_baud       (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.baud;     }
  1038 int                __modbus_get_ClientNode_baud       (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.baud;     }
  1017 int                __modbus_get_ClientNode_parity     (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.parity;   }
  1039 int                __modbus_get_ClientNode_parity     (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.parity;   }
  1018 int                __modbus_get_ClientNode_stop_bits  (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.stop_bits;}
  1040 int                __modbus_get_ClientNode_stop_bits  (int nodeid)  {return client_nodes[nodeid].node_address.addr.rtu.stop_bits;}
  1019 u64                __modbus_get_ClientNode_comm_period(int nodeid)  {return client_nodes[nodeid].comm_period;                    }
  1041 u64                __modbus_get_ClientNode_comm_period(int nodeid)  {return client_nodes[nodeid].comm_period;                    }
       
  1042 u64                __modbus_get_ClientNode_req_delay  (int nodeid)  {return client_nodes[nodeid].req_delay;                      }
  1020 const char *       __modbus_get_ClientNode_addr_type  (int nodeid)  {return addr_type_str[client_nodes[nodeid].node_address.naf];}
  1043 const char *       __modbus_get_ClientNode_addr_type  (int nodeid)  {return addr_type_str[client_nodes[nodeid].node_address.naf];}
  1021                                                                                                                         
  1044                                                                                                                         
  1022 const char *       __modbus_get_ServerNode_config_name(int nodeid)  {return server_nodes[nodeid].config_name;                    }
  1045 const char *       __modbus_get_ServerNode_config_name(int nodeid)  {return server_nodes[nodeid].config_name;                    }
  1023 const char *       __modbus_get_ServerNode_host       (int nodeid)  {char*x=server_nodes[nodeid].str1; return (x[0]=='\0'?"#ANY#":x); }
  1046 const char *       __modbus_get_ServerNode_host       (int nodeid)  {char*x=server_nodes[nodeid].str1; return (x[0]=='\0'?"#ANY#":x); }
  1024 const char *       __modbus_get_ServerNode_port       (int nodeid)  {return server_nodes[nodeid].str2;                           }
  1047 const char *       __modbus_get_ServerNode_port       (int nodeid)  {return server_nodes[nodeid].str2;                           }
  1035 void __modbus_set_ClientNode_device     (int nodeid, const char * value)  {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
  1058 void __modbus_set_ClientNode_device     (int nodeid, const char * value)  {__safe_strcnpy(client_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
  1036 void __modbus_set_ClientNode_baud       (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.baud      = value;}
  1059 void __modbus_set_ClientNode_baud       (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.baud      = value;}
  1037 void __modbus_set_ClientNode_parity     (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.parity    = value;}
  1060 void __modbus_set_ClientNode_parity     (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.parity    = value;}
  1038 void __modbus_set_ClientNode_stop_bits  (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.stop_bits = value;}
  1061 void __modbus_set_ClientNode_stop_bits  (int nodeid, int          value)  {client_nodes[nodeid].node_address.addr.rtu.stop_bits = value;}
  1039 void __modbus_set_ClientNode_comm_period(int nodeid, u64          value)  {client_nodes[nodeid].comm_period                     = value;}
  1062 void __modbus_set_ClientNode_comm_period(int nodeid, u64          value)  {client_nodes[nodeid].comm_period                     = value;}
       
  1063 void __modbus_set_ClientNode_req_delay  (int nodeid, u64          value)  {client_nodes[nodeid].req_delay                       = value;}
  1040                                                                                                                         
  1064                                                                                                                         
  1041 
  1065 
  1042 void __modbus_set_ServerNode_host       (int nodeid, const char * value)  {if (strcmp(value,"#ANY#")==0) value = "";
  1066 void __modbus_set_ServerNode_host       (int nodeid, const char * value)  {if (strcmp(value,"#ANY#")==0) value = "";
  1043                                                                            __safe_strcnpy(server_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
  1067                                                                            __safe_strcnpy(server_nodes[nodeid].str1, value, MODBUS_PARAM_STRING_SIZE);}
  1044 void __modbus_set_ServerNode_port       (int nodeid, const char * value)  {__safe_strcnpy(server_nodes[nodeid].str2, value, MODBUS_PARAM_STRING_SIZE);}
  1068 void __modbus_set_ServerNode_port       (int nodeid, const char * value)  {__safe_strcnpy(server_nodes[nodeid].str2, value, MODBUS_PARAM_STRING_SIZE);}