-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing Modbus TCP Server Sample #530
Comments
I had the same issue recently.
Below is a Hello World Modbus TCP server.
Hope this helps.
I have the following in my main() function.
//Start Modbus slave/server thread
pthread_t thread_id;
pthread_create(&thread_id, NULL, modbus_main, NULL);
/*
Hello World: Modbus slave function. Address node 3, data in registers 40001, 40002, and 40003
/*
void *modbus_main(void *x) {
int i;
int server_socket = -1;
modbus_t *ctx;
ctx = modbus_new_tcp(NULL, 502);
// modbus_set_debug(ctx, TRUE);
int header_length = modbus_get_header_length(ctx);
server_socket = modbus_tcp_listen(ctx, 2); //Listen to max two connection
//This next line will block program execution until there is a connection made
modbus_tcp_accept(ctx, &server_socket);
modbus_mapping_t *mb_map, *mb_mapping[100]; //Array of pointers for each device
//this sets up 500 holding registers starting at 40001
mb_map = modbus_mapping_new(0, 0, 500, 0);
mb_mapping[1] = mb_map;
if (mb_mapping[1] == NULL) {
fprintf(stderr, "Failed to allocate the mapping: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return;
}
for (;;) {
uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
int rc;
do {
rc = modbus_receive(ctx, query);
/* Filtered queries return 0 */
} while (rc == 0);
/* The connection is not closed on errors which require on reply such as
bad CRC in RTU.
*/
if (rc == -1 && errno != EMBBADCRC) {
/* Quit */
break; //the loop
}
//Set up some dummy data
mb_mapping[1]->tab_registers[0] = rand() % 1000;
mb_mapping[1]->tab_registers[1] = rand() % 100;
mb_mapping[1]->tab_registers[2] = 333;
//See here for a description of the query
//http://www.simplymodbus.ca/FC03.htm
printf("Node=%d function=%d num registers=%d start addr=%d\n", query[header_length - 1], query[header_length], MODBUS_GET_INT16_FROM_INT8(query, header_length + 3), MODBUS_GET_INT16_FROM_INT8(query, header_length + 1) + 40001);
//query[6] = modbus node address
//query[7] = modbus function
if (query[6] != 3) { //If the node is NOT correct
modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_GATEWAY_TARGET);
continue;
} else {
/* Return data */
/* rc is the query size */
modbus_reply(ctx, query, rc, mb_mapping[1]);
}
}
printf("Quit the loop: %s\n", modbus_strerror(errno));
if (server_socket != -1) {
close(server_socket);
}
modbus_mapping_free(mb_mapping[1]);
modbus_close(ctx);
modbus_free(ctx);
}
From: Nick Apperley <notifications@github.com>
Sent: Wednesday, April 8, 2020 10:42 PM
To: stephane/libmodbus <libmodbus@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Subject: [stephane/libmodbus] Missing Modbus TCP Server Sample (#530)
Although there is a C source file <https://github.com/stephane/libmodbus/blob/master/tests/unit-test-server.c> showing how to do a Modbus server it covers far too much (it is too complex), and lacks focus on a specific area. To make matters worse the source file isn't extensively documented (especially on memory management, and how to send a response back to the client with register data set in the response), and lacks proper code structure (all logic is done in a enormous sized main function).
The libmodbus library would greatly benefit from having a small Modbus TCP server sample that only focuses on a single area, and shows the minimum required to get a Modbus TCP server implemented.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub <#530> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAFDSAKLM6IJW6CVTBQER43RLUYXLANCNFSM4MEMNACQ> . <https://github.com/notifications/beacon/AAFDSAJVOLP543N3PSR2XQDRLUYXLA5CNFSM4MEMNAC2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4I4VGNUQ.gif>
|
That example doesn't work. An error message appears after sending the reply on the server side:
|
0x9c44 is simply not in range of the registers setup in @watsocd 's example, so it's behaving exactly as expected. They setup 500 holding registers, and no input registers. |
Code comment at the top: Of course no/limited error checking. IT IS a Hello World minimal example for holding (40000) registers. |
Caution: this demo server code only serve for one client. |
The code above gives me segmentation fault during runtime. So does the random-test-server when i access the mb_mapping->tab_registers[0] to print or to assign some value to it. Without accessing the mb_mapping->tab_registers[index] it runs fine. As a sever i want to assign some values in the tab_registers array. Any kind of help is greatly appreciated. I am running it in rhel 7 with libmodbus-3.1.10 installed. |
Although there is a C source file showing how to do a Modbus server it covers far too much (it is too complex), and lacks focus on a specific area. To make matters worse the source file isn't extensively documented (especially on memory management, and how to send a response back to the client with register data set in the response), and lacks proper code structure (all logic is done in a enormous sized main function).
The libmodbus library would greatly benefit from having a small Modbus TCP server sample that only focuses on a single area, and shows the minimum required to get a Modbus TCP server implemented.
The text was updated successfully, but these errors were encountered: