Debug prints
This commit is contained in:
parent
07b4440096
commit
d25e462e69
@ -1,63 +0,0 @@
|
|||||||
#include "modbusino.h"
|
|
||||||
|
|
||||||
// Server (slave) handler functions
|
|
||||||
|
|
||||||
// This server data model will support coils addresses 0 to 100 and registers addresses from 0 to 26
|
|
||||||
#define COILS_ADDR_MAX 100
|
|
||||||
#define REGS_ADDR_MAX 32
|
|
||||||
|
|
||||||
// A single mbsn_bitfield variable can keep 2000 coils
|
|
||||||
mbsn_bitfield server_coils = {0};
|
|
||||||
|
|
||||||
uint16_t server_registers[REGS_ADDR_MAX] = {0};
|
|
||||||
|
|
||||||
|
|
||||||
mbsn_error handle_read_coils(uint16_t address, uint16_t quantity, mbsn_bitfield coils_out) {
|
|
||||||
if (address + quantity > COILS_ADDR_MAX + 1)
|
|
||||||
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
|
||||||
|
|
||||||
// Read our coils values into coils_out
|
|
||||||
for (int i = 0; i < quantity; i++) {
|
|
||||||
bool value = mbsn_bitfield_read(server_coils, address + i);
|
|
||||||
mbsn_bitfield_write(coils_out, i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mbsn_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const mbsn_bitfield coils) {
|
|
||||||
if (address + quantity > COILS_ADDR_MAX + 1)
|
|
||||||
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
|
||||||
|
|
||||||
// Write coils values to our server_coils
|
|
||||||
for (int i = 0; i < quantity; i++) {
|
|
||||||
mbsn_bitfield_write(server_coils, address + i, mbsn_bitfield_read(coils, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mbsn_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out) {
|
|
||||||
if (address + quantity > REGS_ADDR_MAX + 1)
|
|
||||||
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
|
||||||
|
|
||||||
// Read our registers values into registers_out
|
|
||||||
for (int i = 0; i < quantity; i++)
|
|
||||||
registers_out[i] = server_registers[address + i];
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mbsn_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers) {
|
|
||||||
if (address + quantity > REGS_ADDR_MAX + 1)
|
|
||||||
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
|
||||||
|
|
||||||
// Write registers values to our server_registers
|
|
||||||
for (int i = 0; i < quantity; i++)
|
|
||||||
server_registers[address + i] = registers[i];
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
#include "modbusino.h"
|
#include "modbusino.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "server-handlers.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -19,6 +18,66 @@
|
|||||||
* The platform functions are for Linux systems.
|
* The platform functions are for Linux systems.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// 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 REGS_ADDR_MAX 32
|
||||||
|
|
||||||
|
// A single mbsn_bitfield variable can keep 2000 coils
|
||||||
|
mbsn_bitfield server_coils = {0};
|
||||||
|
uint16_t server_registers[REGS_ADDR_MAX] = {0};
|
||||||
|
|
||||||
|
mbsn_error handle_read_coils(uint16_t address, uint16_t quantity, mbsn_bitfield coils_out) {
|
||||||
|
if (address + quantity > COILS_ADDR_MAX + 1)
|
||||||
|
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
||||||
|
|
||||||
|
// Read our coils values into coils_out
|
||||||
|
for (int i = 0; i < quantity; i++) {
|
||||||
|
bool value = mbsn_bitfield_read(server_coils, address + i);
|
||||||
|
mbsn_bitfield_write(coils_out, i, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MBSN_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mbsn_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const mbsn_bitfield coils) {
|
||||||
|
if (address + quantity > COILS_ADDR_MAX + 1)
|
||||||
|
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
||||||
|
|
||||||
|
// Write coils values to our server_coils
|
||||||
|
for (int i = 0; i < quantity; i++) {
|
||||||
|
mbsn_bitfield_write(server_coils, address + i, mbsn_bitfield_read(coils, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return MBSN_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mbsn_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out) {
|
||||||
|
if (address + quantity > REGS_ADDR_MAX + 1)
|
||||||
|
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
||||||
|
|
||||||
|
// Read our registers values into registers_out
|
||||||
|
for (int i = 0; i < quantity; i++)
|
||||||
|
registers_out[i] = server_registers[address + i];
|
||||||
|
|
||||||
|
return MBSN_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mbsn_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers) {
|
||||||
|
if (address + quantity > REGS_ADDR_MAX + 1)
|
||||||
|
return MBSN_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
||||||
|
|
||||||
|
// Write registers values to our server_registers
|
||||||
|
for (int i = 0; i < quantity; i++)
|
||||||
|
server_registers[address + i] = registers[i];
|
||||||
|
|
||||||
|
return MBSN_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: server-tcp [address] [port]\n");
|
fprintf(stderr, "Usage: server-tcp [address] [port]\n");
|
||||||
|
|||||||
146
modbusino.c
146
modbusino.c
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
#ifdef MBSN_DEBUG
|
#ifdef MBSN_DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#define DEBUG(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG(...) (void) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MBSN_BIG_ENDIAN) && !defined(MBSN_LITTLE_ENDIAN)
|
#if !defined(MBSN_BIG_ENDIAN) && !defined(MBSN_LITTLE_ENDIAN)
|
||||||
@ -169,12 +172,6 @@ static mbsn_error recv(mbsn_t* mbsn, uint32_t count) {
|
|||||||
int ret = mbsn->platform.read_byte(mbsn->msg.buf + mbsn->msg.buf_idx + r, mbsn->byte_timeout_ms,
|
int ret = mbsn->platform.read_byte(mbsn->msg.buf + mbsn->msg.buf_idx + r, mbsn->byte_timeout_ms,
|
||||||
mbsn->platform.arg);
|
mbsn->platform.arg);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
#ifdef MBSN_DEBUG
|
|
||||||
if (mbsn->address_rtu == 0)
|
|
||||||
printf("c: to\n");
|
|
||||||
else
|
|
||||||
printf("s: to\n");
|
|
||||||
#endif
|
|
||||||
return MBSN_ERROR_TIMEOUT;
|
return MBSN_ERROR_TIMEOUT;
|
||||||
}
|
}
|
||||||
else if (ret != 1) {
|
else if (ret != 1) {
|
||||||
@ -184,13 +181,6 @@ static mbsn_error recv(mbsn_t* mbsn, uint32_t count) {
|
|||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MBSN_DEBUG
|
|
||||||
if (mbsn->address_rtu == 0)
|
|
||||||
printf("c: recv %d\n", count);
|
|
||||||
else
|
|
||||||
printf("s: recv %d\n", count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
return MBSN_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,13 +203,6 @@ static mbsn_error send(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MBSN_DEBUG
|
|
||||||
if (mbsn->address_rtu == 0)
|
|
||||||
printf("c: sent %d\n", mbsn->msg.buf_idx - 1);
|
|
||||||
else
|
|
||||||
printf("s: sent %d\n", mbsn->msg.buf_idx - 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
return MBSN_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,6 +221,8 @@ static mbsn_error recv_msg_footer(mbsn_t* mbsn) {
|
|||||||
return MBSN_ERROR_TRANSPORT;
|
return MBSN_ERROR_TRANSPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG("\n");
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
return MBSN_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,14 +342,18 @@ static mbsn_error recv_res_header(mbsn_t* mbsn) {
|
|||||||
|
|
||||||
if (exception < 1 || exception > 4)
|
if (exception < 1 || exception > 4)
|
||||||
return MBSN_ERROR_INVALID_RESPONSE;
|
return MBSN_ERROR_INVALID_RESPONSE;
|
||||||
else
|
else {
|
||||||
|
DEBUG("exception %d\n", exception);
|
||||||
return exception;
|
return exception;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return MBSN_ERROR_INVALID_RESPONSE;
|
return MBSN_ERROR_INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG("MBSN res <- fc %d\t", mbsn->msg.fc);
|
||||||
|
|
||||||
return MBSN_ERROR_NONE;
|
return MBSN_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,15 +382,32 @@ static mbsn_error send_msg_footer(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mbsn_error err = send(mbsn);
|
mbsn_error err = send(mbsn);
|
||||||
|
|
||||||
|
DEBUG("\n");
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void send_req_header(mbsn_t* mbsn, uint16_t data_length) {
|
||||||
|
send_msg_header(mbsn, data_length);
|
||||||
|
DEBUG("MBSN req -> fc %d\t", mbsn->msg.fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void send_res_header(mbsn_t* mbsn, uint16_t data_length) {
|
||||||
|
send_msg_header(mbsn, data_length);
|
||||||
|
DEBUG("MBSN res -> fc %d\t", mbsn->msg.fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static mbsn_error handle_exception(mbsn_t* mbsn, uint8_t exception) {
|
static mbsn_error handle_exception(mbsn_t* mbsn, uint8_t exception) {
|
||||||
mbsn->msg.fc += 0x80;
|
mbsn->msg.fc += 0x80;
|
||||||
send_msg_header(mbsn, 1);
|
send_msg_header(mbsn, 1);
|
||||||
put_1(mbsn, exception);
|
put_1(mbsn, exception);
|
||||||
|
|
||||||
|
DEBUG("MBSN res -> exception %d\n", exception);
|
||||||
|
|
||||||
return send_msg_footer(mbsn);
|
return send_msg_footer(mbsn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,6 +420,8 @@ static mbsn_error handle_read_discrete(mbsn_t* mbsn, mbsn_error (*callback)(uint
|
|||||||
uint16_t address = get_2(mbsn);
|
uint16_t address = get_2(mbsn);
|
||||||
uint16_t quantity = get_2(mbsn);
|
uint16_t quantity = get_2(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -437,12 +445,16 @@ static mbsn_error handle_read_discrete(mbsn_t* mbsn, mbsn_error (*callback)(uint
|
|||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
uint8_t discrete_bytes = (quantity / 8) + 1;
|
uint8_t discrete_bytes = (quantity / 8) + 1;
|
||||||
send_msg_header(mbsn, discrete_bytes);
|
send_res_header(mbsn, discrete_bytes);
|
||||||
|
|
||||||
put_1(mbsn, discrete_bytes);
|
put_1(mbsn, discrete_bytes);
|
||||||
|
|
||||||
|
DEBUG("b %d\t", discrete_bytes);
|
||||||
|
|
||||||
|
DEBUG("coils ");
|
||||||
for (int i = 0; i < discrete_bytes; i++) {
|
for (int i = 0; i < discrete_bytes; i++) {
|
||||||
put_1(mbsn, bf[i]);
|
put_1(mbsn, bf[i]);
|
||||||
|
DEBUG("%d", bf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
@ -467,6 +479,8 @@ static mbsn_error handle_read_registers(mbsn_t* mbsn, mbsn_error (*callback)(uin
|
|||||||
uint16_t address = get_2(mbsn);
|
uint16_t address = get_2(mbsn);
|
||||||
uint16_t quantity = get_2(mbsn);
|
uint16_t quantity = get_2(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -490,12 +504,16 @@ static mbsn_error handle_read_registers(mbsn_t* mbsn, mbsn_error (*callback)(uin
|
|||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
uint8_t regs_bytes = quantity * 2;
|
uint8_t regs_bytes = quantity * 2;
|
||||||
send_msg_header(mbsn, regs_bytes);
|
send_res_header(mbsn, regs_bytes);
|
||||||
|
|
||||||
put_1(mbsn, regs_bytes);
|
put_1(mbsn, regs_bytes);
|
||||||
|
|
||||||
|
DEBUG("b %d\t", regs_bytes);
|
||||||
|
|
||||||
|
DEBUG("regs ");
|
||||||
for (int i = 0; i < quantity; i++) {
|
for (int i = 0; i < quantity; i++) {
|
||||||
put_2(mbsn, regs[i]);
|
put_2(mbsn, regs[i]);
|
||||||
|
DEBUG("%d", regs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
@ -540,6 +558,8 @@ static mbsn_error handle_write_single_coil(mbsn_t* mbsn) {
|
|||||||
uint16_t address = get_2(mbsn);
|
uint16_t address = get_2(mbsn);
|
||||||
uint16_t value = get_2(mbsn);
|
uint16_t value = get_2(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -558,9 +578,12 @@ static mbsn_error handle_write_single_coil(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
send_msg_header(mbsn, 4);
|
send_res_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, value);
|
put_2(mbsn, value);
|
||||||
|
DEBUG("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -583,6 +606,8 @@ static mbsn_error handle_write_single_register(mbsn_t* mbsn) {
|
|||||||
uint16_t address = get_2(mbsn);
|
uint16_t address = get_2(mbsn);
|
||||||
uint16_t value = get_2(mbsn);
|
uint16_t value = get_2(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -598,9 +623,12 @@ static mbsn_error handle_write_single_register(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
send_msg_header(mbsn, 4);
|
send_res_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, value);
|
put_2(mbsn, value);
|
||||||
|
DEBUG("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -624,6 +652,8 @@ static mbsn_error handle_write_multiple_coils(mbsn_t* mbsn) {
|
|||||||
uint16_t quantity = get_2(mbsn);
|
uint16_t quantity = get_2(mbsn);
|
||||||
uint8_t coils_bytes = get_1(mbsn);
|
uint8_t coils_bytes = get_1(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d\tb %d\tcoils ", address, quantity, coils_bytes);
|
||||||
|
|
||||||
err = recv(mbsn, coils_bytes);
|
err = recv(mbsn, coils_bytes);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -631,6 +661,7 @@ static mbsn_error handle_write_multiple_coils(mbsn_t* mbsn) {
|
|||||||
mbsn_bitfield coils;
|
mbsn_bitfield coils;
|
||||||
for (int i = 0; i < coils_bytes; i++) {
|
for (int i = 0; i < coils_bytes; i++) {
|
||||||
coils[i] = get_1(mbsn);
|
coils[i] = get_1(mbsn);
|
||||||
|
DEBUG("%d ", coils[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
@ -660,9 +691,12 @@ static mbsn_error handle_write_multiple_coils(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
send_msg_header(mbsn, 4);
|
send_res_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
|
DEBUG("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -686,6 +720,8 @@ static mbsn_error handle_write_multiple_registers(mbsn_t* mbsn) {
|
|||||||
uint16_t quantity = get_2(mbsn);
|
uint16_t quantity = get_2(mbsn);
|
||||||
uint8_t registers_bytes = get_1(mbsn);
|
uint8_t registers_bytes = get_1(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d\tb %d\tregs ", address, quantity, registers_bytes);
|
||||||
|
|
||||||
err = recv(mbsn, registers_bytes);
|
err = recv(mbsn, registers_bytes);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -693,6 +729,7 @@ static mbsn_error handle_write_multiple_registers(mbsn_t* mbsn) {
|
|||||||
uint16_t registers[0x007B];
|
uint16_t registers[0x007B];
|
||||||
for (int i = 0; i < registers_bytes / 2; i++) {
|
for (int i = 0; i < registers_bytes / 2; i++) {
|
||||||
registers[i] = get_2(mbsn);
|
registers[i] = get_2(mbsn);
|
||||||
|
DEBUG("%d ", registers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
@ -722,9 +759,12 @@ static mbsn_error handle_write_multiple_registers(mbsn_t* mbsn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!mbsn->msg.broadcast) {
|
if (!mbsn->msg.broadcast) {
|
||||||
send_msg_header(mbsn, 4);
|
send_res_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
|
DEBUG("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
err = send_msg_footer(mbsn);
|
err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -740,6 +780,8 @@ static mbsn_error handle_write_multiple_registers(mbsn_t* mbsn) {
|
|||||||
|
|
||||||
|
|
||||||
static mbsn_error handle_req_fc(mbsn_t* mbsn) {
|
static mbsn_error handle_req_fc(mbsn_t* mbsn) {
|
||||||
|
DEBUG("fc %d\t", mbsn->msg.fc);
|
||||||
|
|
||||||
mbsn_error err;
|
mbsn_error err;
|
||||||
switch (mbsn->msg.fc) {
|
switch (mbsn->msg.fc) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -794,6 +836,16 @@ mbsn_error mbsn_server_poll(mbsn_t* mbsn) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MBSN_DEBUG
|
||||||
|
printf("MBSN req <- ");
|
||||||
|
if (mbsn->platform.transport == MBSN_TRANSPORT_RTU) {
|
||||||
|
if (mbsn->msg.broadcast)
|
||||||
|
printf("broadcast\t");
|
||||||
|
|
||||||
|
printf("client_id %d\t", mbsn->msg.unit_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
err = handle_req_fc(mbsn);
|
err = handle_req_fc(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE) {
|
if (err != MBSN_ERROR_NONE) {
|
||||||
if (!mbsn_error_is_exception(err))
|
if (!mbsn_error_is_exception(err))
|
||||||
@ -812,11 +864,13 @@ static mbsn_error read_discrete(mbsn_t* mbsn, uint8_t fc, uint16_t address, uint
|
|||||||
return MBSN_ERROR_INVALID_ARGUMENT;
|
return MBSN_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
msg_state_req(mbsn, fc);
|
msg_state_req(mbsn, fc);
|
||||||
send_msg_header(mbsn, 4);
|
send_req_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -830,13 +884,16 @@ static mbsn_error read_discrete(mbsn_t* mbsn, uint8_t fc, uint16_t address, uint
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
uint8_t coils_bytes = get_1(mbsn);
|
uint8_t coils_bytes = get_1(mbsn);
|
||||||
|
DEBUG("b %d\t", coils_bytes);
|
||||||
|
|
||||||
err = recv(mbsn, coils_bytes);
|
err = recv(mbsn, coils_bytes);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
DEBUG("coils ");
|
||||||
for (int i = 0; i < coils_bytes; i++) {
|
for (int i = 0; i < coils_bytes; i++) {
|
||||||
values[i] = get_1(mbsn);
|
values[i] = get_1(mbsn);
|
||||||
|
DEBUG("%d", values[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
@ -865,11 +922,13 @@ static mbsn_error read_registers(mbsn_t* mbsn, uint8_t fc, uint16_t address, uin
|
|||||||
return MBSN_ERROR_INVALID_ARGUMENT;
|
return MBSN_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
msg_state_req(mbsn, fc);
|
msg_state_req(mbsn, fc);
|
||||||
send_msg_header(mbsn, 4);
|
send_req_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
|
|
||||||
|
DEBUG("a %d\tq %d ", address, quantity);
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -883,13 +942,16 @@ static mbsn_error read_registers(mbsn_t* mbsn, uint8_t fc, uint16_t address, uin
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
uint8_t registers_bytes = get_1(mbsn);
|
uint8_t registers_bytes = get_1(mbsn);
|
||||||
|
DEBUG("b %d\t", registers_bytes);
|
||||||
|
|
||||||
err = recv(mbsn, registers_bytes);
|
err = recv(mbsn, registers_bytes);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
DEBUG("regs ");
|
||||||
for (int i = 0; i < registers_bytes / 2; i++) {
|
for (int i = 0; i < registers_bytes / 2; i++) {
|
||||||
registers[i] = get_2(mbsn);
|
registers[i] = get_2(mbsn);
|
||||||
|
DEBUG("%d", registers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
@ -915,13 +977,15 @@ mbsn_error mbsn_read_input_registers(mbsn_t* mbsn, uint16_t address, uint16_t qu
|
|||||||
|
|
||||||
mbsn_error mbsn_write_single_coil(mbsn_t* mbsn, uint16_t address, bool value) {
|
mbsn_error mbsn_write_single_coil(mbsn_t* mbsn, uint16_t address, bool value) {
|
||||||
msg_state_req(mbsn, 5);
|
msg_state_req(mbsn, 5);
|
||||||
send_msg_header(mbsn, 4);
|
send_req_header(mbsn, 4);
|
||||||
|
|
||||||
uint16_t value_req = value ? 0xFF00 : 0;
|
uint16_t value_req = value ? 0xFF00 : 0;
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, value_req);
|
put_2(mbsn, value_req);
|
||||||
|
|
||||||
|
DEBUG("a %d\tvalue %d ", address, value_req);
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -938,6 +1002,8 @@ mbsn_error mbsn_write_single_coil(mbsn_t* mbsn, uint16_t address, bool value) {
|
|||||||
uint16_t address_res = get_2(mbsn);
|
uint16_t address_res = get_2(mbsn);
|
||||||
uint16_t value_res = get_2(mbsn);
|
uint16_t value_res = get_2(mbsn);
|
||||||
|
|
||||||
|
DEBUG("a %d\tvalue %d", address, value_res);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -955,11 +1021,13 @@ mbsn_error mbsn_write_single_coil(mbsn_t* mbsn, uint16_t address, bool value) {
|
|||||||
|
|
||||||
mbsn_error mbsn_write_single_register(mbsn_t* mbsn, uint16_t address, uint16_t value) {
|
mbsn_error mbsn_write_single_register(mbsn_t* mbsn, uint16_t address, uint16_t value) {
|
||||||
msg_state_req(mbsn, 6);
|
msg_state_req(mbsn, 6);
|
||||||
send_msg_header(mbsn, 4);
|
send_req_header(mbsn, 4);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, value);
|
put_2(mbsn, value);
|
||||||
|
|
||||||
|
DEBUG("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
@ -975,6 +1043,7 @@ mbsn_error mbsn_write_single_register(mbsn_t* mbsn, uint16_t address, uint16_t v
|
|||||||
|
|
||||||
uint16_t address_res = get_2(mbsn);
|
uint16_t address_res = get_2(mbsn);
|
||||||
uint16_t value_res = get_2(mbsn);
|
uint16_t value_res = get_2(mbsn);
|
||||||
|
DEBUG("a %d\tvalue %d ", address, value_res);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
@ -1001,14 +1070,17 @@ mbsn_error mbsn_write_multiple_coils(mbsn_t* mbsn, uint16_t address, uint16_t qu
|
|||||||
uint8_t coils_bytes = (quantity / 8) + 1;
|
uint8_t coils_bytes = (quantity / 8) + 1;
|
||||||
|
|
||||||
msg_state_req(mbsn, 15);
|
msg_state_req(mbsn, 15);
|
||||||
send_msg_header(mbsn, 5 + coils_bytes);
|
send_req_header(mbsn, 5 + coils_bytes);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
put_1(mbsn, coils_bytes);
|
put_1(mbsn, coils_bytes);
|
||||||
|
DEBUG("a %d\tq %d\tb %d\t", address, quantity, coils_bytes);
|
||||||
|
|
||||||
|
DEBUG("coils ");
|
||||||
for (int i = 0; i < coils_bytes; i++) {
|
for (int i = 0; i < coils_bytes; i++) {
|
||||||
put_1(mbsn, coils[i]);
|
put_1(mbsn, coils[i]);
|
||||||
|
DEBUG("%d ", coils[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
@ -1026,6 +1098,7 @@ mbsn_error mbsn_write_multiple_coils(mbsn_t* mbsn, uint16_t address, uint16_t qu
|
|||||||
|
|
||||||
uint16_t address_res = get_2(mbsn);
|
uint16_t address_res = get_2(mbsn);
|
||||||
uint16_t quantity_res = get_2(mbsn);
|
uint16_t quantity_res = get_2(mbsn);
|
||||||
|
DEBUG("a %d\tq %d", address_res, quantity_res);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
@ -1052,14 +1125,17 @@ mbsn_error mbsn_write_multiple_registers(mbsn_t* mbsn, uint16_t address, uint16_
|
|||||||
uint8_t registers_bytes = quantity * 2;
|
uint8_t registers_bytes = quantity * 2;
|
||||||
|
|
||||||
msg_state_req(mbsn, 16);
|
msg_state_req(mbsn, 16);
|
||||||
send_msg_header(mbsn, 5 + registers_bytes);
|
send_req_header(mbsn, 5 + registers_bytes);
|
||||||
|
|
||||||
put_2(mbsn, address);
|
put_2(mbsn, address);
|
||||||
put_2(mbsn, quantity);
|
put_2(mbsn, quantity);
|
||||||
put_1(mbsn, registers_bytes);
|
put_1(mbsn, registers_bytes);
|
||||||
|
DEBUG("a %d\tq %d\tb %d\t", address, quantity, registers_bytes);
|
||||||
|
|
||||||
|
DEBUG("regs ");
|
||||||
for (int i = 0; i < quantity; i++) {
|
for (int i = 0; i < quantity; i++) {
|
||||||
put_2(mbsn, registers[i]);
|
put_2(mbsn, registers[i]);
|
||||||
|
DEBUG("%d ", registers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
mbsn_error err = send_msg_footer(mbsn);
|
mbsn_error err = send_msg_footer(mbsn);
|
||||||
@ -1077,6 +1153,7 @@ mbsn_error mbsn_write_multiple_registers(mbsn_t* mbsn, uint16_t address, uint16_
|
|||||||
|
|
||||||
uint16_t address_res = get_2(mbsn);
|
uint16_t address_res = get_2(mbsn);
|
||||||
uint16_t quantity_res = get_2(mbsn);
|
uint16_t quantity_res = get_2(mbsn);
|
||||||
|
DEBUG("a %d\tq %d", address_res, quantity_res);
|
||||||
|
|
||||||
err = recv_msg_footer(mbsn);
|
err = recv_msg_footer(mbsn);
|
||||||
if (err != MBSN_ERROR_NONE)
|
if (err != MBSN_ERROR_NONE)
|
||||||
@ -1096,8 +1173,11 @@ mbsn_error mbsn_write_multiple_registers(mbsn_t* mbsn, uint16_t address, uint16_
|
|||||||
mbsn_error mbsn_send_raw_pdu(mbsn_t* mbsn, uint8_t fc, const void* data, uint32_t data_len) {
|
mbsn_error mbsn_send_raw_pdu(mbsn_t* mbsn, uint8_t fc, const void* data, uint32_t data_len) {
|
||||||
msg_state_req(mbsn, fc);
|
msg_state_req(mbsn, fc);
|
||||||
send_msg_header(mbsn, data_len);
|
send_msg_header(mbsn, data_len);
|
||||||
|
|
||||||
|
DEBUG("raw ");
|
||||||
for (uint32_t i = 0; i < data_len; i++) {
|
for (uint32_t i = 0; i < data_len; i++) {
|
||||||
put_1(mbsn, ((uint8_t*) (data))[i]);
|
put_1(mbsn, ((uint8_t*) (data))[i]);
|
||||||
|
DEBUG("%d ", ((uint8_t*) (data))[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return send_msg_footer(mbsn);
|
return send_msg_footer(mbsn);
|
||||||
|
|||||||
@ -1,47 +0,0 @@
|
|||||||
#ifndef MODBUSINO_MODBUSINO_PLATFORM_H
|
|
||||||
#define MODBUSINO_MODBUSINO_PLATFORM_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* ### Endianness macros.
|
|
||||||
* In most cases, endianness will be detected automatically, so they can be left commented
|
|
||||||
*/
|
|
||||||
/* Uncomment if your platform is big endian */
|
|
||||||
// #define MBSN_BIG_ENDIAN
|
|
||||||
|
|
||||||
/* Uncomment if your platform is little endian */
|
|
||||||
// #define MBSN_LITTLE_ENDIAN
|
|
||||||
|
|
||||||
|
|
||||||
/* ### Transport function pointers.
|
|
||||||
* Point them to your platform-specific methods that read/write data to/from a serial port or a TCP connection and
|
|
||||||
* flush their receive buffers.
|
|
||||||
*
|
|
||||||
* read()/write() methods should block until the requested byte is read/written.
|
|
||||||
* If your implementation uses a read/write timeout, and the timeout expires, the methods should return 0.
|
|
||||||
* Their return values should be:
|
|
||||||
* - 1 in case of success
|
|
||||||
* - 0 if no data is available immediately or after an internal timeout expiration
|
|
||||||
* - -1 in case of error
|
|
||||||
*
|
|
||||||
* The primary effect of flush() methods should be the flushing of the underlying receive buffer.
|
|
||||||
* These methods will be called in case of error, in order to "reset" the state of the connection.
|
|
||||||
* On most platforms
|
|
||||||
*
|
|
||||||
* You can leave some of them NULL if you don't plan to use a certain transport.
|
|
||||||
*/
|
|
||||||
int (*mbsn_rtu_flush)() = NULL;
|
|
||||||
|
|
||||||
int (*mbsn_rtu_read_byte)(uint8_t* b) = NULL;
|
|
||||||
|
|
||||||
int (*mbsn_rtu_write_byte)(uint8_t b) = NULL;
|
|
||||||
|
|
||||||
int (*mbsn_tcp_flush)() = NULL;
|
|
||||||
|
|
||||||
int (*mbsn_tcp_read_byte)(uint8_t* b) = NULL;
|
|
||||||
|
|
||||||
int (*mbsn_tcp_write_byte)(uint8_t b) = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
#endif //MODBUSINO_MODBUSINO_PLATFORM_H
|
|
||||||
Loading…
Reference in New Issue
Block a user