Updated examples
This commit is contained in:
parent
7f811f2338
commit
76f28fefb9
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user