Loading...
Searching...
No Matches
rs_message.h
Go to the documentation of this file.
/**
*******************************************************************************
* @file rs_message.h
* @brief Библиотека обмена сообщениями по RS-интерфейсу
*******************************************************************************
@defgroup RS_TOOLS RS Tools
@brief Всякое для работы по UART/RS
@{
*******************************************************************************
* @details
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
через UART в режиме прерываний с поддержкой таймаутов.
@section posibility Основные возможности:
- Прием/передача в прерываниях
- Обработка IDLE линии для определения конца фрейма
- Таймауты приема через TIM
- Гибкая настройка размера сообщений
@section usage Использование:
1. Определить структуру сообщения и размеры буфера
2. Реализовать weak-функции обработки сообщений
3. Добавить вызовы RS_UART_Handler/RS_TIM_Handler в прерывания
4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT()
@section features Особенности:
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
- Состояния: отслеживается через флаги в RS_HandleTypeDef
- Таймауты: контролируют максимальное время ожидания фрейма
******************************************************************************/
#ifndef __RS_LIB_H_
#define __RS_LIB_H_
#include "modbus_core.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
/* Check that all defines required by RS are defined */
#ifndef MSG_SIZE_MAX
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
#endif
/**
* @cond Заглушки и внутренний недокументированный стаф
*/
/* Clear message-uart buffer */
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
/* Set/Reset flags */
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0;
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0; _hRS_->f.RX_Continue = 0;
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0;
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
#define RS_Set_TX_End_Flag(_hRS_) _hRS_->f.TX_Done = 1
#define RS_Set_RX_End(_hRS_) RS_Reset_RX_Flags(_hRS_); RS_Set_RX_End_Flag(_hRS_)
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
/* Clear all RS stuff */
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
#ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0
#endif
#ifndef local_time
#define local_time() uwTick
#endif
/** @endcond */
/**
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
* @ingroup RS_TOOLS
* @brief Дефайны для отладки периферии
* @{
*/
#ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0 ///< Количество переменных в @ref TrackerTypeDef
#endif
/**
* @brief Тип структуры для счетчиков-переменных
* @param num_user_vars Есть возмоность добавления num_user_vars количества пользовательскиъх переменных
*/
#define TrackerTypeDef(num_user_vars) void *
/** @brief Инкрементировать переменную - успешных событий */
#define TrackerCnt_Ok(_cntstruct_)
/** @brief Инкрементировать переменную - ошибок */
#define TrackerCnt_Err(_cntstruct_)
/** @brief Инкрементировать переменную - предупреждений */
#define TrackerCnt_Warn(_cntstruct_)
#ifndef printf_rs
/** @brief Printf обычных событий RS/UART/TIM */
#define printf_rs(...)
#endif
#ifndef printf_rs_err
/** @brief Printf ошибок RS/UART/TIM */
#define printf_rs_err(...)
#endif
#ifndef RS_TIM_Handler_ENTER
/** @brief Действия при заходе в прерывания таймера */
#define RS_TIM_Handler_ENTER()
#endif
#ifndef RS_TIM_Handler_EXIT
/** @brief Действия при выходе из прерывания таймера */
#define RS_TIM_Handler_EXIT()
#endif
#ifndef RS_UART_Handler_ENTER
/** @brief Действия при заходе в прерывания UART */
#define RS_UART_Handler_ENTER()
#endif
#ifndef RS_UART_Handler_EXIT
/** @brief Действия при выходе из прерывания UART */
#define RS_UART_Handler_EXIT()
#endif
/** RS_TOOLS
* @}
*/
// направление передачи rs485
#ifndef RS_EnableReceive
#define RS_EnableReceive() ///< Функция изменения направления передачи на ПРИЕМ для RS-485
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit() ///< Функция изменения направления передачи на ПЕРЕДАЧУ для RS-485
#endif
////////////////////////////---DEFINES---////////////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////---STRUCTURES & ENUMS---//////////////////////
//------------------ENUMERATIONS--------------------
/** @brief Enums for respond CMD about RS status */
typedef enum // RS_StatusTypeDef
{
/* IN-CODE STATUS (start from 0x01, and goes up)*/
/*0x01*/ RS_OK = 0x01,
/*0x02*/ RS_ERR,
/*0x03*/ RS_ABORTED,
/*0x04*/ RS_BUSY,
/*0x05*/ RS_SKIP,
/*0x06*/ RS_TIMEOUT,
/*0x07*/ RS_COLLECT_MSG_ERR,
/*0x08*/ RS_PARSE_MSG_ERR,
// reserved values
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
}RS_StatusTypeDef;
#define RS_MASTER_MODE_START 0x3 ///< Начало режимов мастера (до него - режим слейв)
/** @brief Enums for RS Modes */
typedef enum // RS_ModeTypeDef
{
RS_SLAVE_ALWAYS_WAIT = 0x01, ///< Слейв в постоянном ожидании
RS_RESERVED = 0x02, ///< резерв
RS_MASTER_REQUEST = 0x03, ///< Мастер с ручным запросом
//RS_MASTER_POLLING = 0x04, ///< Мастер с опросом в фоновом режиме
}RS_ModeTypeDef;
/** @brief Enums for Abort modes */
typedef enum // RS_AbortTypeDef
{
ABORT_TX = 0x01, ///< Отменить передачу
ABORT_RX = 0x02, ///< Отменить прием
ABORT_RX_TX = 0x03, ///< Отменить прием и передачу
ABORT_RS = 0x04, ///< Отменить любую работу UART в целом
}RS_AbortTypeDef;
//-----------STRUCTURE FOR HANDLE RS------------
/** @brief Struct for flags RS */
typedef struct
{
unsigned RS_Busy:1; ///< 1 - RS занят, 0 - RS свободен
unsigned RX_Ongoing:1; ///< 1 - Прием данных в активном состоянии, 0 - Ожидаем начало приема данных
unsigned RX_Busy:1; ///< 1 - Режим приема активен, 0 - Прием не активен
unsigned TX_Busy:1; ///< 1 - Режим передачи активен, 0 - Прием не активен
unsigned RX_Done:1; ///< 1 - Прием закончен, 0 - Прием еще в процессе или не инициализирован
unsigned TX_Done:1; ///< 1 - Передача закончена, 0 - Передача еще в процессе или не инициализирована
// Выставление следующие флагов определяет пользователь
unsigned RX_Continue:1; ///< 0 - Продолжить принимать, 0 - Начать прием сначала
unsigned MessageHandled:1; ///< 1 - Обработка запроса успешна, 0 - Обработка запроса в процессе или ошибка
unsigned EchoResponse:1; ///< 1 - Ответить эхом, 0 - Ответить своим сообщением
unsigned DeferredResponse:1; ///< 1 - Не начинать передачу в IT, 0 - Ответить в прерывании
unsigned DataUpdated:1; ///< 1 - Данные были обновлены
}RS_FlagsTypeDef;
/**
* @brief Handle for RS communication.
* @note Prefixes: h - handle, s - settings, f - flag
*/
typedef struct // RS_HandleTypeDef
{
/* MESSAGE */
uint8_t ID; ///< ID хендла
RS_MsgTypeDef *pMessagePtr; ///< Указатель на структуру протокола
uint8_t *pBufferPtr; ///< Указатеь на буфер UART
int32_t RS_Message_Size; ///< size of whole message, not only data
/* HANDLERS and SETTINGS */
UART_HandleTypeDef *huart; ///< Хендл UART
TIM_HandleTypeDef *htim; ///< Хендл TIM
RS_ModeTypeDef sRS_Mode; ///< Настройка: слейв/мастер @ref RS_ModeTypeDef
uint16_t sRS_Timeout; ///< Настройка: Таймаут в тиках таймера
void (*pCallback)(void*, void*); ///< Указатель на коллбек: принят ответ в режиме мастер
/* FLAGS */
RS_FlagsTypeDef f; ///< Флаги для контроля приема/передачи
/* RS STATUS */
uint32_t lastPacketTick; ///< Время последнего принятого пакета
RS_StatusTypeDef RS_STATUS; ///< Статус RS
TrackerTypeDef(RS_USER_VARS_NUMB) rs_err;
}RS_HandleTypeDef;
extern RS_HandleTypeDef hmodbus1;
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
/*--------------------Defined by users purposes--------------------*/
/* Пользовательская функция для ответа на запрос по UART */
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Пользовательская функция для обработки принятого ответа по UART */
__weak RS_StatusTypeDef RS_Response_Callback(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Пользовательская функция для сбора сообщения в буфер UART */
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
/* Пользовательская функция для парса сообщения из буфера UART */
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
//-------------------------GENERAL FUNCTIONS-------------------------
/*-----------------Should be called from main code-----------------*/
/* Начать прием по прерываниям */
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Начать передачу по прерываниям */
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Инициалазация структуры @ref RS_HandleTypeDef */
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
/* Отменить прием/передачу RS/UART */
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
//-------------------------GENERAL FUNCTIONS-------------------------
//-------------------------------------------------------------------
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
/* Обработчик для начала приема */
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Обработчик для начала передачи */
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* UART TX Callback: коллбек после окончания передачи */
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
/* Обработчик прерывания UART */
void RS_UART_Handler(RS_HandleTypeDef *hRS);
/* Обработчик прерывания TIM */
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
/* Запуск таймаута приема. */
RS_StatusTypeDef RS_Timeout_Start(RS_HandleTypeDef *hRS);
/* Остановка таймаута приема. */
RS_StatusTypeDef RS_Timeout_Stop(RS_HandleTypeDef *hRS);
/* Обновление (сброс) таймаута приема. */
RS_StatusTypeDef RS_Timeout_Update(RS_HandleTypeDef *hRS);
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
///////////////////////////---FUNCTIONS---///////////////////////////
/** RS_TOOLS
* @}
*/
#endif // __RS_LIB_H_
RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB
Количество переменных в TrackerTypeDef.
Definition rs_message.h:97
TrackerTypeDef
#define TrackerTypeDef(num_user_vars)
Тип структуры для счетчиков-переменных
Definition rs_message.h:104
RS_ModeTypeDef
RS_ModeTypeDef
Enums for RS Modes.
Definition rs_message.h:184
RS_Receive_IT
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Начать прием по прерываниям.
Definition rs_message.c:43
RS_Collect_Message
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
Пользовательская функция для сбора сообщения в буфер UART.
Definition modbus.c:193
RS_Timeout_Stop
RS_StatusTypeDef RS_Timeout_Stop(RS_HandleTypeDef *hRS)
Остановка таймаута приема.
Definition rs_message.c:491
RS_Abort
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode)
Отменить прием/передачу RS/UART.
Definition rs_message.c:193
RS_TIM_Handler
void RS_TIM_Handler(RS_HandleTypeDef *hRS)
Обработчик прерывания TIM.
Definition rs_message.c:433
RS_Transmit_IT
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Начать передачу по прерываниям.
Definition rs_message.c:91
RS_Handle_Transmit_Start
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Обработчик для начала передачи.
Definition rs_message.c:269
RS_Parse_Message
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
Пользовательская функция для парса сообщения из буфера UART.
Definition modbus.c:205
RS_UART_TxCpltCallback
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS)
UART TX Callback: коллбек после окончания передачи.
Definition rs_message.c:300
RS_StatusTypeDef
RS_StatusTypeDef
Enums for respond CMD about RS status.
Definition rs_message.h:164
RS_Response
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Пользовательская функция для ответа на запрос по UART.
Definition modbus.c:184
RS_Init
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr)
Инициалазация структуры RS_HandleTypeDef.
Definition rs_message.c:156
RS_UART_Handler
void RS_UART_Handler(RS_HandleTypeDef *hRS)
Обработчик прерывания UART.
Definition rs_message.c:320
RS_Handle_Receive_Start
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
Обработчик для начала приема.
Definition rs_message.c:237
RS_AbortTypeDef
RS_AbortTypeDef
Enums for Abort modes.
Definition rs_message.h:193
RS_Timeout_Start
RS_StatusTypeDef RS_Timeout_Start(RS_HandleTypeDef *hRS)
Запуск таймаута приема.
Definition rs_message.c:471
RS_Timeout_Update
RS_StatusTypeDef RS_Timeout_Update(RS_HandleTypeDef *hRS)
Обновление (сброс) таймаута приема.
Definition rs_message.c:509
hmodbus1
RS_HandleTypeDef hmodbus1
Default Handle for Modbus.
Definition modbus.c:24
RS_MASTER_REQUEST
@ RS_MASTER_REQUEST
Мастер с ручным запросом
Definition rs_message.h:187
RS_RESERVED
@ RS_RESERVED
резерв
Definition rs_message.h:186
RS_SLAVE_ALWAYS_WAIT
@ RS_SLAVE_ALWAYS_WAIT
Слейв в постоянном ожидании
Definition rs_message.h:185
ABORT_RS
@ ABORT_RS
Отменить любую работу UART в целом
Definition rs_message.h:197
ABORT_TX
@ ABORT_TX
Отменить передачу
Definition rs_message.h:194
ABORT_RX_TX
@ ABORT_RX_TX
Отменить прием и передачу
Definition rs_message.h:196
ABORT_RX
@ ABORT_RX
Отменить прием
Definition rs_message.h:195
modbus_core.h
Ядро Modbus протокола - определения и структуры
RS_FlagsTypeDef
Struct for flags RS.
Definition rs_message.h:203
RS_FlagsTypeDef::RX_Continue
unsigned RX_Continue
0 - Продолжить принимать, 0 - Начать прием сначала
Definition rs_message.h:214
RS_FlagsTypeDef::RX_Busy
unsigned RX_Busy
1 - Режим приема активен, 0 - Прием не активен
Definition rs_message.h:207
RS_FlagsTypeDef::RX_Done
unsigned RX_Done
1 - Прием закончен, 0 - Прием еще в процессе или не инициализирован
Definition rs_message.h:210
RS_FlagsTypeDef::DataUpdated
unsigned DataUpdated
1 - Данные были обновлены
Definition rs_message.h:218
RS_FlagsTypeDef::EchoResponse
unsigned EchoResponse
1 - Ответить эхом, 0 - Ответить своим сообщением
Definition rs_message.h:216
RS_FlagsTypeDef::DeferredResponse
unsigned DeferredResponse
1 - Не начинать передачу в IT, 0 - Ответить в прерывании
Definition rs_message.h:217
RS_FlagsTypeDef::TX_Done
unsigned TX_Done
1 - Передача закончена, 0 - Передача еще в процессе или не инициализирована
Definition rs_message.h:211
RS_FlagsTypeDef::TX_Busy
unsigned TX_Busy
1 - Режим передачи активен, 0 - Прием не активен
Definition rs_message.h:208
RS_FlagsTypeDef::RS_Busy
unsigned RS_Busy
1 - RS занят, 0 - RS свободен
Definition rs_message.h:204
RS_FlagsTypeDef::MessageHandled
unsigned MessageHandled
1 - Обработка запроса успешна, 0 - Обработка запроса в процессе или ошибка
Definition rs_message.h:215
RS_FlagsTypeDef::RX_Ongoing
unsigned RX_Ongoing
1 - Прием данных в активном состоянии, 0 - Ожидаем начало приема данных
Definition rs_message.h:205
RS_HandleTypeDef
Handle for RS communication.
Definition rs_message.h:228
RS_HandleTypeDef::ID
uint8_t ID
ID хендла
Definition rs_message.h:230
RS_HandleTypeDef::pBufferPtr
uint8_t * pBufferPtr
Указатеь на буфер UART.
Definition rs_message.h:232
RS_HandleTypeDef::lastPacketTick
uint32_t lastPacketTick
Время последнего принятого пакета
Definition rs_message.h:246
RS_HandleTypeDef::RS_Message_Size
int32_t RS_Message_Size
size of whole message, not only data
Definition rs_message.h:233
RS_HandleTypeDef::pMessagePtr
RS_MsgTypeDef * pMessagePtr
Указатель на структуру протокола
Definition rs_message.h:231
RS_HandleTypeDef::pCallback
void(* pCallback)(void *, void *)
Указатель на коллбек: принят ответ в режиме мастер
Definition rs_message.h:240
RS_HandleTypeDef::f
RS_FlagsTypeDef f
Флаги для контроля приема/передачи
Definition rs_message.h:243
RS_HandleTypeDef::sRS_Mode
RS_ModeTypeDef sRS_Mode
Настройка: слейв/мастер RS_ModeTypeDef.
Definition rs_message.h:238
RS_HandleTypeDef::RS_STATUS
RS_StatusTypeDef RS_STATUS
Статус RS.
Definition rs_message.h:247
RS_HandleTypeDef::sRS_Timeout
uint16_t sRS_Timeout
Настройка: Таймаут в тиках таймера
Definition rs_message.h:239
RS_HandleTypeDef::huart
UART_HandleTypeDef * huart
Хендл UART.
Definition rs_message.h:236
RS_HandleTypeDef::htim
TIM_HandleTypeDef * htim
Хендл TIM.
Definition rs_message.h:237
RS_MsgTypeDef
Structure for modbus messsage.
Definition modbus_core.h:177