release 0.4 (*API CHANGED)

*Не совсем апи, но поменялись enum в modbus_core.h:
- MB_ExceptionTypeDef
- MB_FunctonTypeDef

Необходимо обновить modbus_data.c:
NO_ERRORS 		->	NO_ERRORS
ILLEGAL_FUNCTION	->	ET_ILLEGAL_FUNCTION
ILLEGAL_DATA_ADDRESS 	-> 	ET_ILLEGAL_DATA_ADDRESS
ILLEGAL_DATA_ADDRESS	->	ET_ILLEGAL_DATA_ADDRESS

- множественные правки докумнтации
- множественный рефакторинг
This commit is contained in:
2025-11-06 21:33:08 +03:00
parent 3d106f18ef
commit c648a605f5
26 changed files with 1187 additions and 926 deletions

View File

@@ -1,12 +1,12 @@
/**
**************************************************************************
* @file modbus_slave.c
* @brief Модуль для реализации слейв MODBUS.
**************************************************************************
*******************************************************************************
* @file modbus_slave.c
* @brief Модуль для реализации слейв MODBUS.
*******************************************************************************
* @details
Файл содержит реализацию функций для работы Modbus в режиме слейва.
@section Функции и макросы
@section slave Функции и макросы
- MB_Slave_Response() — Ответ на запрос
- MB_Slave_Collect_Message() — Сбор сообщения в режиме слейва.
@@ -37,26 +37,26 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
}
MB_Diagnostics_SlaveMessageCnt();
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
if(modbus_msg->FuncCode < FC_ERR_VALUES_START)// if no errors after parsing
{
switch (modbus_msg->Func_Code)
switch (modbus_msg->FuncCode)
{
// Read Coils
case MB_R_COILS:
case FC_R_COILS:
hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr);
break;
// Read Hodling Registers
case MB_R_HOLD_REGS:
case FC_R_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr);
break;
case MB_R_IN_REGS:
case FC_R_IN_REGS:
hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr);
break;
// Write Single Coils
case MB_W_COIL:
case FC_W_COIL:
hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
@@ -66,7 +66,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
}
break;
case MB_W_HOLD_REG:
case FC_W_HOLD_REG:
hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
@@ -77,7 +77,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
break;
// Write Multiple Coils
case MB_W_COILS:
case FC_W_COILS:
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
@@ -88,7 +88,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
break;
// Write Multiple Registers
case MB_W_HOLD_REGS:
case FC_W_HOLD_REGS:
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr);
if(hmodbus->f.MessageHandled)
{
@@ -98,12 +98,12 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
}
break;
case MB_R_DEVICE_INFO:
case FC_R_DEVICE_ID:
hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr);
break;
// Добавить в switch-case после других case:
case MB_R_DIAGNOSTIC:
case FC_R_DIAGNOSTICS:
hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr);
break;
@@ -126,7 +126,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
{
MB_Diagnostics_ExceptionErrorCnt();
TrackerCnt_Warn(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START;
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
}
else
{
@@ -173,17 +173,29 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
else
{
//------INFO ABOUT DATA/MESSAGE------
#ifdef MODBUS_PROTOCOL_TCP
modbus_uart_buff[ind++] = modbus_msg->TransactionID >> 8;
modbus_uart_buff[ind++] = modbus_msg->TransactionID& 0xFF;
modbus_uart_buff[ind++] = modbus_msg->ProtocolID >> 8;
modbus_uart_buff[ind++] = modbus_msg->ProtocolID& 0xFF;
modbus_uart_buff[ind++] = modbus_msg->PDULength >> 8;
modbus_uart_buff[ind++] = modbus_msg->PDULength& 0xFF;
#endif
//-----------[first bytes]-----------
// set ID of message/user
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
// set dat or err response
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
modbus_uart_buff[ind++] = modbus_msg->FuncCode;
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
if (modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
{
// fill modbus header
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identifications header
if(0) {}
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // devide identifications header
{
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
@@ -201,7 +213,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------DATA----------------
//-----------[data bytes]------------
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
{ // set data
modbus_uart_buff[ind++] = *tmp_data_addr;
@@ -209,14 +221,17 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
}
}
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#ifdef MODBUS_ENABLE_DIAGNOSTICS
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
{
// Diagnostics special format: [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
modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
}
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // modbus data header
{
// set size of received data
@@ -230,7 +245,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------DATA----------------
//-----------[data bytes]------------
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
{ // set data
if (i%2 == 0) // HI byte
@@ -255,12 +270,14 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
//---------------CRC----------------
//---------[last 16 bytes]----------
#ifndef MODBUS_PROTOCOL_TCP
// calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// write crc to message structure and modbus-uart buffer
modbus_msg->MB_CRC = CRC_VALUE;
modbus_msg->MbCRC = CRC_VALUE;
modbus_uart_buff[ind++] = CRC_VALUE;
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
#endif
hmodbus->RS_Message_Size = ind;
@@ -279,15 +296,15 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
RS_StatusTypeDef MB_RES = 0;
int mb_func_size = 0;
if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
{
mb_func_size = 1;
}
else if(modbus_msg->Func_Code == MB_R_DEVICE_INFO)
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID)
{
mb_func_size = 0;
}
else if ((modbus_msg->Func_Code & ~ERR_VALUES_START) < 0x0F)
else if ((modbus_msg->FuncCode & ~FC_ERR_VALUES_START) < 0x0F)
{
mb_func_size = 1;
}
@@ -317,6 +334,16 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
hmodbus->f.RX_Continue = 0;
int expected_size = 0;
//-----INFO ABOUT DATA/MESSAGE-------
#ifdef MODBUS_PROTOCOL_TCP
modbus_msg->TransactionID =modbus_uart_buff[ind++]<<8;
modbus_msg->TransactionID |=modbus_uart_buff[ind++];
modbus_msg->ProtocolID =modbus_uart_buff[ind++]<<8;
modbus_msg->ProtocolID |=modbus_uart_buff[ind++];
modbus_msg->PDULength =modbus_uart_buff[ind++]<<8;
modbus_msg->PDULength |=modbus_uart_buff[ind++];
#endif
//-----------[first bits]------------
// get ID of message/user
if(modbus_uart_buff[ind] != hmodbus->ID)
@@ -330,33 +357,38 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
}
// get func code
modbus_msg->Func_Code = modbus_uart_buff[ind++];
if(modbus_msg->Func_Code & ERR_VALUES_START) // явная херня
modbus_msg->FuncCode = modbus_uart_buff[ind++];
if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // явная херня
{
MB_Diagnostics_SlaveNAKCnt();
modbus_msg->MbAddr = 0;
return RS_SKIP;
}
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identifications request
if(0) {}
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // if it device identifications request
{
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
modbus_msg->ByteCnt = 0;
}
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
#ifdef MODBUS_ENABLE_DIAGNOSTICS
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
{
// Diagnostics: читаем 4 байта в DATA[0] и DATA[1]
// Diagnostics: читаем 4 байта в MbData[0] и MbData[1]
// Sub-function
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
// Data
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
modbus_msg->Addr = 0; // не использует Addr
modbus_msg->Qnt = 0; // не использует Qnt
}
#endif //MODBUS_ENABLE_DIAGNOSTICS
else // if its classic modbus request
{
// get address from CMD
@@ -368,7 +400,7 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
modbus_msg->Qnt |= modbus_uart_buff[ind++];
}
if((hmodbus->pMessagePtr->Func_Code == 0x0F) || (hmodbus->pMessagePtr->Func_Code == 0x10))
if((hmodbus->pMessagePtr->FuncCode == 0x0F) || (hmodbus->pMessagePtr->FuncCode == 0x10))
hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
else
hmodbus->pMessagePtr->ByteCnt = 0;
@@ -395,11 +427,11 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
if (modbus_msg->ByteCnt > DATA_SIZE*2)
{
TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START;
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
MB_Diagnostics_CommunicationErrorCnt();
return RS_PARSE_MSG_ERR;
}
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
for(int i = 0; i < modbus_msg->ByteCnt; i++)
{ // set data
if (i%2 == 0)
@@ -414,24 +446,22 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
//---------------CRC----------------
//----------[last 16 bits]----------
#ifndef MODBUS_PROTOCOL_TCP
// calc crc of received data
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
// get crc of received data
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
modbus_msg->MbCRC = modbus_uart_buff[ind++];
modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
// compare crc
if (modbus_msg->MB_CRC != CRC_VALUE)
if (modbus_msg->MbCRC != CRC_VALUE)
{
MB_Diagnostics_CommunicationErrorCnt();
TrackerCnt_Err(hmodbus->rs_err);
modbus_msg->Func_Code |= ERR_VALUES_START;
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
}
#endif
return RS_OK;
}
#else // MODBUS_ENABLE_SLAVE
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) {return RS_ERR;}
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
#endif
#endif //MODBUS_ENABLE_SLAVE