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
|
||||
|
||||
**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
|
||||
resource-constrained systems like microcontrollers.
|
||||
@ -28,6 +29,7 @@ Its main features are:
|
||||
- 20 (0x14) Read File Record
|
||||
- 21 (0x15) Write File Record
|
||||
- 23 (0x17) Read/Write Multiple registers
|
||||
- 43/14 (0x2B/0x0E) Read Device Identification
|
||||
- Platform-agnostic
|
||||
- Requires only C99 and its standard library
|
||||
- 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_WRITE_FILE_RECORD_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
|
||||
- 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};
|
||||
err = nmbs_write_file_record(&nmbs, 1, 0, file, 4);
|
||||
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))
|
||||
return 1;
|
||||
}
|
||||
@ -106,7 +106,7 @@ int main(int argc, char* argv[]) {
|
||||
memset(file, 0, sizeof(file));
|
||||
err = nmbs_read_file_record(&nmbs, 1, 0, file, 4);
|
||||
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))
|
||||
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]);
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
* 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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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[]) {
|
||||
signal(SIGTERM, sighandler);
|
||||
@ -167,6 +195,8 @@ int main(int argc, char* argv[]) {
|
||||
callbacks.write_multiple_registers = handle_write_multiple_registers;
|
||||
callbacks.read_file_record = handle_read_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
|
||||
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
|
||||
static nmbs_error recv_req_header(nmbs_t* nmbs, bool* 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
|
||||
|
||||
#ifndef NMBS_SERVER_READ_DEVICE_IDENTIFICATION_DISABLED
|
||||
|
||||
static nmbs_error handle_read_device_identification(nmbs_t* nmbs) {
|
||||
nmbs_error err = recv(nmbs, 3);
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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);
|
||||
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)
|
||||
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);
|
||||
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)
|
||||
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_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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, next_object_id);
|
||||
|
||||
nmbs_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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, next_object_id);
|
||||
|
||||
nmbs_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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,
|
||||
uint8_t ids_length, uint8_t buffer_length,
|
||||
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)
|
||||
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, next_object_id);
|
||||
|
||||
nmbs_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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, object_id);
|
||||
|
||||
nmbs_error err = send_req(nmbs);
|
||||
nmbs_error err = send_msg(nmbs);
|
||||
if (err != NMBS_ERROR_NONE)
|
||||
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) {
|
||||
msg_state_req(nmbs, fc);
|
||||
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]);
|
||||
}
|
||||
|
||||
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_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
|
||||
@ -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)
|
||||
* @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 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
|
||||
@ -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.
|
||||
*/
|
||||
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)
|
||||
* @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 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 user_application_name char array where the read UserApplicationName value will be stored
|
||||
*
|
||||
* @param buffer_length length of every char array
|
||||
*
|
||||
* @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,
|
||||
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)
|
||||
* @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 buffers array of char arrays where the read values will be stored
|
||||
* @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);
|
||||
|
||||
|
||||
/** Send a raw Modbus PDU.
|
||||
* CRC on RTU will be calculated and sent by this function.
|
||||
* @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_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_NAME);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_PRODUCT_CODE);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MAJOR_MINOR_REVISION);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_URL);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_PRODUCT_NAME);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MODEL_NAME);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_USER_APPLICATION_NAME);
|
||||
nmbs_bitfield_set(map, 0x00);
|
||||
nmbs_bitfield_set(map, 0x01);
|
||||
nmbs_bitfield_set(map, 0x02);
|
||||
nmbs_bitfield_set(map, 0x03);
|
||||
nmbs_bitfield_set(map, 0x04);
|
||||
nmbs_bitfield_set(map, 0x05);
|
||||
nmbs_bitfield_set(map, 0x06);
|
||||
nmbs_bitfield_set(map, 0x80);
|
||||
nmbs_bitfield_set(map, 0x91);
|
||||
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_bitfield_set(map, NMBS_OBJECT_ID_VENDOR_NAME);
|
||||
nmbs_bitfield_set(map, NMBS_OBJECT_ID_MAJOR_MINOR_REVISION);
|
||||
nmbs_bitfield_set(map, 0x00);
|
||||
nmbs_bitfield_set(map, 0x02);
|
||||
return NMBS_ERROR_NONE;
|
||||
}
|
||||
|
||||
nmbs_error read_device_identification(uint8_t object_id, char buffer[NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH]) {
|
||||
switch (object_id) {
|
||||
case NMBS_OBJECT_ID_VENDOR_NAME:
|
||||
case 0x00:
|
||||
strcpy(buffer, "VendorName");
|
||||
break;
|
||||
case NMBS_OBJECT_ID_PRODUCT_CODE:
|
||||
case 0x01:
|
||||
strcpy(buffer, "ProductCode");
|
||||
break;
|
||||
case NMBS_OBJECT_ID_MAJOR_MINOR_REVISION:
|
||||
case 0x02:
|
||||
strcpy(buffer, "MajorMinorRevision");
|
||||
break;
|
||||
case NMBS_OBJECT_ID_VENDOR_URL:
|
||||
case 0x03:
|
||||
strncpy(buffer,
|
||||
"VendorUrl90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
||||
"e0123456",
|
||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||
break;
|
||||
case NMBS_OBJECT_ID_PRODUCT_NAME:
|
||||
case 0x04:
|
||||
strncpy(buffer,
|
||||
"ProductName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdus"
|
||||
"ize0123456",
|
||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||
break;
|
||||
case NMBS_OBJECT_ID_MODEL_NAME:
|
||||
case 0x05:
|
||||
strncpy(buffer,
|
||||
"ModelName90byteslongextendedobjectthatcombinedwithotheronesisdefinitelygonnaexceedthepdusiz"
|
||||
"e0123456",
|
||||
NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH);
|
||||
break;
|
||||
case NMBS_OBJECT_ID_USER_APPLICATION_NAME:
|
||||
case 0x06:
|
||||
strcpy(buffer, "UserApplicationName");
|
||||
break;
|
||||
case 0x80:
|
||||
@ -1264,8 +1264,6 @@ int main(int argc, char* argv[]) {
|
||||
UNUSED_PARAM(argc);
|
||||
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_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_fc43_14, "send and receive FC 43 / 14 (0x2B / 0x0E) Read Device Identification");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user