Улучшена логика отправки сообщений и реализованы новые функции пакетной передачи
Реализована обработка разных типов сообщений (BroadCast, Discrete, Analog) в функции PROTOCAN_SEND_CORE с корректной разбивкой данных на пакеты размером до 8 байт. Добавлены новые функции для пакетной отправки данных по диапазону регистров (PROTOCAN_SEND_GENERAL_ADDRESS_SPACE) и модбас-данных (PROTOCAN_SEND_MODBUS).
This commit is contained in:
@@ -252,14 +252,20 @@ typedef struct{
|
|||||||
unsigned LastPulseStep; /**< Шаг последнего импульса. */
|
unsigned LastPulseStep; /**< Шаг последнего импульса. */
|
||||||
} ProtoCanDevice_t;
|
} ProtoCanDevice_t;
|
||||||
|
|
||||||
struct RXMsg{
|
/**
|
||||||
struct INFO{
|
* @brief Структура для хранения сообщения RXCAN.
|
||||||
unsigned EXT:1;
|
*/
|
||||||
unsigned RTR:1;
|
struct RXMsg {
|
||||||
}info;
|
/**
|
||||||
ProtoCanId_t eID;
|
* @brief Структура, содержащая флаги информации.
|
||||||
uint16_t DLC;
|
*/
|
||||||
uint8_t Data[8];
|
struct INFO {
|
||||||
|
unsigned EXT : 1; /**< Бит расширенного идентификатора (EXT). */
|
||||||
|
unsigned RTR : 1; /**< Бит запроса на передачу (RTR). */
|
||||||
|
} info; /**< Информационные флаги сообщения. */
|
||||||
|
ProtoCanId_t eID; /**< Идентификатор CAN-сообщения. */
|
||||||
|
uint16_t DLC; /**< Длина данных (Data Length Code). */
|
||||||
|
uint8_t Data[8]; /**< Массив данных (до 8 байт). */
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t AvailableCanRxMsg(void);
|
uint16_t AvailableCanRxMsg(void);
|
||||||
|
|||||||
@@ -635,6 +635,107 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg)
|
|||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отправляет сообщение по CAN-шине в соответствии с типом протокола.
|
||||||
|
* Эта функция формирует и отправляет сообщение через CAN-шину, основываясь на типе
|
||||||
|
* переданного ID и данных. Поддерживаются типы сообщений: широковещательные, дискретные
|
||||||
|
* и аналоговые.
|
||||||
|
* @param id Идентификатор сообщения, содержащий тип сообщения и другую информацию.
|
||||||
|
* @param coreData Структура данных, включающая тип, тело и данные для передачи.
|
||||||
|
* @return PROTOCAN_StatusTypeDef Статус операции.
|
||||||
|
* @details
|
||||||
|
* В зависимости от типа сообщения (панель broadcast, discrete или analog),
|
||||||
|
* формируется соответствующий пакет данных и отправляется на шину CAN.
|
||||||
|
* Для сообщений, превышающих длину 8 байт, передача выполняется пакетами.
|
||||||
|
* В случае ошибок при добавлении сообщения в очередь передачи, возвращается ошибка.
|
||||||
|
*/
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND_CORE(const ProtoCanId_t id, const struct ProtoCanCoreData coreData)
|
||||||
|
{
|
||||||
|
ProtoCanId_t localId = id;
|
||||||
|
uint8_t msgType = localId.Fields.MsgType;
|
||||||
|
CAN_TxHeaderTypeDef TxHeader;
|
||||||
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
uint32_t TxMailBox = 0;
|
||||||
|
uint8_t canData[8];
|
||||||
|
switch(id.Fields.MsgType)
|
||||||
|
{
|
||||||
|
case PROTOCAN_MSGTYPE_BROADCAST:
|
||||||
|
{
|
||||||
|
msgBodyBroadcastType body;
|
||||||
|
body.Fields.Type = coreData.Type;
|
||||||
|
body.Fields.Body = coreData.Body;
|
||||||
|
localId.Fields.MsgBody = body.Body;
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
TxHeader.DLC = 0;
|
||||||
|
if(HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_DISCRETE:
|
||||||
|
{
|
||||||
|
msgBodyDiscreteType body;
|
||||||
|
body.Fields.Type = coreData.Type;
|
||||||
|
uint8_t regsRemaining = coreData.DataCount;
|
||||||
|
uint8_t currentIndex = 0;
|
||||||
|
while(regsRemaining > 0)
|
||||||
|
{
|
||||||
|
uint8_t regsInPacket = (regsRemaining > 8) ? 8 : regsRemaining;
|
||||||
|
body.Fields.Body = coreData.Body + currentIndex;
|
||||||
|
localId.Fields.MsgBody = body.Body;
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
TxHeader.DLC = regsInPacket;
|
||||||
|
for(int i = 0; i < regsInPacket; i++)
|
||||||
|
{
|
||||||
|
canData[i] = coreData.Data[coreData.DataCount - regsRemaining];
|
||||||
|
}
|
||||||
|
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
||||||
|
if(status != HAL_OK)
|
||||||
|
{
|
||||||
|
return (PROTOCAN_StatusTypeDef)status;
|
||||||
|
}
|
||||||
|
regsRemaining -= regsInPacket;
|
||||||
|
currentIndex += regsInPacket;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PROTOCAN_MSGTYPE_ANALOG:
|
||||||
|
{
|
||||||
|
msgBodyAnalogType body;
|
||||||
|
body.Fields.Type = coreData.Type;
|
||||||
|
uint8_t regsRemaining = coreData.DataCount;
|
||||||
|
uint8_t currentIndex = 0;
|
||||||
|
while(regsRemaining > 0)
|
||||||
|
{
|
||||||
|
uint8_t regsInPacket = (regsRemaining > 8) ? 8 : regsRemaining;
|
||||||
|
body.Fields.SensorID = coreData.Body + currentIndex;
|
||||||
|
localId.Fields.MsgBody = body.Body;
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
TxHeader.DLC = regsInPacket;
|
||||||
|
for(int i = 0; i < regsInPacket; i++)
|
||||||
|
{
|
||||||
|
canData[i] = coreData.Data[coreData.DataCount - regsRemaining];
|
||||||
|
}
|
||||||
|
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
||||||
|
if(status != HAL_OK)
|
||||||
|
{
|
||||||
|
return (PROTOCAN_StatusTypeDef)status;
|
||||||
|
}
|
||||||
|
regsRemaining -= regsInPacket;
|
||||||
|
currentIndex += regsInPacket;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PROTOCAN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Обработка и ответ на запрос общего адресного пространства.
|
* @brief Обработка и ответ на запрос общего адресного пространства.
|
||||||
* Формирует и передает сообщение с данными о статусе "GAS-XXXX", где XXXX — значение из сообщения _rxMsg.
|
* Формирует и передает сообщение с данными о статусе "GAS-XXXX", где XXXX — значение из сообщения _rxMsg.
|
||||||
@@ -674,15 +775,12 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxM
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Отправляет произвольный диапазон регистров в пакетах по, максимум, 4 регистра за раз через CAN.
|
* @brief Отправляет произвольный диапазон регистров в пакетах по, максимум, 4 регистра за раз через CAN.
|
||||||
*
|
|
||||||
* Функция разбивает передаваемый массив регистров на пакеты по 4 или меньше и отправляет их по отдельности.
|
* Функция разбивает передаваемый массив регистров на пакеты по 4 или меньше и отправляет их по отдельности.
|
||||||
* Для каждого пакета формируется уникальный MsgBody, равный адресу первого регистра в пакете.
|
* Для каждого пакета формируется уникальный MsgBody, равный адресу первого регистра в пакете.
|
||||||
*
|
|
||||||
* @param priority Приоритет сообщения CAN. ProtoCan_Priority_TypeDef
|
* @param priority Приоритет сообщения CAN. ProtoCan_Priority_TypeDef
|
||||||
* @param regStartAdr Адрес первого регистра из всего массива.
|
* @param regStartAdr Адрес первого регистра из всего массива.
|
||||||
* @param data Указатель на массив регистров для отправки.
|
* @param data Указатель на массив регистров для отправки.
|
||||||
* @param regCount Общее количество регистров для отправки.
|
* @param regCount Общее количество регистров для отправки.
|
||||||
*
|
|
||||||
* @return Возвращает статус отправки: HAL_OK при успехе, или код ошибки HAL_StatusTypeDef при сбое.
|
* @return Возвращает статус отправки: HAL_OK при успехе, или код ошибки HAL_StatusTypeDef при сбое.
|
||||||
*/
|
*/
|
||||||
PROTOCAN_StatusTypeDef PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(ProtoCanId_t id, uint16_t regStartAdr, uint16_t *data, uint8_t regCount)
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(ProtoCanId_t id, uint16_t regStartAdr, uint16_t *data, uint8_t regCount)
|
||||||
@@ -712,8 +810,8 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND_GENERAL_ADDRESS_SPACE(ProtoCanId_t id, uint
|
|||||||
for(int i = 0; i < regsInPacket; i++)
|
for(int i = 0; i < regsInPacket; i++)
|
||||||
{
|
{
|
||||||
canData[(i * 2)] = LowByteOfWord(data[currentIndex + i]);
|
canData[(i * 2)] = LowByteOfWord(data[currentIndex + i]);
|
||||||
canData[(i * 2) + 1] = HighByteOfWord(data[currentIndex + i]);
|
canData[(i * 2) + 1] = HighByteOfWord(data[currentIndex + i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox);
|
||||||
|
|
||||||
@@ -896,82 +994,89 @@ __weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
* @brief Отправляет данные Modbus через CAN-шину в соответствии с типом сообщения.
|
||||||
int PROTOCAN_SEND_MODBUS(const ProtoCanId_t* id, const struct ProtoCanModbusData* modbusData)
|
* Эта функция формирует и отправляет Modbus-данные по CAN-шине, поддерживая
|
||||||
|
* различные типы сообщений: Coil, Discrete, Holding Register и Input Register.
|
||||||
|
* Для сообщений, превышающих 4 регистров, данные отправляются пакетами.
|
||||||
|
* @param id Идентификатор сообщения, содержащий тип сообщения и другую информацию.
|
||||||
|
* @param modbusData Структура с данными Modbus: адрес, количество регистров и сами данные.
|
||||||
|
* @return PROTOCAN_StatusTypeDef Статус операции.
|
||||||
|
* @details
|
||||||
|
* В зависимости от типа Modbus (coil/discrete или holding/input), формируется
|
||||||
|
* соответствующий CAN-пакет. Для coil/discrete отправляется один пакет, для holding/input —
|
||||||
|
* несколько, по 4 регистра в пакете. В случае ошибок при добавлении сообщения API HAL возвращается ошибка.
|
||||||
|
*/
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND_MODBUS(const ProtoCanId_t id, const struct ProtoCanModbusData modbusData)
|
||||||
{
|
{
|
||||||
if (!id || !modbusData)
|
ProtoCanId_t localId = id;
|
||||||
|
uint8_t msgType = localId.Fields.MsgType;
|
||||||
|
// Структура для отправки
|
||||||
|
CAN_TxHeaderTypeDef TxHeader;
|
||||||
|
uint32_t TxMailBox = 0;
|
||||||
|
uint8_t canData[8];
|
||||||
|
if(msgType == PROTOCAN_MSGTYPE_MODBUS_COIL || msgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE)
|
||||||
|
{
|
||||||
|
// Формируем body
|
||||||
|
msgBodyModbusType body;
|
||||||
|
body.Fields.StrAdr = modbusData.StrAdr;
|
||||||
|
body.Fields.RegCount = modbusData.RegCount;
|
||||||
|
// Устанавливаем коллизию ExtId с body.Body
|
||||||
|
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
||||||
|
// Обновляем ExtId
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
// Остальные настройки
|
||||||
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
TxHeader.DLC = modbusData.RegCount % 8 + 1;
|
||||||
|
// Формируем CAN данные
|
||||||
|
canData[0] = LowByteOfWord(modbusData.Data[0]);
|
||||||
|
canData[1] = HighByteOfWord(modbusData.Data[0]);
|
||||||
|
if (HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
{
|
{
|
||||||
return PROTOCAN_ERROR;
|
return PROTOCAN_ERROR;
|
||||||
}
|
}
|
||||||
ProtoCanId_t localId = *id;
|
}
|
||||||
uint8_t msgType = localId.Fields.MsgType;
|
else if(msgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || msgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
||||||
// Структура для отправки
|
{
|
||||||
CAN_TxHeaderTypeDef TxHeader;
|
uint16_t* dataPtr = modbusData.Data;
|
||||||
uint32_t TxMailBox = 0;
|
unsigned totalRegs = modbusData.RegCount;
|
||||||
uint8_t canData[8];
|
unsigned regsProcessed = 0;
|
||||||
if(msgType == PROTOCAN_MSGTYPE_MODBUS_COIL || msgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE)
|
unsigned startAddress = modbusData.StrAdr;
|
||||||
|
while (regsProcessed < totalRegs)
|
||||||
{
|
{
|
||||||
|
uint8_t regsInPacket = (totalRegs - regsProcessed) > 4 ? 4 : (totalRegs - regsProcessed);
|
||||||
// Формируем body
|
// Формируем body
|
||||||
msgBodyModbusType body;
|
msgBodyModbusType body;
|
||||||
body.Fields.StrAdr = modbusData->StrAdr;
|
body.Fields.StrAdr = startAddress;
|
||||||
body.Fields.RegCount = modbusData->RegCount;
|
body.Fields.RegCount = regsInPacket;
|
||||||
// Устанавливаем коллизию ExtId с body.Body
|
|
||||||
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
|
||||||
// Обновляем ExtId
|
// Обновляем ExtId
|
||||||
|
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
||||||
TxHeader.ExtId = localId.BitAll;
|
TxHeader.ExtId = localId.BitAll;
|
||||||
// Остальные настройки
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
TxHeader.IDE = CAN_ID_EXT; // Предположим, что используете расширенные ID
|
|
||||||
TxHeader.RTR = CAN_RTR_DATA;
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
TxHeader.TransmitGlobalTime = DISABLE;
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
TxHeader.DLC = modbusData->RegCount % 8 + 1;
|
TxHeader.DLC = regsInPacket * 2;
|
||||||
// Формируем CAN данные
|
// Добавляем регистры
|
||||||
canData[0] = (*modbusData->Data) & 0xFF;
|
for (int i = 0; i < regsInPacket; i++)
|
||||||
canData[1] = (*modbusData->Data >> 8) & 0xFF;
|
{
|
||||||
if (HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
canData[i * 2] = LowByteOfWord(dataPtr[regsProcessed + i]);
|
||||||
|
canData[i * 2 + 1] = HighByteOfWord(dataPtr[regsProcessed + i]);
|
||||||
|
}
|
||||||
|
// Отправляем сообщение
|
||||||
|
if(HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
{
|
{
|
||||||
return PROTOCAN_ERROR;
|
return PROTOCAN_ERROR;
|
||||||
}
|
}
|
||||||
}
|
regsProcessed += regsInPacket;
|
||||||
else if(msgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING || msgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
|
startAddress += regsInPacket;
|
||||||
{
|
}
|
||||||
uint16_t* dataPtr = modbusData->Data;
|
}
|
||||||
unsigned totalRegs = modbusData->RegCount;
|
else
|
||||||
unsigned regsProcessed = 0;
|
{
|
||||||
unsigned startAddress = modbusData->StrAdr;
|
return PROTOCAN_ERROR; // Неверный тип сообщения
|
||||||
while (regsProcessed < totalRegs)
|
}
|
||||||
{
|
return PROTOCAN_OK;
|
||||||
uint8_t regsInPacket = (totalRegs - regsProcessed) > 4 ? 4 : (totalRegs - regsProcessed);
|
|
||||||
// Формируем body
|
|
||||||
msgBodyModbusType body;
|
|
||||||
body.Fields.StrAdr = startAddress;
|
|
||||||
body.Fields.RegCount = regsInPacket;
|
|
||||||
// Обновляем ExtId
|
|
||||||
localId.Fields.MsgBody = (body.Body & 0xFFFF);
|
|
||||||
TxHeader.ExtId = localId.BitAll;
|
|
||||||
TxHeader.IDE = CAN_ID_EXT;
|
|
||||||
TxHeader.RTR = CAN_RTR_DATA;
|
|
||||||
TxHeader.TransmitGlobalTime = DISABLE;
|
|
||||||
TxHeader.DLC = regsInPacket * 2;
|
|
||||||
// Добавляем регистры
|
|
||||||
for (int i = 0; i < regsInPacket; i++)
|
|
||||||
{
|
|
||||||
canData[i * 2] = LowByteOfWord(dataPtr[regsProcessed + i]);
|
|
||||||
canData[i * 2 + 1] = HighByteOfWord(dataPtr[regsProcessed + i]);
|
|
||||||
}
|
|
||||||
// Отправляем сообщение
|
|
||||||
if(HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
|
||||||
{
|
|
||||||
return PROTOCAN_ERROR;
|
|
||||||
}
|
|
||||||
regsProcessed += regsInPacket;
|
|
||||||
startAddress += regsInPacket;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return PROTOCAN_ERROR; // Неверный тип сообщения
|
|
||||||
}
|
|
||||||
return PROTOCAN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1001,6 +1106,40 @@ __weak PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
|
|||||||
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Отправляет сообщение об ошибке по CAN-шине.
|
||||||
|
* Эта функция формирует и отправляет сообщение об ошибке с кодом и информацией,
|
||||||
|
* объединёнными в поле MsgBody идентификатора сообщения, и передаёт его через CAN.
|
||||||
|
* @param id Идентификатор сообщения, содержащий базовую информацию.
|
||||||
|
* @param errorData Структура с данными ошибки: код и дополнительная информация.
|
||||||
|
* @return PROTOCAN_StatusTypeDef Статус операции.
|
||||||
|
* @details
|
||||||
|
* В качестве данных передаётся 2 байта: старшие биты — информация об ошибке, младшие — код ошибки.
|
||||||
|
* Размер данных в CANFrames устанавливается нулевым, так как все данные инкапсулированы в MsgBody.
|
||||||
|
*/
|
||||||
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND_ERROR(const ProtoCanId_t id, const struct ProtoCanErrorData errorData)
|
||||||
|
{
|
||||||
|
ProtoCanId_t localId = id;
|
||||||
|
uint8_t msgType = localId.Fields.MsgType;
|
||||||
|
// Структура для отправки
|
||||||
|
CAN_TxHeaderTypeDef TxHeader;
|
||||||
|
uint32_t TxMailBox = 0;
|
||||||
|
uint8_t canData[8];
|
||||||
|
localId.Fields.MsgBody = ((errorData.Info << 8) | errorData.Code);
|
||||||
|
// Обновляем ExtId
|
||||||
|
TxHeader.ExtId = localId.BitAll;
|
||||||
|
// Остальные настройки
|
||||||
|
TxHeader.IDE = CAN_ID_EXT;
|
||||||
|
TxHeader.RTR = CAN_RTR_DATA;
|
||||||
|
TxHeader.TransmitGlobalTime = DISABLE;
|
||||||
|
TxHeader.DLC = 0;
|
||||||
|
if(HAL_CAN_AddTxMessage(_HCAN, &TxHeader, canData, &TxMailBox) != HAL_OK)
|
||||||
|
{
|
||||||
|
return PROTOCAN_ERROR;
|
||||||
|
}
|
||||||
|
return PROTOCAN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Записывает полученное сообщение CAN в буфер rxMsg.
|
* @brief Записывает полученное сообщение CAN в буфер rxMsg.
|
||||||
* Копирует параметры расширенного ID, типы, длину данных и сам данные в указанный элемент буфера.
|
* Копирует параметры расширенного ID, типы, длину данных и сам данные в указанный элемент буфера.
|
||||||
@@ -1183,32 +1322,22 @@ void PROTOCAN_FILTERS()
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Отправляет CAN-сообщение в зависимости от типа сообщения.
|
* @brief Отправляет CAN-сообщение в зависимости от типа сообщения.
|
||||||
*
|
|
||||||
* Эта функция анализирует тип сообщения в идентификаторе и вызывает
|
* Эта функция анализирует тип сообщения в идентификаторе и вызывает
|
||||||
* соответствующую функцию отправки. В текущей реализации поддерживается только
|
* соответствующую функцию отправки. В текущей реализации поддерживается только
|
||||||
* тип PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE.
|
* тип PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE.
|
||||||
*
|
|
||||||
* @param id Идентификатор CAN-сообщения, содержащий информацию о типе.
|
* @param id Идентификатор CAN-сообщения, содержащий информацию о типе.
|
||||||
* @param data Структура с данными, которые необходимо отправить. Зависит от типа сообщения.
|
* @param data Структура с данными, которые необходимо отправить. Зависит от типа сообщения.
|
||||||
*
|
* @return Статус выполнения операции.
|
||||||
* @return Статус выполнения операции:
|
|
||||||
* - PROTOCAN_OK при успешной отправке,
|
|
||||||
* - PROTOCAN_ERROR, если тип сообщения не поддерживается или произошла ошибка.
|
|
||||||
*/
|
*/
|
||||||
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
||||||
{
|
{
|
||||||
switch (id.Fields.MsgType)
|
switch(id.Fields.MsgType)
|
||||||
{
|
{
|
||||||
case PROTOCAN_MSGTYPE_BROADCAST:
|
case PROTOCAN_MSGTYPE_BROADCAST:
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PROTOCAN_MSGTYPE_DISCRETE:
|
case PROTOCAN_MSGTYPE_DISCRETE:
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PROTOCAN_MSGTYPE_ANALOG:
|
case PROTOCAN_MSGTYPE_ANALOG:
|
||||||
{
|
{
|
||||||
|
return PROTOCAN_SEND_CORE(id, data.CoreData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE:
|
case PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE:
|
||||||
@@ -1227,10 +1356,12 @@ PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data)
|
|||||||
case PROTOCAN_MSGTYPE_MODBUS_HOLDING:
|
case PROTOCAN_MSGTYPE_MODBUS_HOLDING:
|
||||||
case PROTOCAN_MSGTYPE_MODBUS_INPUT:
|
case PROTOCAN_MSGTYPE_MODBUS_INPUT:
|
||||||
{
|
{
|
||||||
|
return PROTOCAN_SEND_MODBUS(id, data.ModbusData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROTOCAN_MSGTYPE_ERROR:
|
case PROTOCAN_MSGTYPE_ERROR:
|
||||||
{
|
{
|
||||||
|
return PROTOCAN_SEND_ERROR(id, data.ErrorData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user