- Data Access API расширено функциями для чтения/записи регистров - API для реквестов MB_RespGet.. перенесено в modbus_master - Мастер: коллбек реквеста вызывается и при таймауте - В коллбеке можно понять статус реквеста по hmodbus->RS_STATUS
171 lines
7.0 KiB
C
171 lines
7.0 KiB
C
/**
|
||
******************************************************************************
|
||
* @file modbus_holdregs.c
|
||
* @brief Реализация работы с регистрами хранения Modbus
|
||
******************************************************************************
|
||
* @details
|
||
Модуль обработки команд для holding registers (регистров хранения):
|
||
- Чтение множественных регистров (0x03) - копирование данных в буфер ответа
|
||
- Запись одиночного регистра (0x06) - прямая запись значения
|
||
- Запись множественных регистров (0x10) - пакетная запись из буфера
|
||
|
||
@section Валидация данных:
|
||
- Проверка соответствия количества байт и регистров
|
||
Валидация адресов через MB_DefineRegistersAddress()
|
||
- Обработка исключений при некорректных запросах
|
||
|
||
@section Echo-ответы:
|
||
При успешной записи формируется echo-ответ с теми же данными,
|
||
что были в запросе (для функций 0x05, 0x06, 0x0F, 0x10).
|
||
******************************************************************************/
|
||
#include "modbus_inputregs.h"
|
||
|
||
|
||
#ifdef MODBUS_ENABLE_HOLDINGS
|
||
|
||
|
||
|
||
/**
|
||
* @brief Записать регистр хранения по глобальному адресу.
|
||
* @param Addr Адрес регистра.
|
||
* @param WriteVal Число для записи.
|
||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и NO_ERRORS если все ок.
|
||
*
|
||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
||
Вне зависимости от того как регистры размещены в памяти.
|
||
*/
|
||
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
|
||
{
|
||
//---------CHECK FOR ERRORS----------
|
||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||
uint16_t *pHoldRegs;
|
||
|
||
//------------WRITE COIL-------------
|
||
Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
|
||
if(Exception == NO_ERRORS)
|
||
{
|
||
*(pHoldRegs) = WriteVal;
|
||
}
|
||
return Exception;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief Считать регистр хранения по глобальному адресу.
|
||
* @param Addr Адрес регистра.
|
||
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
|
||
* @return uint16_t Возвращает значение регистра.
|
||
*
|
||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
||
Вне зависимости от того как регистры размещены в памяти.
|
||
*/
|
||
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||
{
|
||
//---------CHECK FOR ERRORS----------
|
||
MB_ExceptionTypeDef Exception_tmp = 0;
|
||
|
||
uint16_t *pHoldRegs;
|
||
|
||
//------------READ COIL--------------
|
||
Exception_tmp = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
|
||
|
||
if(Exception) // if exception is not given to func fill it
|
||
*Exception = Exception_tmp;
|
||
|
||
if(Exception_tmp == NO_ERRORS)
|
||
{
|
||
return *(pHoldRegs);
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief Обработать функцию Read Holding Registers (03 - 0x03).
|
||
* @param modbus_msg Указатель на структуру собщения modbus.
|
||
* @return fMessageHandled Статус о результате обработки комманды.
|
||
* @details Обработка команды Read Holding Registers.
|
||
*/
|
||
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
||
{
|
||
//---------CHECK FOR ERRORS----------
|
||
// get origin address for data
|
||
uint16_t *pHoldRegs;
|
||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||
return 0;
|
||
|
||
|
||
//-----------READING REGS------------
|
||
// setup output message data size
|
||
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||
// read data
|
||
int i;
|
||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||
{
|
||
modbus_msg->DATA[i] = *(pHoldRegs++);
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief Обработать функцию Write Single Register (06 - 0x06).
|
||
* @param modbus_msg Указатель на структуру собщения modbus.
|
||
* @return fMessageHandled Статус о результате обработки комманды.
|
||
* @details Обработка команды Write Single Register.
|
||
*/
|
||
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
|
||
{
|
||
// get origin address for data
|
||
uint16_t *pHoldRegs;
|
||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||
return 0;
|
||
|
||
//-----------WRITTING REG------------
|
||
*(pHoldRegs) = modbus_msg->Qnt;
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* @brief Обработать функцию Write Multiple Registers (16 - 0x10).
|
||
* @param modbus_msg Указатель на структуру собщения modbus.
|
||
* @return fMessageHandled Статус о результате обработки комманды.
|
||
* @details Обработка команды Write Multiple Registers.
|
||
*/
|
||
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
|
||
{
|
||
//---------CHECK FOR ERRORS----------
|
||
if (modbus_msg->Qnt*2 != modbus_msg->ByteCnt)
|
||
{ // if quantity and bytes count arent match
|
||
modbus_msg->Except_Code = 3;
|
||
return 0;
|
||
}
|
||
// get origin address for data
|
||
uint16_t *pHoldRegs;
|
||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||
return 0;
|
||
|
||
//-----------WRITTING REGS-----------
|
||
for (int i = 0; i<modbus_msg->Qnt; i++)
|
||
{
|
||
*(pHoldRegs++) = modbus_msg->DATA[i];
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
|
||
#else //MODBUS_ENABLE_HOLDINGS
|
||
|
||
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal) {return ILLEGAL_FUNCTION;}
|
||
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;}
|
||
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||
|
||
#endif |