Добавлено три варианта приёма CAN (Бесконечный, все сообщения, одно сообщение).
This commit is contained in:
@@ -275,7 +275,9 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan,
|
||||
TIM_HandleTypeDef *tmp_tim);
|
||||
void PROTOCAN_DEINIT(uint8_t stage);
|
||||
void PROTOCAN_FILTERS(void);
|
||||
void PROTOCAN_LOOP(void);
|
||||
void PROTOCAN_LoopProcessRxMsgs(void);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ProcessAllRxMsgs(void);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ProcessSingleRxMsg(void);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data);
|
||||
|
||||
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
|
||||
@@ -305,7 +307,7 @@ PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg);
|
||||
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxMsg);
|
||||
|
||||
PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_RequestError(struct RXMsg _rxMsg);
|
||||
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg);
|
||||
|
||||
@@ -111,50 +111,165 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция с обработкой полученных запросов
|
||||
* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType.
|
||||
* Обработка запроса аналоговых значений - PROTOCAN_AnalogProcessing().
|
||||
* Обработка широковещательных запросов - PROTOCAN_BroadcastProcessing().
|
||||
* Обработка запроса дискретных значений - PROTOCAN_DiscreticProcessing().
|
||||
* Обработка запроса к общему адресному пространству - PROTOCAN_GeneralAddressSpace_Answer().
|
||||
* Обработка Modbus - PROTOCAN_ModbusProcessing().
|
||||
*/
|
||||
void PROTOCAN_LOOP(void)
|
||||
* @brief Бесконечный цикл обработки входящих CAN-сообщений.
|
||||
*
|
||||
* Эта функция постоянно проверяет наличие доступных сообщений в буфере CAN и
|
||||
* вызывает соответствующие обработчики в зависимости от типа полученного сообщения.
|
||||
* Обрабатываемые типы сообщений:
|
||||
* - Аналоговые данные
|
||||
* - Широковещательные сообщения
|
||||
* - Дискретные данные
|
||||
* - Общее адресное пространство
|
||||
* - Модбас сообщения
|
||||
* - Ошибки
|
||||
*
|
||||
* Обработка сообщений осуществляется внутри бесконечного цикла с использованием
|
||||
* функции AvailableCanRxMsg() для определения наличия новых сообщений.
|
||||
*
|
||||
* В конце каждого обработанного сообщения индекс текущего элемента буфера инкрементируется
|
||||
* с учетом размера буфера через операцию по модулю.
|
||||
*/
|
||||
void PROTOCAN_LoopProcessRxMsgs(void)
|
||||
{
|
||||
while(1)
|
||||
while(1)
|
||||
{
|
||||
if(AvailableCanRxMsg())
|
||||
{
|
||||
if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG)
|
||||
{
|
||||
PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST)
|
||||
{
|
||||
PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE)
|
||||
{
|
||||
PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE)
|
||||
{
|
||||
ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||
{
|
||||
PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR)
|
||||
{
|
||||
PROTOCAN_RequestError(rxMsg[CurrentStep]);
|
||||
}
|
||||
// Обновление индекса текущего сообщения с циклическим масштабированием
|
||||
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обрабатывает все доступные входящие CAN-сообщения.
|
||||
*
|
||||
* Эта функция последовательно обрабатывает все сообщения, доступные в буфере,
|
||||
* вызывая соответствующие функции обработчики в зависимости от типа сообщения.
|
||||
* После обработки каждого сообщения индекс текущего элемента буфера обновляется
|
||||
* циклически.
|
||||
*
|
||||
* @return PROTOCAN_OK, если все сообщения были обработаны успешно.
|
||||
* В противном случае возвращается код ошибки, полученный при обработке сообщения.
|
||||
*
|
||||
* Обработка происходит до тех пор, пока есть доступные сообщения, полученные функцией
|
||||
* AvailableCanRxMsg().
|
||||
*/
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ProcessAllRxMsgs(void)
|
||||
{
|
||||
PROTOCAN_StatusTypeDef result = PROTOCAN_TIMEOUT;
|
||||
while(AvailableCanRxMsg())
|
||||
{
|
||||
if(AvailableCanRxMsg())
|
||||
if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG)
|
||||
{
|
||||
if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG)
|
||||
{
|
||||
PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST)
|
||||
{
|
||||
PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE)
|
||||
{
|
||||
PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE)
|
||||
{
|
||||
ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||
{
|
||||
PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR)
|
||||
{
|
||||
CanRequestError(rxMsg[CurrentStep]);
|
||||
}
|
||||
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||
result = PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST)
|
||||
{
|
||||
result = PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE)
|
||||
{
|
||||
result = PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE)
|
||||
{
|
||||
result = ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||
{
|
||||
result = PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR)
|
||||
{
|
||||
result = PROTOCAN_RequestError(rxMsg[CurrentStep]);
|
||||
}
|
||||
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||
if(result != PROTOCAN_OK)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обрабатывает одно доступное CAN-сообщение.
|
||||
*
|
||||
* Эта функция проверяет наличие доступных сообщений в буфере и, если таковое есть,
|
||||
* выполняет обработку текущего сообщения в зависимости от его типа. После обработки
|
||||
* индекс текущего сообщения обновляется циклически.
|
||||
*
|
||||
* @return Прошедший статус обработки:
|
||||
* - PROTOCAN_OK, если сообщение успешно обработано,
|
||||
* - PROTOCAN_TIMEOUT, если сообщений не было,
|
||||
* - или код ошибки, возвращенный функцией обработки.
|
||||
*/
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ProcessSingleRxMsg(void)
|
||||
{
|
||||
PROTOCAN_StatusTypeDef result = PROTOCAN_TIMEOUT;
|
||||
if(AvailableCanRxMsg())
|
||||
{
|
||||
if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG)
|
||||
{
|
||||
result = PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST)
|
||||
{
|
||||
result = PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE)
|
||||
{
|
||||
result = PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE)
|
||||
{
|
||||
result = ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING ||
|
||||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||
{
|
||||
result = PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]);
|
||||
}
|
||||
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR)
|
||||
{
|
||||
result = PROTOCAN_RequestError(rxMsg[CurrentStep]);
|
||||
}
|
||||
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -568,10 +683,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg)
|
||||
msg.Body = _rxMsg.eID.Fields.MsgBody;
|
||||
data[0] = 'U';
|
||||
data[1] = 'S';
|
||||
data[2] = 47 + msg.Fields.SensorID / 1000;
|
||||
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = 47 + msg.Fields.SensorID % 10;
|
||||
data[2] = '0' + msg.Fields.SensorID / 1000;
|
||||
data[3] = '0' + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = '0' + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = '0' + msg.Fields.SensorID % 10;
|
||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||
}
|
||||
|
||||
@@ -598,10 +713,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg)
|
||||
msg.Body = _rxMsg.eID.Fields.MsgBody;
|
||||
data[0] = 'I';
|
||||
data[1] = 'S';
|
||||
data[2] = 47 + msg.Fields.SensorID / 1000;
|
||||
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = 47 + msg.Fields.SensorID % 10;
|
||||
data[2] = '0' + msg.Fields.SensorID / 1000;
|
||||
data[3] = '0' + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = '0' + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = '0' + msg.Fields.SensorID % 10;
|
||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||
}
|
||||
|
||||
@@ -628,10 +743,10 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg)
|
||||
msg.Body = _rxMsg.eID.Fields.MsgBody;
|
||||
data[0] = 'T';
|
||||
data[1] = 'S';
|
||||
data[2] = 47 + msg.Fields.SensorID / 1000;
|
||||
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = 47 + msg.Fields.SensorID % 10;
|
||||
data[2] = '0' + msg.Fields.SensorID / 1000;
|
||||
data[3] = '0' + msg.Fields.SensorID / 100 % 10;
|
||||
data[4] = '0' + msg.Fields.SensorID / 10 % 10;
|
||||
data[5] = '0' + msg.Fields.SensorID % 10;
|
||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||
}
|
||||
|
||||
@@ -1085,7 +1200,7 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND_MODBUS(const ProtoCanId_t id, const struct
|
||||
* @param _rxMsg Структура входящего сообщения RXMsg, данными которого формируется ответ-ошибка.
|
||||
* @return HAL_StatusTypeDef Статус выполнения команды CAN.
|
||||
*/
|
||||
__weak PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
|
||||
__weak PROTOCAN_StatusTypeDef PROTOCAN_RequestError(struct RXMsg _rxMsg)
|
||||
{
|
||||
CAN_TxHeaderTypeDef TxHeader;
|
||||
uint32_t TxMailBox = 0;
|
||||
|
||||
Reference in New Issue
Block a user