Updated examples

This commit is contained in:
Valerio De Benedetto 2022-06-02 11:10:42 +02:00
parent 7f811f2338
commit 76f28fefb9
3 changed files with 112 additions and 92 deletions

View File

@ -1,7 +1,3 @@
#include "nanomodbus.h"
#include "platform.h"
#include <stdio.h>
/*
* This example application connects via TCP to a modbus server at the specified address and port, and sends some
* modbus requests to it.
@ -9,9 +5,14 @@
* Since the platform for this example is linux, the platform arg is used to pass (to the linux TCP read/write
* functions) a pointer to the file descriptor of our TCP connection
*
* The platform functions are for Linux systems.
*/
#include <stdio.h>
#include "nanomodbus.h"
#include "platform.h"
int main(int argc, char* argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: client-tcp [address] [port]\n");
@ -27,9 +28,8 @@ int main(int argc, char* argv[]) {
nmbs_platform_conf platform_conf;
platform_conf.transport = NMBS_TRANSPORT_TCP;
platform_conf.read_byte = read_byte_fd_linux;
platform_conf.write_byte = write_byte_fd_linux;
platform_conf.sleep = sleep_linux;
platform_conf.read = read_fd_linux;
platform_conf.write = write_fd_linux;
platform_conf.arg = conn; // Passing our TCP connection handle to the read/write functions
// Create the modbus client

View File

@ -1,86 +1,20 @@
#include "nanomodbus.h"
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
// Read/write/sleep platform functions
int read_byte_fd_linux(uint8_t* b, int32_t timeout_ms, void* arg) {
int fd = *(int*) arg;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
struct timeval* tv_p = NULL;
struct timeval tv;
if (timeout_ms >= 0) {
tv_p = &tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
}
int ret = select(fd + 1, &rfds, NULL, NULL, tv_p);
if (ret == 0) {
return 0;
}
else if (ret == 1) {
ssize_t r = read(fd, b, 1);
if (r != 1)
return -1;
else {
return 1;
}
}
else
return -1;
}
#include "nanomodbus.h"
int write_byte_fd_linux(uint8_t b, int32_t timeout_ms, void* arg) {
int fd = *(int*) arg;
fd_set wfds;
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
struct timeval* tv_p = NULL;
struct timeval tv;
if (timeout_ms >= 0) {
tv_p = &tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
}
int ret = select(fd + 1, NULL, &wfds, NULL, tv_p);
if (ret == 0) {
return 0;
}
else if (ret == 1) {
ssize_t r = write(fd, &b, 1);
if (r != 1)
return -1;
else {
return 1;
}
}
else
return -1;
}
void sleep_linux(uint32_t milliseconds, void* arg) {
usleep(milliseconds * 1000);
}
#define UNUSED_PARAM(x) ((x) = (x))
// Connection management
@ -125,6 +59,7 @@ int client_read_fd = -1;
fd_set client_connections;
void close_server_on_exit(int sig) {
UNUSED_PARAM(sig);
if (server_fd != -1)
close(server_fd);
}
@ -208,7 +143,7 @@ void* server_poll() {
}
FD_SET(client, &client_connections);
printf("Accepted connection from %s\n", inet_ntoa(client_addr.sin_addr));
printf("Accepted connection %d from %s\n", client, inet_ntoa(client_addr.sin_addr));
}
else {
client_read_fd = i;
@ -223,9 +158,95 @@ void* server_poll() {
void disconnect(void* conn) {
int fd = *(int*) conn;
close(fd);
printf("Closed connection %d\n", fd);
}
void close_server() {
close(server_fd);
printf("Server closed\n");
}
// Read/write/sleep platform functions
int read_fd_linux(uint8_t* buf, uint32_t count, int32_t timeout_ms, void* arg) {
int fd = *(int*) arg;
int32_t total = 0;
while (total != (int32_t) count) {
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
struct timeval* tv_p = NULL;
struct timeval tv;
if (timeout_ms >= 0) {
tv_p = &tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
}
int ret = select(fd + 1, &rfds, NULL, NULL, tv_p);
if (ret == 0) {
return total;
}
else if (ret == 1) {
ssize_t r = read(fd, buf + total, 1);
if (r == 0) {
disconnect(arg);
return -1;
}
else if (r < 0)
return -1;
else {
total += (int32_t) r;
}
}
else
return -1;
}
return total;
}
int32_t write_fd_linux(const uint8_t* buf, uint32_t count, int32_t timeout_ms, void* arg) {
int fd = *(int*) arg;
int32_t total = 0;
while (total != (int32_t) count) {
fd_set wfds;
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
struct timeval* tv_p = NULL;
struct timeval tv;
if (timeout_ms >= 0) {
tv_p = &tv;
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
}
int ret = select(fd + 1, NULL, &wfds, NULL, tv_p);
if (ret == 0) {
return 0;
}
else if (ret == 1) {
ssize_t w = write(fd, buf + total, count);
if (w == 0) {
disconnect(arg);
return -1;
}
else if (w <= 0)
return -1;
else {
total += (int32_t) w;
}
}
else
return -1;
}
return total;
}

View File

@ -1,7 +1,3 @@
#include "nanomodbus.h"
#include "platform.h"
#include <stdio.h>
/*
* This example application sets up a TCP server at the specified address and port, and polls from modbus requests
* from more than one modbus client (more specifically from maximum 1024 clients, since it uses select())
@ -12,12 +8,16 @@
* FC 15 (0x0F) Write Multiple Coils
* FC 16 (0x10) Write Multiple registers
*
* Since the platform for this example is linux, the platform arg is used to pass (to the linux TCP read/write
* functions) a pointer to the file descriptor of the current read client connection
* Since the platform for this example is linux, the platform arg is used to pass (to the linux TCP read/write
* functions) a pointer to the file descriptor of the current read client connection
*
* The platform functions are for Linux systems.
*/
#include <stdio.h>
#include "nanomodbus.h"
#include "platform.h"
// The data model of this sever will support coils addresses 0 to 100 and registers addresses from 0 to 32
#define COILS_ADDR_MAX 100
@ -93,9 +93,8 @@ int main(int argc, char* argv[]) {
nmbs_platform_conf platform_conf = {0};
platform_conf.transport = NMBS_TRANSPORT_TCP;
platform_conf.read_byte = read_byte_fd_linux;
platform_conf.write_byte = write_byte_fd_linux;
platform_conf.sleep = sleep_linux;
platform_conf.read = read_fd_linux;
platform_conf.write = write_fd_linux;
platform_conf.arg = NULL; // We will set the arg (socket fd) later
// These functions are defined in server.h
@ -130,7 +129,7 @@ int main(int argc, char* argv[]) {
err = nmbs_server_poll(&nmbs);
if (err != NMBS_ERROR_NONE) {
fprintf(stderr, "Error on modbus connection - %s\n", nmbs_strerror(err));
printf("Error on modbus connection - %s\n", nmbs_strerror(err));
// In a more complete example, we would handle this error by checking its nmbs_error value
}
}