Loading...
Searching...
No Matches
modbus_core.h
Go to the documentation of this file.
/**
*******************************************************************************
* @file modbus_core.h
* @brief Ядро Modbus протокола - определения и структуры
*******************************************************************************
@addtogroup MODBUS_INTERNAL Modbus Internal Tools
@ingroup MODBUS
@brief Внутренние штуки библиотеки
@{
*******************************************************************************
* @details
Базовые определения для реализации Modbus RTU устройства:
- Структуры сообщений Modbus
Коды функций и исключений
Константы размеров полей
Вспомогательные макросы
@section msg Структура сообщения:
[ADDR][FUNC][DATA...][CRC]
- Адрес: 1 байт
- Функция: 1 байт
- Данные: переменной длины
- CRC: 2 байта
******************************************************************************/
#ifndef __MODBUS_CORE_H_
#define __MODBUS_CORE_H_
#include "modbus_config.h"
#include "modbus_data.h"
#include "__crc_algs.h"
#include "__modbus_compat.h"
/**
* @addtogroup MODBUS_MESSAGE_DEFINES Modbus Message Tools
* @ingroup MODBUS
* @brief Определения протокола модбас
* @{
*/
/////////////////////////////////////////////////////////////////////
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
//-------------DEFINES FOR STRUCTURE----------------
/* defines for structure of modbus message */
#define TransactionID_size 2 ///< size of (Transaction ID)
#define ProtocolID_size 2 ///< size of (Protocol ID)
#define PDULength_size 2 ///< size of (PDU Length)
#define MbAddr_SIZE 1 ///< size of (Slave Addr)
#define Func_Code_SIZE 1 ///< size of (Function Code)
#define Addr_SIZE 2 ///< size of (Address)
#define Qnt_SIZE 2 ///< size of (Quantity)
#define ByteCnt_SIZE 1 ///< size of (Byte Count)
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
#define CRC_SIZE 2 ///< size of (MbCRC) in bytes
#ifndef MODBUS_PROTOCOL_TCP
/** @brief Size of whole RTU message */
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
#else
/** @brief Size of whole TCP message */
#define INFO_SIZE_MAX (TransactionID_size+ProtocolID_size+PDULength_size+MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE)
#endif
/** @brief Size of first part of message that will be received
first receive info part of message, than defines size of rest message*/
#define RX_FIRST_PART_SIZE INFO_SIZE_MAX
/** @brief Size of buffer: max size of whole message */
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
/**
* @brief Enum for modbus exception codes
* @details Prefix ET for Error Type
*/
typedef enum //MB_ExceptionTypeDef
{
// reading
ET_NO_ERRORS = 0x00, ///< no errors
ET_ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
ET_ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
ET_ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
ET_SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
// ET_ACKNOWLEDGE = 0x05, ///< idk
// ET_SLAVE_DEVICE_BUSY = 0x06, ///< idk
// ET_MEMORY_PARITY_ERROR = 0x08, ///< idk
}MB_ExceptionTypeDef;
#define FC_ERR_VALUES_START 0x80U ///< from this value starts error func codes
/**
* @brief Enum for modbus func codes
* @details Prefix FC for Function Code
*/
typedef enum //MB_FunctonTypeDef
{
/* COMMANDS */
// reading
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
#else
FC_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
FC_R_IN_REGS = 0x03, ///< Чтение регистров хранения
#endif
// writting
FC_W_COIL = 0x05, ///< Запись битовой ячейки
FC_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
FC_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
FC_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
FC_R_DIAGNOSTICS = 0x08, ///< Чтение диагностической информации устройства
FC_R_DEVICE_ID = 0x2B, ///< Чтение информации об устройстве
/* ERRORS */
// error reading
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
// error writting
FC_ERR_W_COIL = FC_W_COIL + FC_ERR_VALUES_START, ///< Ошибка записи битовой ячейки
FC_ERR_W_HOLD_REG = FC_W_HOLD_REG + FC_ERR_VALUES_START, ///< Ошибка записи одиночного регистра
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
}MB_FunctonTypeDef;
/** @brief Enum for MEI func codes */
typedef enum //MB_FunctonTypeDef
{
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
}MB_MEITypeDef;
/**
* @brief Enum for Read Device Id codes
* @details Prefix RID for Read ID
*/
typedef enum //MB_FunctonTypeDef
{
RID_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
@details All objects of this category are mandatory:
VendorName, Product code, and revision number */
RID_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
@details The device provides additional and optional
identifications and description data objects */
RID_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
@details The device provides additional and optional
identifications and description private data about the physical
device itself. All of these data are device dependent. */
RID_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
@details The device provides one specific identifications object. */
}ReadDevId;
/** @brief Structure for device identifications message type */
typedef struct
{
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
ReadDevId ReadDevId;
uint8_t Conformity; ///< Identification conformity level of the device and type of supported access @ref MODBUS_DEVICE_CONFORMITY
uint8_t MoreFollows;
uint8_t NextObjId;
uint8_t NumbOfObj;
}MB_DevIdMsgTypeDef;
/** @brief Structure for modbus messsage */
typedef struct // RS_MsgTypeDef
{
#ifdef MODBUS_PROTOCOL_TCP
uint16_t TransactionID; ///< Modbus TCP: ID Transaction
uint16_t ProtocolID; ///< Modbus TCP: ID Protocol
uint16_t PDULength; ///< Modbus TCP: PDU Length
#endif
uint8_t MbAddr; ///< Modbus Slave Address
MB_FunctonTypeDef FuncCode; ///< Modbus Function Code
MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
uint16_t Addr; ///< Modbus Address of data
uint16_t Qnt; ///< Quantity of modbus data
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
uint16_t MbData[DATA_SIZE]; ///< Modbus Data
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
uint16_t MbCRC; ///< Modbus CRC
}RS_MsgTypeDef;
//--------------------------------------------------
extern RS_MsgTypeDef MODBUS_MSG;
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
/////////////////////////////////////////////////////////////////////
////////////////////---MODBUS FUNCTION DEFINES---////////////////////
/**
* @brief Macros to set pointer to 16-bit array
* @param _arr_ - массив регистров (16-бит).
*/
#define MB_Set_Arr16_Ptr(_arr_) ((uint16_t*)(&(_arr_)))
/**
* @brief Macros to set pointer to register
* @param _parr_ - массив регистров.
* @param _addr_ - Номер регистра (его индекс) от начала массива _arr_.
*/
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
/**
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
* @param _parr_ - массив коилов.
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Mask
@code Пояснение выражений
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endcode
*/
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
/**
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
* @param _coil_ - Номер коила от начала массива _arr_.
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
@code Пояснение выражений
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
Визуальный пример: 30 коил будет регистре[1], на 14 бите:
register = 30/16 = 1
bit = 30 - (16*30/16) = 30 - 16 = 14
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|register[0]----| |register[1]----|
|skip this------| |get this-------|
|shift to 14 bit|
@endcode
*/
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
/** GENERAL_MODBUS_STUFF
* @}
*/
//------------------OTHER DEFINES-------------------
#define RegisterType_Holding 0
#define RegisterType_Input 1
#define RegisterType_Discrete 2
// create hadnles and settings for uart, tim, rs with _modbus_ name
//--------------------------------------------------
#ifndef Divide_Up
/**
* @brief Calc dividing including remainder
* @param _val_ - делимое.
* @param _div_ - делитель.
* @details Если результат деления без остатка: он возвращается как есть
Если с остатком - округляется вверх
*/
//#define Divide_Up(_val_, _div_) (((_val_)%(_div_))? (_val_)/(_div_)+1 : (_val_)/_div_) /* через тернарный оператор */
#define Divide_Up(_val_, _div_) ((_val_ - 1) / _div_) + 1 /* через мат выражение */
#endif
#ifndef ByteSwap16
/**
* @brief Swap between Little Endian and Big Endian
* @param v - Переменная для свапа.
* @return v (new) - Свапнутая переменная.
* @details Переключения между двумя типами хранения слова: HI-LO байты и LO-HI байты.
*/
#define ByteSwap16(v) (((v&0xFF00) >> (8)) | ((v&0x00FF) << (8)))
#endif
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////---FUNCTIONS---/////////////////////////////
/**
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
* @{
*/
/* Реализация этих функций лежит в modbus_data.c */
/* Check is address valid for certain array */
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB);
/* Define Address Origin for Input/Holding Registers */
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType);
/* Define Address Origin for coils */
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag);
/** MODBUS_CMD_PROCESS_FUNCTIONS
* @}
*/
/////////////////////////---FUNCTIONS---/////////////////////////////
#endif //__MODBUS_CORE_H_
/** MODBUS_INTERNAL
* @}
*/
__modbus_compat.h
Модуль для совместимости библиотеки MODBUS.
MB_DefineRegistersAddress
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
Define Address Origin for Input/Holding Registers.
Definition __modbus_data.c:66
MB_Check_Address_For_Arr
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
Check is address valid for certain array.
Definition __modbus_data.c:38
MB_DefineCoilsAddress
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
Define Address Origin for coils.
Definition __modbus_data.c:119
MB_FunctonTypeDef
MB_FunctonTypeDef
Enum for modbus func codes.
Definition modbus_core.h:94
MB_ExceptionTypeDef
MB_ExceptionTypeDef
Enum for modbus exception codes.
Definition modbus_core.h:76
ReadDevId
ReadDevId
Enum for Read Device Id codes.
Definition modbus_core.h:144
MODBUS_MSG
RS_MsgTypeDef MODBUS_MSG
Default Message Struct for Modbus.
Definition modbus.c:25
FC_ERR_VALUES_START
#define FC_ERR_VALUES_START
from this value starts error func codes
Definition modbus_core.h:88
MB_MEITypeDef
MB_MEITypeDef
Enum for MEI func codes.
Definition modbus_core.h:135
DATA_SIZE
#define DATA_SIZE
maximum number of data: DWORD (NOT MESSAGE SIZE)
Definition modbus_core.h:53
FC_ERR_R_DEVICE_INFO
@ FC_ERR_R_DEVICE_INFO
Ошибка чтения информации об устройстве
Definition modbus_core.h:130
FC_W_HOLD_REG
@ FC_W_HOLD_REG
Запись одиночного регистра
Definition modbus_core.h:109
FC_ERR_W_HOLD_REG
@ FC_ERR_W_HOLD_REG
Ошибка записи одиночного регистра
Definition modbus_core.h:125
FC_R_DEVICE_ID
@ FC_R_DEVICE_ID
Чтение информации об устройстве
Definition modbus_core.h:114
FC_R_COILS
@ FC_R_COILS
Чтение битовых ячеек
Definition modbus_core.h:97
FC_R_DISC_IN
@ FC_R_DISC_IN
Чтение дискретных входов
Definition modbus_core.h:98
FC_W_COILS
@ FC_W_COILS
Запись нескольких битовых ячеек
Definition modbus_core.h:110
FC_ERR_W_HOLD_REGS
@ FC_ERR_W_HOLD_REGS
Ошибка записи нескольких регистров
Definition modbus_core.h:127
FC_ERR_R_DISC_IN
@ FC_ERR_R_DISC_IN
Ошибка чтения дискретных входов
Definition modbus_core.h:119
FC_ERR_R_COILS
@ FC_ERR_R_COILS
Ошибка чтения битовых ячеек
Definition modbus_core.h:118
FC_R_IN_REGS
@ FC_R_IN_REGS
Чтение регистров хранения
Definition modbus_core.h:101
FC_W_COIL
@ FC_W_COIL
Запись битовой ячейки
Definition modbus_core.h:108
FC_ERR_R_DIAGNOSTIC
@ FC_ERR_R_DIAGNOSTIC
Ошибка чтения диагностической информации устройства
Definition modbus_core.h:129
FC_R_DIAGNOSTICS
@ FC_R_DIAGNOSTICS
Чтение диагностической информации устройства
Definition modbus_core.h:113
FC_ERR_W_COIL
@ FC_ERR_W_COIL
Ошибка записи битовой ячейки
Definition modbus_core.h:124
FC_ERR_R_HOLD_REGS
@ FC_ERR_R_HOLD_REGS
Ошибка чтения входных регистров
Definition modbus_core.h:121
FC_ERR_R_IN_REGS
@ FC_ERR_R_IN_REGS
Ошибка чтения регистров хранения
Definition modbus_core.h:120
FC_R_HOLD_REGS
@ FC_R_HOLD_REGS
Чтение входных регистров
Definition modbus_core.h:100
FC_ERR_W_COILS
@ FC_ERR_W_COILS
Ошибка записи нескольких битовых ячеек
Definition modbus_core.h:126
FC_W_HOLD_REGS
@ FC_W_HOLD_REGS
Запись нескольких регистров
Definition modbus_core.h:111
ET_ILLEGAL_DATA_VALUE
@ ET_ILLEGAL_DATA_VALUE
Значение, содержащееся в поле данных запроса, является недопустимой величиной
Definition modbus_core.h:81
ET_NO_ERRORS
@ ET_NO_ERRORS
no errors
Definition modbus_core.h:78
ET_SLAVE_DEVICE_FAILURE
@ ET_SLAVE_DEVICE_FAILURE
Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное дейс...
Definition modbus_core.h:82
ET_ILLEGAL_FUNCTION
@ ET_ILLEGAL_FUNCTION
Принятый код функции не может быть обработан
Definition modbus_core.h:79
ET_ILLEGAL_DATA_ADDRESS
@ ET_ILLEGAL_DATA_ADDRESS
Адрес данных, указанный в запросе, недоступен
Definition modbus_core.h:80
RID_REGULAR_IDENTIFICATIONS
@ RID_REGULAR_IDENTIFICATIONS
Regular Device Identifications.
Definition modbus_core.h:149
RID_SPEDIFIC_IDENTIFICATIONS
@ RID_SPEDIFIC_IDENTIFICATIONS
Specific Device Identifications.
Definition modbus_core.h:158
RID_BASIC_IDENTIFICATIONS
@ RID_BASIC_IDENTIFICATIONS
Basic Device Identifications.
Definition modbus_core.h:145
RID_EXTENDED_IDENTIFICATIONS
@ RID_EXTENDED_IDENTIFICATIONS
Extended Device Identifications.
Definition modbus_core.h:153
modbus_config.h
Конфигурационные параметры Modbus устройства
modbus_data.h
Определения структур данных Modbus устройства
MB_DevIdMsgTypeDef
Structure for device identifications message type.
Definition modbus_core.h:165
MB_DevIdMsgTypeDef::Conformity
uint8_t Conformity
Identification conformity level of the device and type of supported access MODBUS_DEVICE_CONFORMITY.
Definition modbus_core.h:168
MB_DevIdMsgTypeDef::MEI_Type
MB_MEITypeDef MEI_Type
MEI Type assigned number for Device Identifications Interface.
Definition modbus_core.h:166
RS_MsgTypeDef
Structure for modbus messsage.
Definition modbus_core.h:177
RS_MsgTypeDef::FuncCode
MB_FunctonTypeDef FuncCode
Modbus Function Code.
Definition modbus_core.h:185
RS_MsgTypeDef::Qnt
uint16_t Qnt
Quantity of modbus data.
Definition modbus_core.h:188
RS_MsgTypeDef::MbAddr
uint8_t MbAddr
Modbus Slave Address.
Definition modbus_core.h:184
RS_MsgTypeDef::Except_Code
MB_ExceptionTypeDef Except_Code
Exception Code for the command.
Definition modbus_core.h:192
RS_MsgTypeDef::MbCRC
uint16_t MbCRC
Modbus CRC.
Definition modbus_core.h:194
RS_MsgTypeDef::DevId
MB_DevIdMsgTypeDef DevId
Read Device Identifications Header struct.
Definition modbus_core.h:186
RS_MsgTypeDef::ByteCnt
uint8_t ByteCnt
Quantity of bytes of data in message to transmit/receive.
Definition modbus_core.h:189
RS_MsgTypeDef::MbData
uint16_t MbData[DATA_SIZE]
Modbus Data.
Definition modbus_core.h:191
RS_MsgTypeDef::Addr
uint16_t Addr
Modbus Address of data.
Definition modbus_core.h:187