/** ****************************************************************************** * @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 Обработать функцию 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; iQnt; 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; iQnt; i++) { *(pHoldRegs++) = modbus_msg->DATA[i]; } return 1; } #else //MODBUS_ENABLE_HOLDINGS 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