520 lines
20 KiB
C
520 lines
20 KiB
C
/**
|
||
**************************************************************************
|
||
* @file modbus_master.c
|
||
* @brief Модуль для реализации мастера MODBUS.
|
||
**************************************************************************
|
||
* @details
|
||
Файл содержит реализацию функций для работы Modbus в режиме мастера.
|
||
|
||
@section Функции и макросы
|
||
|
||
- MB_Master_Collect_Message() — Сбор сообщения в режиме мастера
|
||
- MB_Master_Parse_Message() — Парс сообщения в режиме мастера
|
||
******************************************************************************/
|
||
#include "modbus.h"
|
||
|
||
#ifdef MODBUS_ENABLE_MASTER
|
||
|
||
|
||
/**
|
||
* @brief Получить значение регистра из ответа по его адресу
|
||
* @param modbus_msg Указатель на структуру сообщения
|
||
* @param reg_addr Адрес регистра, значение которого нужно получить
|
||
* @param reg_value Указатель для значения регистра
|
||
* @return 1 - успех, 0 - ошибка или reg_addr вне диапазона запроса
|
||
*/
|
||
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value)
|
||
{
|
||
if(modbus_msg == NULL || reg_value == NULL)
|
||
return 0;
|
||
|
||
// Проверяем что reg_addr в пределах запрошенного диапазона
|
||
if(reg_addr < modbus_msg->Addr || reg_addr >= modbus_msg->Addr + modbus_msg->Qnt)
|
||
return 0;
|
||
|
||
// Вычисляем индекс регистра в полученных данных
|
||
uint16_t reg_index = reg_addr - modbus_msg->Addr;
|
||
|
||
// Проверяем что регистр существует в данных
|
||
if(reg_index >= modbus_msg->ByteCnt / 2)
|
||
return 0;
|
||
|
||
// Получаем значение регистра
|
||
*reg_value = modbus_msg->DATA[reg_index];
|
||
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
||
* @param hRS Указатель на хендлер RS.
|
||
* @param rx_data_size Указатель на переменную для записи кол-ва байт для принятия.
|
||
* @return RS_RES Статус о корректности рассчета кол-ва байт для принятия.
|
||
* @details Определение сколько байтов надо принять по протоколу.
|
||
*/
|
||
static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||
{
|
||
RS_StatusTypeDef MB_RES = 0;
|
||
int mb_func_size = 0;
|
||
|
||
|
||
// Master mode - calculating response size from slave
|
||
if (modbus_msg->Func_Code & ERR_VALUES_START)
|
||
{
|
||
// Error response: [Addr][Func|0x80][ExceptCode][CRC]
|
||
mb_func_size = -1; // Only Exception Code
|
||
}
|
||
else if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||
{
|
||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||
mb_func_size = 1;
|
||
}
|
||
else if (modbus_msg->Func_Code == MB_R_DEVICE_INFO)
|
||
{
|
||
// Device identifications: variable size, need to read first to determine
|
||
mb_func_size = 0; // Will be determined after reading header
|
||
}
|
||
else
|
||
{
|
||
switch (modbus_msg->Func_Code & ~ERR_VALUES_START)
|
||
{
|
||
case 0x01: // Read Coils
|
||
case 0x02: // Read Discrete Inputs
|
||
case 0x03: // Read Holding Registers
|
||
case 0x04: // Read Input Registers
|
||
// Response: [ByteCount][Data...]
|
||
mb_func_size = modbus_msg->ByteCnt + 2; // ByteCount + variable data
|
||
break;
|
||
|
||
case 0x05: // Write Single Coil
|
||
case 0x06: // Write Single Register
|
||
// Echo response: [Addr][Value][CRC]
|
||
mb_func_size = 4; // Address(2) + Value(2)
|
||
break;
|
||
|
||
case 0x0F: // Write Multiple Coils
|
||
case 0x10: // Write Multiple Registers
|
||
// Echo response: [Addr][Qty][CRC]
|
||
mb_func_size = 4; // Address(2) + Quantity(2)
|
||
break;
|
||
|
||
default:
|
||
mb_func_size = 0;
|
||
}
|
||
}
|
||
|
||
mb_func_size = RX_FIRST_PART_SIZE + mb_func_size; // size of whole message
|
||
return mb_func_size;
|
||
}
|
||
|
||
/**
|
||
* @brief Сбор сообщения в буфер UART в режиме мастер (фрейм мастера из msg -> uart).
|
||
* @param hmodbus Указатель на хендлер RS.
|
||
* @param modbus_msg Указатель на структуру сообщения.
|
||
* @param modbus_uart_buff Указатель на буффер UART.
|
||
* @return RS_RES Статус о результате заполнения буфера.
|
||
*/
|
||
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||
{
|
||
int ind = 0; // ind for modbus-uart buffer
|
||
|
||
//------INFO ABOUT DATA/MESSAGE------
|
||
//-----------[first bytes]-----------
|
||
// set ID of slave device
|
||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||
|
||
// set function code
|
||
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||
|
||
if(modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||
{
|
||
// fill modbus header
|
||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications request
|
||
{
|
||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
||
}
|
||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||
{
|
||
// Diagnostics: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] >> 8; // Sub-function HI
|
||
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO
|
||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI
|
||
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO
|
||
}
|
||
else // classic modbus request
|
||
{
|
||
// set address
|
||
modbus_uart_buff[ind++] = modbus_msg->Addr >> 8;
|
||
modbus_uart_buff[ind++] = modbus_msg->Addr & 0xFF;
|
||
|
||
// set quantity
|
||
modbus_uart_buff[ind++] = modbus_msg->Qnt >> 8;
|
||
modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF;
|
||
|
||
// for write multiple functions
|
||
if((modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||
{
|
||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||
|
||
// write data bytes
|
||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||
{
|
||
modbus_uart_buff[ind++] = tmp_data_addr[i];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(ind < 0)
|
||
return RS_COLLECT_MSG_ERR;
|
||
|
||
//---------------CRC----------------
|
||
//---------[last 2 bytes]----------
|
||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||
modbus_msg->MB_CRC = CRC_VALUE;
|
||
modbus_uart_buff[ind++] = CRC_VALUE & 0xFF;
|
||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||
|
||
hmodbus->RS_Message_Size = ind;
|
||
|
||
return RS_OK;
|
||
}
|
||
|
||
/**
|
||
* @brief Парс сообщения в режиме мастер (фрейм слейва из uart -> msg).
|
||
* @param hmodbus Указатель на хендлер RS.
|
||
* @param modbus_msg Указатель на структуру сообщения.
|
||
* @param modbus_uart_buff Указатель на буффер UART.
|
||
* @return RS_RES Статус о результате заполнения структуры.
|
||
*/
|
||
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||
{
|
||
int ind = 0; // ind for modbus-uart buffer
|
||
int expected_size = 0;
|
||
|
||
// get ID of slave device
|
||
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
||
|
||
// get function code (check if error response)
|
||
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||
|
||
if(modbus_msg->Func_Code & ERR_VALUES_START) // error response
|
||
{
|
||
modbus_msg->Except_Code = modbus_uart_buff[ind++];
|
||
}
|
||
else if(modbus_msg->Func_Code < ERR_VALUES_START) // normal response
|
||
{
|
||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications response
|
||
{
|
||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||
modbus_msg->DevId.Conformity = modbus_uart_buff[ind++];
|
||
modbus_msg->DevId.MoreFollows = modbus_uart_buff[ind++];
|
||
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
||
modbus_msg->DevId.NumbOfObj = modbus_uart_buff[ind++];
|
||
|
||
modbus_msg->ByteCnt = 0;
|
||
|
||
// Парсинг объектов идентификации устройства
|
||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||
int data_index = 0;
|
||
|
||
for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++)
|
||
{
|
||
// Читаем ID объекта
|
||
uint8_t object_id = modbus_uart_buff[ind++];
|
||
tmp_data_addr[data_index++] = object_id;
|
||
|
||
// Читаем длину объекта
|
||
uint8_t object_length = modbus_uart_buff[ind++];
|
||
tmp_data_addr[data_index++] = object_length;
|
||
|
||
// Читаем данные объекта
|
||
for(int i = 0; i < object_length; i++)
|
||
{
|
||
tmp_data_addr[data_index++] = modbus_uart_buff[ind++];
|
||
}
|
||
|
||
modbus_msg->ByteCnt += (2 + object_length); // ID + длина + данные
|
||
}
|
||
}
|
||
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||
{
|
||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
|
||
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
|
||
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
|
||
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
|
||
}
|
||
else // classic modbus response
|
||
{
|
||
// get byte count for read functions
|
||
if((modbus_msg->Func_Code == 0x01) || (modbus_msg->Func_Code == 0x02) ||
|
||
(modbus_msg->Func_Code == 0x03) || (modbus_msg->Func_Code == 0x04))
|
||
{
|
||
modbus_msg->ByteCnt = modbus_uart_buff[ind++];
|
||
|
||
// read data bytes
|
||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||
{
|
||
if(i % 2 == 0) // HI byte
|
||
tmp_data_addr[i/2] = (uint16_t)modbus_uart_buff[ind++] << 8;
|
||
else // LO byte
|
||
tmp_data_addr[i/2] |= modbus_uart_buff[ind++];
|
||
}
|
||
}
|
||
// for write functions - echo address and quantity
|
||
else if((modbus_msg->Func_Code == 0x05) || (modbus_msg->Func_Code == 0x06) ||
|
||
(modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||
{
|
||
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
||
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
||
modbus_msg->Qnt = modbus_uart_buff[ind++] << 8;
|
||
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//---------------CRC----------------
|
||
//----------[last 2 bytes]----------
|
||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||
|
||
if(modbus_msg->MB_CRC != CRC_VALUE)
|
||
{
|
||
TrackerCnt_Err(hmodbus->rs_err);
|
||
return RS_PARSE_MSG_ERR;
|
||
}
|
||
|
||
return RS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/** @brief Сформировать запрос на чтение коилов */
|
||
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на чтение дискретных регистров */
|
||
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на чтение холдинг регистров */
|
||
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на чтение инпут регистров */
|
||
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на запись одного коила */
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на запись одного регистра */
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на запись нескольких регистров */
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
|
||
// Calculate byte count and prepare data
|
||
uint8_t byte_count = (quantity + 7) / 8;
|
||
msg.ByteCnt = byte_count;
|
||
|
||
// Copy coil data to message DATA array
|
||
for(int i = 0; i < byte_count; i++) {
|
||
if(i < DATA_SIZE) {
|
||
msg.DATA[i] = coils_data[i];
|
||
}
|
||
}
|
||
|
||
return msg;
|
||
}
|
||
|
||
/** @brief Сформировать запрос на запись нескольких коилов */
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||
|
||
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
|
||
|
||
// Copy register data to message DATA array
|
||
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
|
||
msg.DATA[i] = regs_data[i];
|
||
}
|
||
|
||
return msg;
|
||
}
|
||
|
||
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
||
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DIAGNOSTIC, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
|
||
return msg;
|
||
}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0000, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0001, data);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0002, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0004, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000A, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000B, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000C, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000D, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000E, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x000F, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0010, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0011, 0x0000);
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr)
|
||
{
|
||
return MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, 0x0012, 0x0000);
|
||
}
|
||
|
||
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id)
|
||
{
|
||
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||
return msg;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
#else
|
||
RS_MsgTypeDef msg_dummy = {0};
|
||
|
||
int MB_GetRegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
|
||
|
||
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data) {return msg_dummy;}
|
||
|
||
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
||
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||
|
||
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr) {return msg_dummy;}
|
||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id) {return msg_dummy;}
|
||
|
||
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||
#endif
|
||
|
||
|
||
|