FC 43 / 14 Read Device Identification
This commit is contained in:
parent
dccaa4f432
commit
a25ee5781a
@ -1,6 +1,7 @@
|
|||||||
# nanoMODBUS - A compact MODBUS RTU/TCP C library for embedded/microcontrollers
|
# nanoMODBUS - A compact MODBUS RTU/TCP C library for embedded/microcontrollers
|
||||||
|
|
||||||
**If you found this library useful, buy me a coffee on** [<img src='https://storage.ko-fi.com/cdn/brandasset/logo_white_stroke.png' width='80'>](https://ko-fi.com/B0B2LK779)
|
**If you found this library useful, buy me a coffee on
|
||||||
|
** [<img src='https://storage.ko-fi.com/cdn/brandasset/logo_white_stroke.png' width='80'>](https://ko-fi.com/B0B2LK779)
|
||||||
|
|
||||||
nanoMODBUS is a small C library that implements the Modbus protocol. It is especially useful in embedded and
|
nanoMODBUS is a small C library that implements the Modbus protocol. It is especially useful in embedded and
|
||||||
resource-constrained systems like microcontrollers.
|
resource-constrained systems like microcontrollers.
|
||||||
@ -28,6 +29,7 @@ Its main features are:
|
|||||||
- 20 (0x14) Read File Record
|
- 20 (0x14) Read File Record
|
||||||
- 21 (0x15) Write File Record
|
- 21 (0x15) Write File Record
|
||||||
- 23 (0x17) Read/Write Multiple registers
|
- 23 (0x17) Read/Write Multiple registers
|
||||||
|
- 43/14 (0x2B/0x0E) Read Device Identification
|
||||||
- Platform-agnostic
|
- Platform-agnostic
|
||||||
- Requires only C99 and its standard library
|
- Requires only C99 and its standard library
|
||||||
- Data transport read/write function are implemented by the user
|
- Data transport read/write function are implemented by the user
|
||||||
@ -157,5 +159,6 @@ Please refer to `examples/arduino/README.md` for more info about building and ru
|
|||||||
- `NMBS_SERVER_READ_FILE_RECORD_DISABLED`
|
- `NMBS_SERVER_READ_FILE_RECORD_DISABLED`
|
||||||
- `NMBS_SERVER_WRITE_FILE_RECORD_DISABLED`
|
- `NMBS_SERVER_WRITE_FILE_RECORD_DISABLED`
|
||||||
- `NMBS_SERVER_READ_WRITE_REGISTERS_DISABLED`
|
- `NMBS_SERVER_READ_WRITE_REGISTERS_DISABLED`
|
||||||
|
- `NMBS_SERVER_READ_DEVICE_IDENTIFICATION_DISABLED`
|
||||||
- `NMBS_STRERROR_DISABLED` to disable the code that converts `nmbs_error`s to strings
|
- `NMBS_STRERROR_DISABLED` to disable the code that converts `nmbs_error`s to strings
|
||||||
- Debug prints about received and sent messages can be enabled by defining `NMBS_DEBUG`
|
- Debug prints about received and sent messages can be enabled by defining `NMBS_DEBUG`
|
||||||
|
|||||||
@ -94,7 +94,7 @@ int main(int argc, char* argv[]) {
|
|||||||
uint16_t file[4] = {0x0000, 0x00AA, 0x5500, 0xFFFF};
|
uint16_t file[4] = {0x0000, 0x00AA, 0x5500, 0xFFFF};
|
||||||
err = nmbs_write_file_record(&nmbs, 1, 0, file, 4);
|
err = nmbs_write_file_record(&nmbs, 1, 0, file, 4);
|
||||||
if (err != NMBS_ERROR_NONE) {
|
if (err != NMBS_ERROR_NONE) {
|
||||||
fprintf(stderr, "Error writing file - %s", nmbs_strerror(err));
|
fprintf(stderr, "Error writing file - %s\n", nmbs_strerror(err));
|
||||||
if (!nmbs_error_is_exception(err))
|
if (!nmbs_error_is_exception(err))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ int main(int argc, char* argv[]) {
|
|||||||
memset(file, 0, sizeof(file));
|
memset(file, 0, sizeof(file));
|
||||||
err = nmbs_read_file_record(&nmbs, 1, 0, file, 4);
|
err = nmbs_read_file_record(&nmbs, 1, 0, file, 4);
|
||||||
if (err != NMBS_ERROR_NONE) {
|
if (err != NMBS_ERROR_NONE) {
|
||||||
fprintf(stderr, "Error writing file - %s", nmbs_strerror(err));
|
fprintf(stderr, "Error writing file - %s\n", nmbs_strerror(err));
|
||||||
if (!nmbs_error_is_exception(err))
|
if (!nmbs_error_is_exception(err))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -114,6 +114,38 @@ int main(int argc, char* argv[]) {
|
|||||||
printf("Read file registers: 0x%04X 0x%04X 0x%04X 0x%04X\n", file[0], file[1], file[2], file[3]);
|
printf("Read file registers: 0x%04X 0x%04X 0x%04X 0x%04X\n", file[0], file[1], file[2], file[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read basic device identification
|
||||||
|
char vendor_name[128], product_code[128], major_minor_revision[128];
|
||||||
|
err = nmbs_read_device_identification_basic(&nmbs, vendor_name, product_code, major_minor_revision, 128);
|
||||||
|
if (err != NMBS_ERROR_NONE) {
|
||||||
|
fprintf(stderr, "Error reading basic device identification - %s\n", nmbs_strerror(err));
|
||||||
|
if (!nmbs_error_is_exception(err))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Read basic device identification: %s %s %s\n", vendor_name, product_code, major_minor_revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read basic extended device identification
|
||||||
|
char mem[8 * 128];
|
||||||
|
char* buffers[8];
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
buffers[i] = &mem[i * 128];
|
||||||
|
uint8_t ids[8];
|
||||||
|
uint8_t objects_count = 0;
|
||||||
|
err = nmbs_read_device_identification_extended(&nmbs, 0x80, ids, buffers, 8, 128, &objects_count);
|
||||||
|
if (err != NMBS_ERROR_NONE) {
|
||||||
|
// If err == NMBS_INVALID_ARGUMENT, the length of the ids and buffers arrays (8 here) is not enough for all
|
||||||
|
// the read objects from the server
|
||||||
|
fprintf(stderr, "Error reading extended device identification - %s\n", nmbs_strerror(err));
|
||||||
|
if (!nmbs_error_is_exception(err))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < objects_count; i++)
|
||||||
|
printf("Read extended device identification: ID 0x%02x value %s\n", ids[i], buffers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Close the TCP connection
|
// Close the TCP connection
|
||||||
disconnect(conn);
|
disconnect(conn);
|
||||||
|
|
||||||
|
|||||||
@ -2,12 +2,6 @@
|
|||||||
* 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())
|
||||||
*
|
*
|
||||||
* This server supports the following function codes:
|
|
||||||
* FC 01 (0x01) Read Coils
|
|
||||||
* FC 03 (0x03) Read Holding Registers
|
|
||||||
* 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 file descriptor
|
* Since the platform for this example is linux, the platform arg is used to pass (to the linux file descriptor
|
||||||
* read/write functions) a pointer to the file descriptor of the current read client connection
|
* read/write functions) a pointer to the file descriptor of the current read client connection
|
||||||
*
|
*
|
||||||
@ -135,6 +129,40 @@ nmbs_error handle_write_file_record(uint16_t file_number, uint16_t record_number
|
|||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nmbs_error handle_read_device_identification_map(nmbs_bitfield_256 map) {
|
||||||
|
// We support basic object ID and a couple of extended ones
|
||||||
|
nmbs_bitfield_set(map, 0x00);
|
||||||
|
nmbs_bitfield_set(map, 0x01);
|
||||||
|
nmbs_bitfield_set(map, 0x02);
|
||||||
|
nmbs_bitfield_set(map, 0x90);
|
||||||
|
nmbs_bitfield_set(map, 0xA0);
|
||||||
|
return NMBS_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nmbs_error handle_read_device_identification(uint8_t object_id, char buffer[NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH]) {
|
||||||
|
switch (object_id) {
|
||||||
|
case 0x00:
|
||||||
|
strcpy(buffer, "VendorName");
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
strcpy(buffer, "ProductCode");
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
strcpy(buffer, "MajorMinorRevision");
|
||||||
|
break;
|
||||||
|
case 0x90:
|
||||||
|
strcpy(buffer, "Extended 1");
|
||||||
|
break;
|
||||||
|
case 0xA0:
|
||||||
|
strcpy(buffer, "Extended 2");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NMBS_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
signal(SIGTERM, sighandler);
|
signal(SIGTERM, sighandler);
|
||||||
@ -167,6 +195,8 @@ int main(int argc, char* argv[]) {
|
|||||||
callbacks.write_multiple_registers = handle_write_multiple_registers;
|
callbacks.write_multiple_registers = handle_write_multiple_registers;
|
||||||
callbacks.read_file_record = handle_read_file_record;
|
callbacks.read_file_record = handle_read_file_record;
|
||||||
callbacks.write_file_record = handle_write_file_record;
|
callbacks.write_file_record = handle_write_file_record;
|
||||||
|
callbacks.read_device_identification_map = handle_read_device_identification_map;
|
||||||
|
callbacks.read_device_identification = handle_read_device_identification;
|
||||||
|
|
||||||
// Create the modbus server. It's ok to set address_rtu to 0 since we are on TCP
|
// Create the modbus server. It's ok to set address_rtu to 0 since we are on TCP
|
||||||
nmbs_t nmbs;
|
nmbs_t nmbs;
|
||||||
|
|||||||
164
nanomodbus.c
164
nanomodbus.c
@ -380,17 +380,6 @@ static nmbs_error send_msg(nmbs_t* nmbs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef NMBS_CLIENT_DISABLED
|
|
||||||
static nmbs_error send_req(nmbs_t* nmbs) {
|
|
||||||
if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) {
|
|
||||||
// Flush the remaining data on the line before sending the request
|
|
||||||
// nmbs->platform.read(nmbs->msg.buf, sizeof(nmbs->msg.buf), 0, nmbs->platform.arg);
|
|
||||||
}
|
|
||||||
return send_msg(nmbs);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NMBS_SERVER_DISABLED
|
#ifndef NMBS_SERVER_DISABLED
|
||||||
static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) {
|
static nmbs_error recv_req_header(nmbs_t* nmbs, bool* first_byte_received) {
|
||||||
nmbs_error err = recv_msg_header(nmbs, first_byte_received);
|
nmbs_error err = recv_msg_header(nmbs, first_byte_received);
|
||||||
@ -1592,7 +1581,6 @@ static nmbs_error handle_read_write_registers(nmbs_t* nmbs) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NMBS_SERVER_READ_DEVICE_IDENTIFICATION_DISABLED
|
#ifndef NMBS_SERVER_READ_DEVICE_IDENTIFICATION_DISABLED
|
||||||
|
|
||||||
static nmbs_error handle_read_device_identification(nmbs_t* nmbs) {
|
static nmbs_error handle_read_device_identification(nmbs_t* nmbs) {
|
||||||
nmbs_error err = recv(nmbs, 3);
|
nmbs_error err = recv(nmbs, 3);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
@ -1919,7 +1907,7 @@ static nmbs_error read_discrete(nmbs_t* nmbs, uint8_t fc, uint16_t address, uint
|
|||||||
|
|
||||||
NMBS_DEBUG_PRINT("a %d\tq %d", address, quantity);
|
NMBS_DEBUG_PRINT("a %d\tq %d", address, quantity);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -1951,7 +1939,7 @@ static nmbs_error read_registers(nmbs_t* nmbs, uint8_t fc, uint16_t address, uin
|
|||||||
|
|
||||||
NMBS_DEBUG_PRINT("a %d\tq %d ", address, quantity);
|
NMBS_DEBUG_PRINT("a %d\tq %d ", address, quantity);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -1980,7 +1968,7 @@ nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value) {
|
|||||||
|
|
||||||
NMBS_DEBUG_PRINT("a %d\tvalue %d ", address, value_req);
|
NMBS_DEBUG_PRINT("a %d\tvalue %d ", address, value_req);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2000,7 +1988,7 @@ nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t v
|
|||||||
|
|
||||||
NMBS_DEBUG_PRINT("a %d\tvalue %d", address, value);
|
NMBS_DEBUG_PRINT("a %d\tvalue %d", address, value);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2034,7 +2022,7 @@ nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t qu
|
|||||||
NMBS_DEBUG_PRINT("%d ", coils[i]);
|
NMBS_DEBUG_PRINT("%d ", coils[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2068,7 +2056,7 @@ nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_
|
|||||||
NMBS_DEBUG_PRINT("%d ", registers[i]);
|
NMBS_DEBUG_PRINT("%d ", registers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2101,7 +2089,7 @@ nmbs_error nmbs_read_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t re
|
|||||||
put_2(nmbs, count);
|
put_2(nmbs, count);
|
||||||
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fread ", file_number, record_number, count);
|
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fread ", file_number, record_number, count);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2133,7 +2121,7 @@ nmbs_error nmbs_write_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t r
|
|||||||
put_regs(nmbs, registers, count);
|
put_regs(nmbs, registers, count);
|
||||||
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fwrite ", file_number, record_number, count);
|
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fwrite ", file_number, record_number, count);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2179,7 +2167,7 @@ nmbs_error nmbs_read_write_registers(nmbs_t* nmbs, uint16_t read_address, uint16
|
|||||||
NMBS_DEBUG_PRINT("%d ", registers[i]);
|
NMBS_DEBUG_PRINT("%d ", registers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2205,7 +2193,7 @@ nmbs_error nmbs_read_device_identification_basic(nmbs_t* nmbs, char* vendor_name
|
|||||||
put_1(nmbs, 1);
|
put_1(nmbs, 1);
|
||||||
put_1(nmbs, next_object_id);
|
put_1(nmbs, next_object_id);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2241,7 +2229,7 @@ nmbs_error nmbs_read_device_identification_regular(nmbs_t* nmbs, char* vendor_ur
|
|||||||
put_1(nmbs, 2);
|
put_1(nmbs, 2);
|
||||||
put_1(nmbs, next_object_id);
|
put_1(nmbs, next_object_id);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2266,29 +2254,6 @@ nmbs_error nmbs_read_device_identification_regular(nmbs_t* nmbs, char* vendor_ur
|
|||||||
nmbs_error nmbs_read_device_identification_extended(nmbs_t* nmbs, uint8_t object_id_start, uint8_t* ids, char** buffers,
|
nmbs_error nmbs_read_device_identification_extended(nmbs_t* nmbs, uint8_t object_id_start, uint8_t* ids, char** buffers,
|
||||||
uint8_t ids_length, uint8_t buffer_length,
|
uint8_t ids_length, uint8_t buffer_length,
|
||||||
uint8_t* objects_count_out) {
|
uint8_t* objects_count_out) {
|
||||||
// if (object_id_start < 0x80)
|
|
||||||
// return NMBS_ERROR_INVALID_ARGUMENT;
|
|
||||||
//
|
|
||||||
// msg_state_req(nmbs, 43);
|
|
||||||
// put_msg_header(nmbs, 3);
|
|
||||||
// put_1(nmbs, 0x0E);
|
|
||||||
// put_1(nmbs, 3);
|
|
||||||
// put_1(nmbs, object_id_start);
|
|
||||||
//
|
|
||||||
// nmbs_error err = send_req(nmbs);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// err = recv_read_device_identification_res(nmbs, buffers_count, buffers, buffer_length, NULL, next_object_id_out,
|
|
||||||
// objects_count_out);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// if (next_object_id_out && *next_object_id_out == 0x7F) {
|
|
||||||
// *next_object_id_out = object_id_start;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return NMBS_ERROR_NONE;
|
|
||||||
if (object_id_start < 0x80)
|
if (object_id_start < 0x80)
|
||||||
return NMBS_ERROR_INVALID_ARGUMENT;
|
return NMBS_ERROR_INVALID_ARGUMENT;
|
||||||
|
|
||||||
@ -2302,7 +2267,7 @@ nmbs_error nmbs_read_device_identification_extended(nmbs_t* nmbs, uint8_t object
|
|||||||
put_1(nmbs, 3);
|
put_1(nmbs, 3);
|
||||||
put_1(nmbs, next_object_id);
|
put_1(nmbs, next_object_id);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2332,7 +2297,7 @@ nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, uint8_t object_id, char
|
|||||||
put_1(nmbs, 4);
|
put_1(nmbs, 4);
|
||||||
put_1(nmbs, object_id);
|
put_1(nmbs, object_id);
|
||||||
|
|
||||||
nmbs_error err = send_req(nmbs);
|
nmbs_error err = send_msg(nmbs);
|
||||||
if (err != NMBS_ERROR_NONE)
|
if (err != NMBS_ERROR_NONE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -2341,107 +2306,6 @@ nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, uint8_t object_id, char
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, const nmbs_object_id* object_ids, uint8_t object_ids_len,
|
|
||||||
// char** buffers_out, uint8_t buffer_size) {
|
|
||||||
// if (object_ids_len == 0 || object_ids_len > 7) {
|
|
||||||
// return NMBS_ERROR_INVALID_ARGUMENT;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (buffers_out == NULL) {
|
|
||||||
// return NMBS_ERROR_INVALID_ARGUMENT;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// uint8_t cont_start = 0;
|
|
||||||
// uint8_t cont_length = 0;
|
|
||||||
// uint8_t last_id = 0;
|
|
||||||
// uint8_t indices[7] = {0};
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < object_ids_len; i++) {
|
|
||||||
// if (object_ids[i] > 0x06)
|
|
||||||
// return NMBS_ERROR_INVALID_ARGUMENT;
|
|
||||||
//
|
|
||||||
// indices[object_ids[i]] = i;
|
|
||||||
// bool send = false;
|
|
||||||
//
|
|
||||||
// if (cont_length == 0) {
|
|
||||||
// if (object_ids[i] == 0x00 || object_ids[i] == 0x03) {
|
|
||||||
// cont_start = i;
|
|
||||||
// cont_length = 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else if (object_ids[i] - last_id == 1) {
|
|
||||||
// cont_length++;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// cont_length = 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ((object_ids[cont_start] == 0x00 && cont_length == 3) ||
|
|
||||||
// (object_ids[cont_start] == 0x03 && cont_length == 5)) {
|
|
||||||
// send = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (object_ids_len - i > 3 && object_ids[i] == 0x00 && object_ids[i + 1] == 0x01 && object_ids[i + 2] == 0x02) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (send || i == object_ids_len - 1) {
|
|
||||||
// uint8_t next_id = 0;
|
|
||||||
// uint8_t objects_received = 0;
|
|
||||||
//
|
|
||||||
// msg_state_req(nmbs, 43);
|
|
||||||
// put_msg_header(nmbs, 3);
|
|
||||||
// put_1(nmbs, 0x0E);
|
|
||||||
//
|
|
||||||
// if (cont_length > 1) {
|
|
||||||
// // Stream access
|
|
||||||
// while (cont_length > 0) {
|
|
||||||
// if (object_ids[cont_start] < 0x03)
|
|
||||||
// put_1(nmbs, 1);
|
|
||||||
// if (object_ids[cont_start] >= 0x03)
|
|
||||||
// put_1(nmbs, 2);
|
|
||||||
//
|
|
||||||
// put_1(nmbs, next_id);
|
|
||||||
//
|
|
||||||
// nmbs_error err = send_req(nmbs);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// err = recv_read_device_identification_res(nmbs, cont_length, buffers_out + cont_start, buffer_size,
|
|
||||||
// indices + cont_start, &next_id, &objects_received);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// cont_start += objects_received;
|
|
||||||
// cont_length -= objects_received;
|
|
||||||
//
|
|
||||||
// for (int j = 0; j < objects_received; j++) {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // Individual access
|
|
||||||
// put_1(nmbs, 4);
|
|
||||||
// put_1(nmbs, object_ids[i]);
|
|
||||||
//
|
|
||||||
// nmbs_error err = send_req(nmbs);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// err = recv_read_device_identification_res(nmbs, 1, buffers_out + cont_start, buffer_size,
|
|
||||||
// indices + cont_start, &next_id, &objects_received);
|
|
||||||
// if (err != NMBS_ERROR_NONE)
|
|
||||||
// return err;
|
|
||||||
//
|
|
||||||
// cont_length = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// last_id = object_ids[i];
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return NMBS_ERROR_NONE;
|
|
||||||
//}
|
|
||||||
|
|
||||||
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint16_t data_len) {
|
nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint16_t data_len) {
|
||||||
msg_state_req(nmbs, fc);
|
msg_state_req(nmbs, fc);
|
||||||
put_msg_header(nmbs, data_len);
|
put_msg_header(nmbs, data_len);
|
||||||
@ -2452,7 +2316,7 @@ nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint
|
|||||||
NMBS_DEBUG_PRINT("%d ", data[i]);
|
NMBS_DEBUG_PRINT("%d ", data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return send_req(nmbs);
|
return send_msg(nmbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
22
nanomodbus.h
22
nanomodbus.h
@ -71,18 +71,6 @@ typedef enum nmbs_error {
|
|||||||
NMBS_EXCEPTION_SERVER_DEVICE_FAILURE = 4, /**< Modbus exception 4 */
|
NMBS_EXCEPTION_SERVER_DEVICE_FAILURE = 4, /**< Modbus exception 4 */
|
||||||
} nmbs_error;
|
} nmbs_error;
|
||||||
|
|
||||||
/**
|
|
||||||
* 43 / 14 (0x2B / 0x0E) Read Device Identification Object Id definitions
|
|
||||||
*/
|
|
||||||
typedef enum nmbs_object_id {
|
|
||||||
NMBS_OBJECT_ID_VENDOR_NAME = 0,
|
|
||||||
NMBS_OBJECT_ID_PRODUCT_CODE = 1,
|
|
||||||
NMBS_OBJECT_ID_MAJOR_MINOR_REVISION = 2,
|
|
||||||
NMBS_OBJECT_ID_VENDOR_URL = 3,
|
|
||||||
NMBS_OBJECT_ID_PRODUCT_NAME = 4,
|
|
||||||
NMBS_OBJECT_ID_MODEL_NAME = 5,
|
|
||||||
NMBS_OBJECT_ID_USER_APPLICATION_NAME = 6,
|
|
||||||
} nmbs_object_id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the nmbs_error is a modbus exception
|
* Return whether the nmbs_error is a modbus exception
|
||||||
@ -449,7 +437,6 @@ nmbs_error nmbs_read_write_registers(nmbs_t* nmbs, uint16_t read_address, uint16
|
|||||||
|
|
||||||
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Basic Object Id values (Read Device ID code 1)
|
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Basic Object Id values (Read Device ID code 1)
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param object_id requested Object Id
|
|
||||||
* @param vendor_name char array where the read VendorName value will be stored
|
* @param vendor_name char array where the read VendorName value will be stored
|
||||||
* @param product_code char array where the read ProductCode value will be stored
|
* @param product_code char array where the read ProductCode value will be stored
|
||||||
* @param major_minor_revision char array where the read MajorMinorRevision value will be stored
|
* @param major_minor_revision char array where the read MajorMinorRevision value will be stored
|
||||||
@ -458,26 +445,24 @@ nmbs_error nmbs_read_write_registers(nmbs_t* nmbs, uint16_t read_address, uint16
|
|||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_read_device_identification_basic(nmbs_t* nmbs, char* vendor_name, char* product_code,
|
nmbs_error nmbs_read_device_identification_basic(nmbs_t* nmbs, char* vendor_name, char* product_code,
|
||||||
char* major_minor_revision, uint8_t buffers_length);
|
char* major_minor_revision, uint8_t buffer_length);
|
||||||
|
|
||||||
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Regular Object Id values (Read Device ID code 2)
|
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Regular Object Id values (Read Device ID code 2)
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param object_id requested Object Id
|
|
||||||
* @param vendor_url char array where the read VendorUrl value will be stored
|
* @param vendor_url char array where the read VendorUrl value will be stored
|
||||||
* @param product_name char array where the read ProductName value will be stored
|
* @param product_name char array where the read ProductName value will be stored
|
||||||
* @param model_name char array where the read ModelName value will be stored
|
* @param model_name char array where the read ModelName value will be stored
|
||||||
* @param user_application_name char array where the read UserApplicationName value will be stored
|
* @param user_application_name char array where the read UserApplicationName value will be stored
|
||||||
*
|
|
||||||
* @param buffer_length length of every char array
|
* @param buffer_length length of every char array
|
||||||
*
|
*
|
||||||
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
* @return NMBS_ERROR_NONE if successful, other errors otherwise.
|
||||||
*/
|
*/
|
||||||
nmbs_error nmbs_read_device_identification_regular(nmbs_t* nmbs, char* vendor_url, char* product_name, char* model_name,
|
nmbs_error nmbs_read_device_identification_regular(nmbs_t* nmbs, char* vendor_url, char* product_name, char* model_name,
|
||||||
char* user_application_name, uint8_t buffers_length);
|
char* user_application_name, uint8_t buffer_length);
|
||||||
|
|
||||||
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Extended Object Id values (Read Device ID code 3)
|
/** Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Extended Object Id values (Read Device ID code 3)
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
* @param object_id requested Object Id
|
* @param object_id_start Object Id to start reading from
|
||||||
* @param ids array where the read Object Ids will be stored
|
* @param ids array where the read Object Ids will be stored
|
||||||
* @param buffers array of char arrays where the read values will be stored
|
* @param buffers array of char arrays where the read values will be stored
|
||||||
* @param ids_length length of the ids array and buffers array
|
* @param ids_length length of the ids array and buffers array
|
||||||
@ -501,7 +486,6 @@ nmbs_error nmbs_read_device_identification_extended(nmbs_t* nmbs, uint8_t object
|
|||||||
*/
|
*/
|
||||||
nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, uint8_t object_id, char* buffer, uint8_t buffer_length);
|
nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, uint8_t object_id, char* buffer, uint8_t buffer_length);
|
||||||
|
|
||||||
|
|
||||||
/** Send a raw Modbus PDU.
|
/** Send a raw Modbus PDU.
|
||||||
* CRC on RTU will be calculated and sent by this function.
|
* CRC on RTU will be calculated and sent by this function.
|
||||||
* @param nmbs pointer to the nmbs_t instance
|
* @param nmbs pointer to the nmbs_t instance
|
||||||
|
|||||||
@ -1072,13 +1072,13 @@ void test_fc23(nmbs_transport transport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error read_device_identification_map(nmbs_bitfield_256 map) {
|
nmbs_error read_device_identification_map(nmbs_bitfield_256 map) {
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_NAME);
|
nmbs_bitfield_set(map, 0x00);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_PRODUCT_CODE);
|
nmbs_bitfield_set(map, 0x01);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MAJOR_MINOR_REVISION);
|
nmbs_bitfield_set(map, 0x02);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_URL);
|
nmbs_bitfield_set(map, 0x03);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_PRODUCT_NAME);
|
nmbs_bitfield_set(map, 0x04);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MODEL_NAME);
|
nmbs_bitfield_set(map, 0x05);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_USER_APPLICATION_NAME);
|
nmbs_bitfield_set(map, 0x06);
|
||||||
nmbs_bitfield_set(map, 0x80);
|
nmbs_bitfield_set(map, 0x80);
|
||||||
nmbs_bitfield_set(map, 0x91);
|
nmbs_bitfield_set(map, 0x91);
|
||||||
nmbs_bitfield_set(map, 0xA2);
|
nmbs_bitfield_set(map, 0xA2);
|
||||||
@ -1087,41 +1087,41 @@ nmbs_error read_device_identification_map(nmbs_bitfield_256 map) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error read_device_identification_map_incomplete(nmbs_bitfield_256 map) {
|
nmbs_error read_device_identification_map_incomplete(nmbs_bitfield_256 map) {
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_NAME);
|
nmbs_bitfield_set(map, 0x00);
|
||||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MAJOR_MINOR_REVISION);
|
nmbs_bitfield_set(map, 0x02);
|
||||||
return NMBS_ERROR_NONE;
|
return NMBS_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nmbs_error read_device_identification(uint8_t object_id, char buffer[NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH]) {
|
nmbs_error read_device_identification(uint8_t object_id, char buffer[NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH]) {
|
||||||
switch (object_id) {
|
switch (object_id) {
|
||||||
case NMBS_OBJECT_ID_VENDOR_NAME:
|
case 0x00:
|
||||||
strcpy(buffer, "VendorName");
|
strcpy(buffer, "VendorName");
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_PRODUCT_CODE:
|
case 0x01:
|
||||||
strcpy(buffer, "ProductCode");
|
strcpy(buffer, "ProductCode");
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_MAJOR_MINOR_REVISION:
|
case 0x02:
|
||||||
strcpy(buffer, "MajorMinorRevision");
|
strcpy(buffer, "MajorMinorRevision");
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_VENDOR_URL:
|
case 0x03:
|
||||||
strncpy(buffer,
|
strncpy(buffer,
|
||||||
"VendorUrl90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
"VendorUrl90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
||||||
"e0123456",
|
"e0123456",
|
||||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_PRODUCT_NAME:
|
case 0x04:
|
||||||
strncpy(buffer,
|
strncpy(buffer,
|
||||||
"ProductName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdus"
|
"ProductName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdus"
|
||||||
"ize0123456",
|
"ize0123456",
|
||||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_MODEL_NAME:
|
case 0x05:
|
||||||
strncpy(buffer,
|
strncpy(buffer,
|
||||||
"ModelName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
"ModelName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
||||||
"e0123456",
|
"e0123456",
|
||||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||||
break;
|
break;
|
||||||
case NMBS_OBJECT_ID_USER_APPLICATION_NAME:
|
case 0x06:
|
||||||
strcpy(buffer, "UserApplicationName");
|
strcpy(buffer, "UserApplicationName");
|
||||||
break;
|
break;
|
||||||
case 0x80:
|
case 0x80:
|
||||||
@ -1264,8 +1264,6 @@ int main(int argc, char* argv[]) {
|
|||||||
UNUSED_PARAM(argc);
|
UNUSED_PARAM(argc);
|
||||||
UNUSED_PARAM(argv);
|
UNUSED_PARAM(argv);
|
||||||
|
|
||||||
for_transports(test_fc43_14, "send and receive FC 43 / 14 (0x2B / 0x0E) Read Device Identification");
|
|
||||||
|
|
||||||
for_transports(test_server_create, "create a modbus server");
|
for_transports(test_server_create, "create a modbus server");
|
||||||
|
|
||||||
for_transports(test_server_receive_base, "receive no messages without failing");
|
for_transports(test_server_receive_base, "receive no messages without failing");
|
||||||
@ -1292,5 +1290,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
for_transports(test_fc23, "send and receive FC 23 (0x17) Read/Write Multiple Registers");
|
for_transports(test_fc23, "send and receive FC 23 (0x17) Read/Write Multiple Registers");
|
||||||
|
|
||||||
|
for_transports(test_fc43_14, "send and receive FC 43 / 14 (0x2B / 0x0E) Read Device Identification");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user