Чет работает
This commit is contained in:
315
AllLibs/Modbus/Inc/rs_message.h
Normal file
315
AllLibs/Modbus/Inc/rs_message.h
Normal file
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @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[RS_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 RS_MSG_SIZE_MAX
|
||||
#error Define RS_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<RS_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_
|
||||
Reference in New Issue
Block a user