Loading...
Searching...
No Matches
E:/.WORK/STM32/Diod_Test/diode_tester/Core/Modbus/__modbus_data.c
/**
******************************************************************************
* @file modbus_data.c
* @brief Функции доступа к данным Modbus
******************************************************************************
* @details
Модуль реализует функции валидации адресов и доступа к данным:
- Проверка корректности запрашиваемых адресов
- Определение указателей на реальные данные в памяти
- Поддержка пользовательских массивов регистров и coils
@section Валидация адресов:
- MB_Check_Address_For_Arr() - проверка принадлежности адреса массиву
- MB_DefineRegistersAddress() - получение указателя на регистры
- MB_DefineCoilsAddress() - получение указателя на coils
******************************************************************************/
#include "modbus_core.h"
#include "modbus_coils.h"
#include "modbus_holdregs.h"
#include "modbus_inputregs.h"
#include "modbus_devid.h"
/**
* @brief Check is address valid for certain array.
* @param Addr Начальный адресс.
* @param Qnt Количество запрашиваемых элементов.
* @param R_ARR_ADDR Начальный адресс массива R_ARR.
* @param R_ARR_NUMB Количество элементов в массиве R_ARR.
* @return ExceptionCode - ET_ILLEGAL_DATA_ADRESS если адресс недействителен, и ET_NO_ERRORS если все ок.
*
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
* Если адресс Addr находится за пределами адрессов массива R_ARR - ET_ILLEGAL_DATA_ADDRESSю.
*/
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
{
// if address from this array
if(Addr >= R_ARR_ADDR)
{
// if quantity too big return error
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
{
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
}
// if all ok - return no errors
return ET_NO_ERRORS;
}
// if address isnt from this array return error
else
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
}
/**
* @brief Define Address Origin for Input/Holding Registers
* @param pRegs Указатель на указатель регистров.
* @param Addr Адрес начального регистра.
* @param Qnt Количество запрашиваемых регистров.
* @param WriteFlag Флаг регистр нужны для чтения или записи.
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
*
* @details Определение адреса начального регистра.
* @note WriteFlag пока не используется.
*/
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
{
/* check quantity error */
if (Qnt > DATA_SIZE)
{
return ET_ILLEGAL_DATA_VALUE; // return exception code
}
if(RegisterType == RegisterType_Holding)
{
// Default holding registers
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == ET_NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
}
// if address doesnt match any array - return illegal data address response
else
{
return ET_ILLEGAL_DATA_ADDRESS;
}
}
else if(RegisterType == RegisterType_Input)
{
// Default input registers
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == ET_NO_ERRORS)
{
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
}
// if address doesnt match any array - return illegal data address response
else
{
return ET_ILLEGAL_DATA_ADDRESS;
}
}
else
{
return ET_ILLEGAL_FUNCTION;
}
// if found requeried array return no err
return ET_NO_ERRORS; // return no errors
}
/**
* @brief Define Address Origin for coils
* @param pCoils Указатель на указатель коилов.
* @param Addr Адресс начального коила.
* @param Qnt Количество запрашиваемых коилов.
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
* @param WriteFlag Флаг коилы нужны для чтения или записи.
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
*
* @details Определение адреса начального регистра запрашиваемых коилов.
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
*/
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
{
/* check quantity error */
if (Qnt > 2000)
{
return ET_ILLEGAL_DATA_VALUE; // return exception code
}
// Default coils
if(MB_Check_Address_For_Arr(Addr, Qnt, C_COILS_ADDR, C_COILS_QNT) == ET_NO_ERRORS)
{
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr - C_COILS_ADDR); // указатель на выбранный по Addr массив коилов
}
// if address doesnt match any array - return illegal data address response
else
{
return ET_ILLEGAL_DATA_ADDRESS;
}
*start_shift = Addr % 16; // set shift to requested coil
// if found requeried array return no err
return ET_NO_ERRORS; // return no errors
}
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_ExceptionTypeDef
MB_ExceptionTypeDef
Enum for modbus exception codes.
Definition modbus_core.h:76
MB_Set_Register_Ptr
#define MB_Set_Register_Ptr(_parr_, _addr_)
Macros to set pointer to register.
Definition modbus_core.h:215
MB_Set_Coil_Reg_Ptr
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_)
Макрос для установки указателя на регистр, содержащий запрашиваемый коил
Definition modbus_core.h:232
DATA_SIZE
#define DATA_SIZE
maximum number of data: DWORD (NOT MESSAGE SIZE)
Definition modbus_core.h:53
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_ILLEGAL_FUNCTION
@ ET_ILLEGAL_FUNCTION
Принятый код функции не может быть обработан
Definition modbus_core.h:79
ET_ILLEGAL_DATA_ADDRESS
@ ET_ILLEGAL_DATA_ADDRESS
Адрес данных, указанный в запросе, недоступен
Definition modbus_core.h:80
modbus_coils.h
Работа с коилами Modbus.
modbus_core.h
Ядро Modbus протокола - определения и структуры
R_INPUT_ADDR
#define R_INPUT_ADDR
Начальный адрес входных регистров
Definition modbus_data.h:61
C_COILS_QNT
#define C_COILS_QNT
Количество регистров коилов
Definition modbus_data.h:70
C_COILS_ADDR
#define C_COILS_ADDR
Начальный адрес коилов
Definition modbus_data.h:69
R_HOLDING_ADDR
#define R_HOLDING_ADDR
Начальный адрес регистров хранения
Definition modbus_data.h:65
R_INPUT_QNT
#define R_INPUT_QNT
Количество входных регистров
Definition modbus_data.h:62
R_HOLDING_QNT
#define R_HOLDING_QNT
Количество регистров хранения
Definition modbus_data.h:66
modbus_devid.h
Идентификаторы устройства Modbus.
modbus_holdregs.h
Работа с регистрами хранения Modbus.
modbus_inputregs.h
Работа с входными регистрами Modbus.