Новая версия протокола CAN.

Пока без ответа на запрос в общее адресное пространство.
This commit is contained in:
2026-02-25 11:57:45 +03:00
parent 167de72ea4
commit ed21d0f378
7 changed files with 487 additions and 400 deletions

View File

@@ -1,29 +1,13 @@
#include "requester.h"
static union Byte byte[2048][8];
#define byte_modbusadr(x) byte[x/64][(x%64)/8]
#define _GET_MODBUS_BIT(x) byte[x/64][(x%64)/8].AllBit>>((x%64)%8)
#define _GET_MODBUS_ADR(SensorId, RequestedBytePosition, RequestedBitPosition) SensorId*64 + RequestedBytePosition*8 + RequestedBitPosition
uint16_t ModbusFilters[COUNT_OF_MODBUS_SECTIONS][2];
struct device CurrentDevice;
struct device Device_on_the_Network[32];
struct data Data;
struct device Device_on_the_Network[8][16];
struct controlflags ControlFlags;
struct received_request ReceivedRequest;
uint8_t CurrentStep = 0;
uint8_t LastStep = 0;
struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE];
#define MAX_NUM_OF_DEVICES_PER_LINE 4
#define MAX_NUM_OF_REGISTERS_IN_DEVICE 255
//Регистр это слово (16 бит). uint16
uint16_t ModbusDemonstration[MAX_NUM_OF_DEVICES_PER_LINE][MAX_NUM_OF_REGISTERS_IN_DEVICE];
uint16_t ModbusAlternativeTable[MAX_NUM_OF_DEVICES_PER_LINE*MAX_NUM_OF_REGISTERS_IN_DEVICE];
_Bool IsLeapYear(uint8_t year)
{
year+=2000;
@@ -50,135 +34,94 @@ void REQUESTER_Init(void)
ControlFlags.IsPulse = 1;
MX_TIM7_Init();
MX_RTC_Init();
#ifdef _DEMO
int Reg_AltModbusTable;
//Тестовые значения регистров. Для отладки/демонстрации
for(int x = 0; x < MAX_NUM_OF_DEVICES_PER_LINE; x++)
{
for(int y = 0; y < MAX_NUM_OF_REGISTERS_IN_DEVICE; y++)
{
ModbusDemonstration[x][y] = x<<8 | y;
Reg_AltModbusTable = x*MAX_NUM_OF_REGISTERS_IN_DEVICE+y;
ModbusAlternativeTable[Reg_AltModbusTable] = x<<8 | y;
}
}
#endif
}
int ProverkaDefinaResult;
int ProverkaDefinaItem = 0;
int ProverkaArbitors = 0;
/**
* @brief Функция с обработкой полученных запросов
* @details В бесконечном цикле функция ожидает выставление флага о полученном запросе.
* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType.
* Обработка запроса аналоговых значений - REQUESTER_AnalogProcessing().
* Обработка широковещательных запросов - REQUESTER_BroadcastProcessing().
* Обработка запроса дискретных значений - REQUESTER_DiscreticProcessing().
* Обработка Modbus - REQUESTER_ModbusProcessing().
* @note
*/
void REQUESTER_MainWhile(void)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
extID eID;
eID.BitAll = 0;
eID.StandardFields.DeviceID = 2;
eID.StandardFields.DataType = DATA_TYPE_ANALOG;
eID.StandardFields.SensorType = 0x1F;
eID.StandardFields.SensorID = 0;
eID.StandardFields.Route = ROUTE_SLAVE;
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.ExtId = eID.BitAll;
int TxTest = 0;
HAL_TIM_Base_Start_IT(&htim7);
unsigned currentAttemptCount;
while(1)
{
if(AvailableCanRxMsg())
{
if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_ANALOG)
{
REQUESTER_AnalogProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_BROADCAST)
{
REQUESTER_BroadcastProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_DISCRETE)
{
REQUESTER_DiscreticProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_COIL ||
rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_DISCRETE ||
rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_HOLDING ||
rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_INPUT)
{
REQUESTER_ModbusProcessing(rxMsg[CurrentStep]);
}
currentAttemptCount = 0;
if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ANALOG)
{
REQUESTER_AnalogProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_BROADCAST)
{
REQUESTER_BroadcastProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_DISCRETE)
{
REQUESTER_DiscreticProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_GENERAL_ADDRESS_SPACE)
{
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_COIL ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_DISCRETE ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_HOLDING ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_INPUT)
{
REQUESTER_ModbusProcessing(rxMsg[CurrentStep]);
}
CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_RX_BUFFER_SIZE;
}
/*
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
if(HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox)!= HAL_OK)
{
ProverkaArbitors++;
}
*/
// eID.Fields.SensorID++;
// if(eID.Fields.SensorID>10)
//{
// eID.Fields.SensorID = 0;
// }
}
}
/**
* @brief Функция обработки аналоговых запросов.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура.
*/
void REQUESTER_AnalogProcessing(struct RXMsg _rxMsg)
CRR_Status REQUESTER_AnalogProcessing(struct RXMsg _rxMsg)
{
switch (_rxMsg.eID.StandardFields.SensorType)
switch (_rxMsg.eID.Fields.Msg.Analog.SensorType)
{
case SENSOR_TYPE_ANALOG_UNIVERSAL:
{
CanRequestToAnalogUniversal(_rxMsg);
return (CRR_Status)CanRequestToAnalogUniversal(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_USTAVKI:
{
CanRequestToAnalogUSTAVKI(_rxMsg);
return (CRR_Status)CanRequestToAnalogUSTAVKI(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_U:
{
CanRequestToAnalogUSens(_rxMsg);
return (CRR_Status)CanRequestToAnalogUSens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_I:
{
CanRequestToAnalogISens(_rxMsg);
return (CRR_Status)CanRequestToAnalogISens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_T:
{
CanRequestToAnalogTSens(_rxMsg);
return (CRR_Status)CanRequestToAnalogTSens(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE
return CRR_ERROR;
break;
}
return CRR_ERROR;
}
__weak HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg)
@@ -191,7 +134,7 @@ __weak HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'U';
@@ -213,7 +156,7 @@ __weak HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 7;
data[0] = 'U';
@@ -236,15 +179,15 @@ __weak HAL_StatusTypeDef CanRequestToAnalogUSens(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'U';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
data[1] = 'S';
data[2] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 1000;
data[3] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 100 % 10;
data[4] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 10 % 10;
data[5] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
@@ -258,15 +201,15 @@ __weak HAL_StatusTypeDef CanRequestToAnalogISens(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'I';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
data[1] = 'S';
data[2] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 1000;
data[3] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 100 % 10;
data[4] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 10 % 10;
data[5] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
@@ -280,30 +223,34 @@ __weak HAL_StatusTypeDef CanRequestToAnalogTSens(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'T';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
data[1] = 'S';
data[2] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 1000;
data[3] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 100 % 10;
data[4] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID / 10 % 10;
data[5] = 47 + _rxMsg.eID.Fields.Msg.Analog.SensorID % 10;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция обработки широковещательных запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, выполняющая команды, переданные в широковещательном формате с головного (master) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени.
*/
void REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg)
CRR_Status REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg)
{
switch(_rxMsg.eID.StandardFields.SensorType)
switch(_rxMsg.eID.Fields.Msg.Broadcast.BroadcastType)
{
case SENSOR_TYPE_BROADCAST_STATUS:
{
//Обработка запроса статуса устройства
CanRequestToBroadcastStatus(_rxMsg);
if(CanRequestToBroadcastStatus(_rxMsg)!=HAL_OK)
{
return CRR_ERROR;
}
break;
}
case SENSOR_TYPE_BROADCAST_ONOFF:
@@ -326,8 +273,10 @@ void REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg)
}
default:
//RESERVE SENSOR TYPE.
return CRR_ERROR;
break;
}
return CRR_OK;
}
__weak HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg)
@@ -341,8 +290,9 @@ __weak HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg)
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.StandardFields.Route = ROUTE_SLAVE;
tmp_eID.StandardFields.DeviceID = CURRENT_ID_DEVICE;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
RTC_TimeTypeDef sTime = {0};
@@ -372,7 +322,7 @@ __weak void CanRequestToBroadcastRestart(struct RXMsg _rxMsg)
{
return;
}
if(_rxMsg.eID.StandardFields.SensorID == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8)))
if(_rxMsg.eID.Fields.Msg.Broadcast.Page == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8)))
{
uint64_t page = 0;
for(int i = 0; i < _rxMsg.DLC; i++)
@@ -416,12 +366,13 @@ __weak void CanRequestToBroadcastRtcSetup(struct RXMsg _rxMsg)
/**
* @brief Функция обработки дискретных запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство.
* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры.
*/
void REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg)
CRR_Status REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg)
{
switch(_rxMsg.eID.StandardFields.SensorType){
switch(_rxMsg.eID.Fields.Msg.Discrete.Type){
case SENSOR_TYPE_DISCRETE_ACCIDENT:
{
CanRequestToDiscreteAccident(_rxMsg);
@@ -459,8 +410,10 @@ void REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg)
}
default:
//RESERVE SENSOR TYPE.
return CRR_ERROR;
break;
}
return CRR_OK;
}
__weak void CanRequestToDiscreteAccident(struct RXMsg _rxMsg)
@@ -499,116 +452,144 @@ __weak void CanRequestToDiscreteRequestListOfParameters(struct RXMsg _rxMsg)
/**
* @brief Функция обработки Modbus запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, формирующая и отправляющая ответ на запросы.
*/
void REQUESTER_ModbusProcessing(struct RXMsg _rxMsg)
CRR_Status REQUESTER_ModbusProcessing(struct RXMsg _rxMsg)
{
switch(_rxMsg.eID.ModbusFields.DataType)
switch(_rxMsg.eID.Fields.MsgType)
{
case DATA_TYPE_MODBUS_COIL:
{
CanRequestToModbusCoil(_rxMsg);
return (CRR_Status)CanRequestToModbusCoil(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_DISCRETE:
{
CanRequestToModbusDiscrete(_rxMsg);
return (CRR_Status)CanRequestToModbusDiscrete(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_HOLDING:
{
CanRequestToModbusHolding(_rxMsg);
return (CRR_Status)CanRequestToModbusHolding(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_INPUT:
{
CanRequestToModbusInput(_rxMsg);
return (CRR_Status)CanRequestToModbusInput(_rxMsg);
break;
}
default:
//ERROR
return CRR_ERROR;
break;
}
return CRR_ERROR;
}
__weak void CanRequestToModbusCoil(struct RXMsg _rxMsg)
__weak HAL_StatusTypeDef CanRequestToModbusCoil(struct RXMsg _rxMsg)
{
return;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'M';
data[1] = 'C';
data[2] = ' ';
data[3] = 'S';
data[4] = _rxMsg.eID.Fields.Msg.Modbus.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = _rxMsg.eID.Fields.Msg.Modbus.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak void CanRequestToModbusDiscrete(struct RXMsg _rxMsg)
__weak HAL_StatusTypeDef CanRequestToModbusDiscrete(struct RXMsg _rxMsg)
{
return;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'M';
data[1] = 'D';
data[2] = ' ';
data[3] = 'S';
data[4] = _rxMsg.eID.Fields.Msg.Modbus.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = _rxMsg.eID.Fields.Msg.Modbus.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak void CanRequestToModbusHolding(struct RXMsg _rxMsg)
__weak HAL_StatusTypeDef CanRequestToModbusHolding(struct RXMsg _rxMsg)
{
return;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'M';
data[1] = 'H';
data[2] = ' ';
data[3] = 'S';
data[4] = _rxMsg.eID.Fields.Msg.Modbus.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = _rxMsg.eID.Fields.Msg.Modbus.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
__weak void CanRequestToModbusInput(struct RXMsg _rxMsg)
__weak HAL_StatusTypeDef CanRequestToModbusInput(struct RXMsg _rxMsg)
{
return;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'M';
data[1] = 'I';
data[2] = ' ';
data[3] = 'S';
data[4] = _rxMsg.eID.Fields.Msg.Modbus.StrAdr;
data[5] = ' ';
data[6] = 'C';
data[7] = _rxMsg.eID.Fields.Msg.Modbus.RegCount;
return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox);
}
/* СТАРЫЙ УЖАСНЫЙ МОДБАС
if((ReceivedRequest.SensorToModbus.Modbus.StrAdr>=0) && (ReceivedRequest.SensorToModbus.Modbus.StrAdr<=127))
{
//Обращение к существующему в устройстве модбас регистру
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.DLC = 8;
TxHeader.RTR = CAN_RTR_DATA;
int RequestFromDLC;
for(RequestFromDLC = ReceivedRequest.SensorToModbus.Modbus.StrAdr;
(RequestFromDLC<MAX_NUM_OF_REGISTERS_IN_DEVICE) &&
((RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count);
// RequestFromDLC++
)
{
TxHeader.DLC = 0;
extID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.StandardFields.Route = ROUTE_SLAVE;
eID.StandardFields.SensorType = RequestFromDLC>>11;
eID.StandardFields.SensorID = RequestFromDLC;
TxHeader.ExtId = eID.BitAll;
for(int DataFor = 0; DataFor < 8; DataFor+=2)
{
data[DataFor] = HighByteOfWord(ModbusDemonstration[CURRENT_ID_DEVICE][RequestFromDLC]);
data[DataFor+1] = LowByteOfWord(ModbusDemonstration[CURRENT_ID_DEVICE][RequestFromDLC]);
RequestFromDLC++;
TxHeader.DLC +=2;
if(!((RequestFromDLC<MAX_NUM_OF_REGISTERS_IN_DEVICE) &&
((RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count)))
{
break;
}
}
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
}
extID emID;
emID.BitAll = 0;
emID.ModbusFields.DeviceID = CURRENT_ID_DEVICE;
emID.ModbusFields.DataType = DATA_TYPE_ERROR;
emID.ModbusFields.CountReg = NONEXISTENT_ELEMENT;
emID.ModbusFields.Route = ROUTE_SLAVE;
TxHeader.DLC = 0;
for(;(RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count; RequestFromDLC++)
{
emID.ModbusFields.StrAdr = RequestFromDLC;
TxHeader.ExtId = emID.BitAll;
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
}
ReceivedRequest.ModbusFlags.AllFlags = 0;
return;
}
ReceivedRequest.ModbusFlags.AllFlags = 0;
*/
/**
* @brief
* @param extID tmp_eID
* @param uint32_t tmp_IDE
* @param uint32_t tmp_RTR
* @param uint32_t tmp_DLC
* @param uint8_t *tmp_DATA
* @param uint16_t tmp_LastStep
* @details
*/
void TakeRxMsgToBuffer(extID tmp_eID, uint32_t tmp_IDE, uint32_t tmp_RTR, uint32_t tmp_DLC, uint8_t *tmp_DATA, uint16_t tmp_LastStep)
{
rxMsg[tmp_LastStep].eID.BitAll = tmp_eID.BitAll;
@@ -638,28 +619,26 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
if(tmp_LastStep == CurrentStep)
{
//Буффер переполнен
return;
}
extID ExtID_Of_RX_MSG;
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
//Полученное сообщение - широковещательное
if (ExtID_Of_RX_MSG.StandardFields.DeviceID == ID_MAIN_DEVICE)
if (ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_BROADCAST)
{
if(ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_BROADCAST)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
//Если ID запроса соответствует ID устройства
if(ExtID_Of_RX_MSG.StandardFields.DeviceID == (CURRENT_ID_DEVICE))
if((ExtID_Of_RX_MSG.Fields.DeviceType == CURRENT_TYPE_DEVICE) && (ExtID_Of_RX_MSG.Fields.DeviceID == CURRENT_ID_DEVICE))
{
if(ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_DISCRETE)
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_DISCRETE)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
if(ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_ANALOG)
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_ANALOG)
{
//Является ли полученное сообщение - запросом
if(RxHeader.RTR)
@@ -668,20 +647,20 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
return;
}
}
if(ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_MODBUS_COIL ||
ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_MODBUS_DISCRETE ||
ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_MODBUS_HOLDING ||
ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_MODBUS_INPUT)
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_COIL ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_DISCRETE ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_HOLDING ||
ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_MODBUS_INPUT)
{
TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep);
return;
}
}
//Полученное сообщение - пульс устройств в сети
if (ExtID_Of_RX_MSG.StandardFields.DataType == DATA_TYPE_PULSE)
if (ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_PULSE)
{
Device_on_the_Network[ExtID_Of_RX_MSG.StandardFields.DeviceID].Status = ONLINE;
Device_on_the_Network[ExtID_Of_RX_MSG.StandardFields.DeviceID].TimeFromLastPulse = 0;
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].Status = ONLINE;
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
}
}
}
@@ -699,9 +678,11 @@ void REQUESTER_Pulse_TIM_Handler()
uint32_t TxMailBox = 0;
extID currentID;
currentID.BitAll = 0;
currentID.StandardFields.DeviceID = CURRENT_ID_DEVICE;
currentID.StandardFields.DataType = DATA_TYPE_PULSE;
currentID.StandardFields.Route = ROUTE_SLAVE;
currentID.Fields.DeviceID = CURRENT_ID_DEVICE;
currentID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
currentID.Fields.MsgType = DATA_TYPE_PULSE;
currentID.Fields.Route = ROUTE_SLAVE;
currentID.Fields.Priority = PRIORITY_STANDARD;
TxHeader.ExtId = currentID.BitAll;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
@@ -719,7 +700,7 @@ void REQUESTER_Pulse_TIM_Handler()
/**
* @brief Функция установки в RTC полученной даты/время из запроса.
* @param Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели.
* @param uint8_t *data - Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели.
*/
void REQUESTER_RTC_SYNC(uint8_t *data)
{
@@ -751,73 +732,122 @@ void REQUESTER_RTC_SYNC(uint8_t *data)
* @brief Функция настройки фильтров CAN.
* @details Настройка фильтров. Фильр для приёма сообщений с главного устройства. Фильтр для приёма на текущее устройство. Фильтр для приёма пульса других устройств в сети.
*/
void CONFIG_CAN_FILTER(uint8_t filterBank, uint32_t idFilter, uint32_t idMask)
{
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = filterBank;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
canFilterConfig.FilterIdHigh = (uint16_t)( ((idFilter & 0xFFFF) >> 13) ); // верхние 16 бит
canFilterConfig.FilterIdLow = (uint16_t)( (((idFilter & 0x1FFF) << 3) ) | CAN_IDE_32 ); // низкие 16 бит,
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask & 0xFFFF) >> 13) );
canFilterConfig.FilterMaskIdLow = (uint16_t)( (((idMask & 0x1FFF) << 3) ) | CAN_IDE_32 );
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
#define BIT27 (1UL << 27)
#define BITS_20_23_MASK (0xFUL << 20) // 4 бита (20..23)
#define BITS_24_26_MASK (0x7UL << 24) // 3 бита (24..26)
uint32_t filter1_id = BIT27 | CURRENT_TYPE_DEVICE | CURRENT_ID_DEVICE;
uint32_t filter1_mask = BIT27 | BITS_24_26_MASK | BITS_20_23_MASK; // все проверяемые биты
#define BITS_16_19_MASK (0xFUL << 16)
uint32_t filter2_id = DATA_TYPE_BROADCAST;
uint32_t filter2_mask = BITS_16_19_MASK;
uint32_t filter3_id = DATA_TYPE_PULSE;
uint32_t filter3_mask = BITS_16_19_MASK;
void REQUESTER_CAN_FILTERS()
{
//MAIN DEVICE
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = 0;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
/*Для ID устройства используются восемь младших битов.
Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
canFilterConfig.FilterIdHigh = (uint16_t)(ID_MAIN_DEVICE>>13);
canFilterConfig.FilterIdLow = (uint16_t)(ID_MAIN_DEVICE<<5) | CAN_IDE_32;
/*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//CURRENT DEVICE
canFilterConfig.FilterBank = 1;
/*Для ID устройства используются восемь младших битов.
Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
canFilterConfig.FilterIdHigh = (uint16_t)(CURRENT_ID_DEVICE>>13);
canFilterConfig.FilterIdLow = (uint16_t)(CURRENT_ID_DEVICE<<5) | CAN_IDE_32;
/*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//MODBUS
canFilterConfig.FilterBank = 2;
canFilterConfig.FilterIdHigh = (uint16_t)(0x03000000>>13);
canFilterConfig.FilterIdLow = (uint16_t)(0x03000000<<5) | CAN_IDE_32;
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//PULSE
canFilterConfig.FilterBank = 3;
canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)>>13);
//canFilterConfig.FilterIdHigh = (uint16_t)(0x1F000000>>13);
canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)<<5) | CAN_IDE_32;
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//DEBUG FILTER "ALL IDE WELCOME"
canFilterConfig.FilterBank = 4;
canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(0)>>13);
canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(0)<<5) | CAN_IDE_32;
canFilterConfig.FilterMaskIdHigh = (uint16_t)(0>>13); // we're checking only high 13 bits, that contained "key"
canFilterConfig.FilterMaskIdLow = (uint16_t)(0<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
// Первый фильтр: проверяем 20-27 биты, где 27-й всегда 1
CONFIG_CAN_FILTER(0, filter1_id, filter1_mask);
// Второй фильтр: проверяем 16-19 биты, равны DATA_TYPE_BROADCASTE
CONFIG_CAN_FILTER(1, filter2_id, filter2_mask);
// Третий фильтр: проверяем 16-19 биты, равны DATA_TYPE_PULSE
CONFIG_CAN_FILTER(2, filter3_id, filter3_mask);
}
//void REQUESTER_CAN_FILTERS()
//{
// //MAIN DEVICE
// CAN_FilterTypeDef canFilterConfig;
// canFilterConfig.FilterBank = 0;
// canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
// canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
// /*Для ID устройства используются восемь младших битов.
// Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
// canFilterConfig.FilterIdHigh = (uint16_t)(ID_MAIN_DEVICE>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(ID_MAIN_DEVICE<<5) | CAN_IDE_32;
// /*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
// canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
// canFilterConfig.FilterActivation = ENABLE;
// canFilterConfig.SlaveStartFilterBank = 14;
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //CURRENT DEVICE
// canFilterConfig.FilterBank = 1;
// /*Для ID устройства используются восемь младших битов.
// Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
// canFilterConfig.FilterIdHigh = (uint16_t)(CURRENT_ID_DEVICE>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(CURRENT_ID_DEVICE<<5) | CAN_IDE_32;
// /*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //MODBUS
// canFilterConfig.FilterBank = 2;
// canFilterConfig.FilterIdHigh = (uint16_t)(0x03000000>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(0x03000000<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //PULSE
// canFilterConfig.FilterBank = 3;
// canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//
// //DEBUG FILTER "ALL IDE WELCOME"
// canFilterConfig.FilterBank = 4;
// canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(0)>>13);
// canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(0)<<5) | CAN_IDE_32;
// canFilterConfig.FilterMaskIdHigh = (uint16_t)(0>>13); // we're checking only high 13 bits, that contained "key"
// canFilterConfig.FilterMaskIdLow = (uint16_t)(0<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
// if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK)
// {
// Error_Handler();
// }
//}