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
|
* This example application connects via TCP to a modbus server at the specified address and port, and sends some
|
||||||
* modbus requests to it.
|
* 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
|
* 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
|
* 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[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: client-tcp [address] [port]\n");
|
fprintf(stderr, "Usage: client-tcp [address] [port]\n");
|
||||||
@ -27,9 +28,8 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
nmbs_platform_conf platform_conf;
|
nmbs_platform_conf platform_conf;
|
||||||
platform_conf.transport = NMBS_TRANSPORT_TCP;
|
platform_conf.transport = NMBS_TRANSPORT_TCP;
|
||||||
platform_conf.read_byte = read_byte_fd_linux;
|
platform_conf.read = read_fd_linux;
|
||||||
platform_conf.write_byte = write_byte_fd_linux;
|
platform_conf.write = write_fd_linux;
|
||||||
platform_conf.sleep = sleep_linux;
|
|
||||||
platform_conf.arg = conn; // Passing our TCP connection handle to the read/write functions
|
platform_conf.arg = conn; // Passing our TCP connection handle to the read/write functions
|
||||||
|
|
||||||
// Create the modbus client
|
// Create the modbus client
|
||||||
|
|||||||
@ -1,86 +1,20 @@
|
|||||||
#include "nanomodbus.h"
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netdb.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nanomodbus.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int write_byte_fd_linux(uint8_t b, int32_t timeout_ms, void* arg) {
|
#define UNUSED_PARAM(x) ((x) = (x))
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Connection management
|
// Connection management
|
||||||
@ -125,6 +59,7 @@ int client_read_fd = -1;
|
|||||||
fd_set client_connections;
|
fd_set client_connections;
|
||||||
|
|
||||||
void close_server_on_exit(int sig) {
|
void close_server_on_exit(int sig) {
|
||||||
|
UNUSED_PARAM(sig);
|
||||||
if (server_fd != -1)
|
if (server_fd != -1)
|
||||||
close(server_fd);
|
close(server_fd);
|
||||||
}
|
}
|
||||||
@ -208,7 +143,7 @@ void* server_poll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FD_SET(client, &client_connections);
|
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 {
|
else {
|
||||||
client_read_fd = i;
|
client_read_fd = i;
|
||||||
@ -223,9 +158,95 @@ void* server_poll() {
|
|||||||
void disconnect(void* conn) {
|
void disconnect(void* conn) {
|
||||||
int fd = *(int*) conn;
|
int fd = *(int*) conn;
|
||||||
close(fd);
|
close(fd);
|
||||||
|
printf("Closed connection %d\n", fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void close_server() {
|
void close_server() {
|
||||||
close(server_fd);
|
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
|
* 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())
|
* from more than one modbus client (more specifically from maximum 1024 clients, since it uses select())
|
||||||
@ -15,9 +11,13 @@
|
|||||||
* Since the platform for this example is linux, the platform arg is used to pass (to the linux TCP read/write
|
* 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
|
* 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
|
// 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
|
#define COILS_ADDR_MAX 100
|
||||||
@ -93,9 +93,8 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
nmbs_platform_conf platform_conf = {0};
|
nmbs_platform_conf platform_conf = {0};
|
||||||
platform_conf.transport = NMBS_TRANSPORT_TCP;
|
platform_conf.transport = NMBS_TRANSPORT_TCP;
|
||||||
platform_conf.read_byte = read_byte_fd_linux;
|
platform_conf.read = read_fd_linux;
|
||||||
platform_conf.write_byte = write_byte_fd_linux;
|
platform_conf.write = write_fd_linux;
|
||||||
platform_conf.sleep = sleep_linux;
|
|
||||||
platform_conf.arg = NULL; // We will set the arg (socket fd) later
|
platform_conf.arg = NULL; // We will set the arg (socket fd) later
|
||||||
|
|
||||||
// These functions are defined in server.h
|
// These functions are defined in server.h
|
||||||
@ -130,7 +129,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
err = nmbs_server_poll(&nmbs);
|
err = nmbs_server_poll(&nmbs);
|
||||||
if (err != NMBS_ERROR_NONE) {
|
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
|
// In a more complete example, we would handle this error by checking its nmbs_error value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user