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