Init
This commit is contained in:
commit
9611aacdf5
|
|
@ -0,0 +1,155 @@
|
|||
//
|
||||
// Created by cfif on 16.03.2024.
|
||||
//
|
||||
|
||||
#ifndef CAN_MODULE_CAN_FRAME_UDS_H
|
||||
#define CAN_MODULE_CAN_FRAME_UDS_H
|
||||
|
||||
#include "SerialPortFrameIO.h"
|
||||
#include "SerialPortFrameTpIO.h"
|
||||
#include "CanSerialPortFrame.h"
|
||||
#include "LoggerToSerialPort.h"
|
||||
#include "CmsisRtosThreadUtils.h"
|
||||
#include "SystemMutexCmsis.h"
|
||||
|
||||
#define TP_FRAME_PADDING 0xaa
|
||||
|
||||
#define WAIT_FC_FRAME_TIMEOUT 200
|
||||
#define WAIT_FF_FRAME_TIMEOUT 300
|
||||
|
||||
#define WAIT_FRAME_WRITE 300
|
||||
|
||||
typedef enum {
|
||||
TP_TYPE_FRAME_SF = 0,
|
||||
TP_TYPE_FRAME_FF = 1,
|
||||
TP_TYPE_FRAME_CF = 2,
|
||||
TP_TYPE_FRAME_FC = 3
|
||||
} eTpTypeFrame;
|
||||
|
||||
typedef enum {
|
||||
TP_RECEIVED_DATA = 0,
|
||||
TP_RECEIVED_FC_DATA = 1,
|
||||
TP_ERROR_FS_ERROR_SIZE = 2,
|
||||
TP_ERROR_FC_TIMEOUT = 3,
|
||||
TP_ERROR_FC_ERROR = 4,
|
||||
TP_ERROR_FF_ERROR = 5,
|
||||
TP_ERROR_FF_ERROR_SIZE = 6,
|
||||
TP_ERROR_FF_ERROR_TIMEOUT = 7,
|
||||
TP_ERROR_CF_ERROR = 8,
|
||||
TP_ERROR_CF_ERROR_SIZE = 9,
|
||||
TP_ERROR_CF_ERROR_SN = 10,
|
||||
TP_ERROR_WRONG_ADDRESS= 11,
|
||||
TP_STANDBY = 12
|
||||
|
||||
} eTpResult;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
eTpTypeFrame typeFrame: 4;
|
||||
} eTpFrameHead;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t dl: 4;
|
||||
eTpTypeFrame typeFrame: 4;
|
||||
uint8_t data[7];
|
||||
} eTpFrameSF;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t dlM: 4;
|
||||
eTpTypeFrame typeFrame: 4;
|
||||
uint8_t dlL;
|
||||
uint8_t data[6];
|
||||
} eTpFrameFF;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t sn: 4;
|
||||
eTpTypeFrame typeFrame: 4;
|
||||
uint8_t data[7];
|
||||
} eTpFrameCF;
|
||||
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t status: 4;
|
||||
eTpTypeFrame typeFrame: 4;
|
||||
uint8_t blockSize;
|
||||
uint8_t timeST;
|
||||
} eTpFrameFC;
|
||||
|
||||
typedef struct {
|
||||
uint32_t adrCan;
|
||||
uint16_t len;
|
||||
uint8_t data[50];
|
||||
} tCanTP_data;
|
||||
|
||||
typedef struct {
|
||||
uint32_t adrCan;
|
||||
uint16_t len;
|
||||
uint8_t data[1024];
|
||||
} tCanTP_Ext_data;
|
||||
|
||||
typedef void (*tReceivedTP_func)(void *arg, tCanTP_data *data);
|
||||
typedef bool (*tReceivedCan_func)(void *arg, can_rx_message_type *data);
|
||||
|
||||
typedef struct {
|
||||
tSerialPortFrameIO *ioCanFrame;
|
||||
tLoggerToSerialPort *slog;
|
||||
char hexString[2048 * 2];
|
||||
volatile bool isFlowControl;
|
||||
|
||||
SystemMutexCmsis txAccessQueue;
|
||||
|
||||
uint32_t timeoutFF;
|
||||
|
||||
tCanTP_data *dataBuf;
|
||||
uint16_t dataBufMaxSize;
|
||||
uint16_t dataBufWorkLen;
|
||||
uint16_t dataBufLen;
|
||||
|
||||
uint16_t dataReceivedConsecutiveFrameLen;
|
||||
uint8_t sn;
|
||||
|
||||
tReceivedCan_func ReceivedCan_func;
|
||||
void *callback_argCan;
|
||||
|
||||
tReceivedTP_func receivedTP_func;
|
||||
void *callback_argTp;
|
||||
|
||||
uint8_t filterIdCount;
|
||||
uint32_t *filterReqId;
|
||||
uint32_t *filterRespId;
|
||||
uint8_t *filterDirReq;
|
||||
|
||||
uint8_t numBuf;
|
||||
|
||||
tStaticThreadBlock(1024) T_can_Listener0;
|
||||
tStaticThreadBlock(1024) T_can_Listener1;
|
||||
} tCanSerialPortFrameTp;
|
||||
|
||||
void CanSerialPortFrameTpInit(
|
||||
tCanSerialPortFrameTp *env,
|
||||
|
||||
uint8_t numBuf,
|
||||
|
||||
SystemMutexCmsis txAccessQueue,
|
||||
|
||||
tReceivedCan_func receivedCan_func,
|
||||
void *callback_argCan,
|
||||
|
||||
tReceivedTP_func receivedTP_func,
|
||||
void *callback_argTp,
|
||||
|
||||
tSerialPortFrameIO *ioCanFrame,
|
||||
tCanTP_data *dataBuf,
|
||||
uint16_t dataBufMaxSize,
|
||||
tLoggerToSerialPort *slog,
|
||||
|
||||
uint8_t filterIdCount,
|
||||
uint32_t *filterReqId,
|
||||
uint32_t *filterRespId,
|
||||
uint8_t *filterDirReq
|
||||
);
|
||||
|
||||
void CanSerialPortFrameTp_Start(tCanSerialPortFrameTp *env, uint8_t numBuf);
|
||||
|
||||
bool
|
||||
CanSerialPortFrameTpTransmit(tCanSerialPortFrameTp *env, uint8_t *data, uint16_t size, uint32_t id, uint32_t timeout);
|
||||
|
||||
#endif //CAN_MODULE_CAN_FRAME_UDS_H
|
||||
|
|
@ -0,0 +1,549 @@
|
|||
//
|
||||
// Created by cfif on 16.03.2024.
|
||||
//
|
||||
#include <SystemDelayInterface.h>
|
||||
#include "CanSerialPortFrameTP.h"
|
||||
#include "memory.h"
|
||||
#include "AsciiStringAssmeblingUtils.h"
|
||||
#include "SystemMutexCmsis.h"
|
||||
|
||||
|
||||
#define LOG_SIGN "CAN"
|
||||
#define LOGGER &env->slog->logger
|
||||
|
||||
_Noreturn void CanTpProcessing_ListenerTask0(tCanSerialPortFrameTp *env);
|
||||
|
||||
_Noreturn void CanTpProcessing_ListenerTask1(tCanSerialPortFrameTp *env);
|
||||
|
||||
void CanSerialPortFrameTpInit(
|
||||
tCanSerialPortFrameTp *env,
|
||||
|
||||
uint8_t numBuf,
|
||||
|
||||
SystemMutexCmsis txAccessQueue,
|
||||
|
||||
tReceivedCan_func receivedCan_func,
|
||||
void *callback_argCan,
|
||||
|
||||
tReceivedTP_func receivedTP_func,
|
||||
void *callback_arg,
|
||||
|
||||
tSerialPortFrameIO *ioCanFrame,
|
||||
tCanTP_data *dataBuf,
|
||||
uint16_t dataBufMaxSize,
|
||||
tLoggerToSerialPort *slog,
|
||||
|
||||
uint8_t filterIdCount,
|
||||
uint32_t *filterReqId,
|
||||
uint32_t *filterRespId,
|
||||
uint8_t *filterDirReq
|
||||
|
||||
) {
|
||||
env->ioCanFrame = ioCanFrame;
|
||||
|
||||
env->numBuf = numBuf;
|
||||
|
||||
env->txAccessQueue = txAccessQueue;
|
||||
|
||||
env->dataBuf = dataBuf;
|
||||
env->dataBufMaxSize = dataBufMaxSize;
|
||||
env->dataBufLen = 0;
|
||||
env->dataBufWorkLen = 0;
|
||||
env->isFlowControl = false;
|
||||
|
||||
env->filterIdCount = filterIdCount;
|
||||
env->filterReqId = filterReqId;
|
||||
env->filterRespId = filterRespId;
|
||||
env->filterDirReq = filterDirReq;
|
||||
|
||||
env->dataReceivedConsecutiveFrameLen = 0;
|
||||
|
||||
|
||||
env->ReceivedCan_func = receivedCan_func;
|
||||
env->callback_argCan = callback_argCan;
|
||||
|
||||
|
||||
env->receivedTP_func = receivedTP_func;
|
||||
env->callback_argTp = callback_arg;
|
||||
|
||||
env->timeoutFF = 0;
|
||||
|
||||
env->slog = slog;
|
||||
|
||||
InitThreadBlock(env->T_can_Listener0, "CanListener0", osPriorityNormal);
|
||||
InitThreadBlock(env->T_can_Listener1, "CanListener1", osPriorityNormal);
|
||||
}
|
||||
|
||||
void CanSerialPortFrameTp_Start(tCanSerialPortFrameTp *env, uint8_t numBuf) {
|
||||
if (numBuf == 0)
|
||||
ThreadBlock_Start(env->T_can_Listener0, env, CanTpProcessing_ListenerTask0);
|
||||
|
||||
if (numBuf == 1)
|
||||
ThreadBlock_Start(env->T_can_Listener1, env, CanTpProcessing_ListenerTask1);
|
||||
}
|
||||
|
||||
char *sendLogCanHex(tCanSerialPortFrameTp *env, uint8_t *data, size_t size) {
|
||||
memset(env->hexString, 0, sizeof(env->hexString));
|
||||
size_t len = 0;
|
||||
vAsciiStringAddBytesAsHex(env->hexString, &len, data, size);
|
||||
|
||||
LoggerStrInfo(LOGGER, LOG_SIGN, env->hexString, strlen(env->hexString));
|
||||
|
||||
return env->hexString;
|
||||
}
|
||||
|
||||
uint16_t sendFlowFrame(tCanSerialPortFrameTp *env, uint32_t id, uint32_t timeout) {
|
||||
uint8_t dataTpFrame[8];
|
||||
memset(dataTpFrame, TP_FRAME_PADDING, sizeof(dataTpFrame));
|
||||
|
||||
eTpFrameFC *frame = (eTpFrameFC *) dataTpFrame;
|
||||
frame->typeFrame = TP_TYPE_FRAME_FC;
|
||||
frame->status = 0;
|
||||
frame->blockSize = 0;
|
||||
frame->timeST = 0;
|
||||
|
||||
uint16_t sent = 0;
|
||||
|
||||
if (osMutexAcquire(env->txAccessQueue, 1000) == osOK) {
|
||||
|
||||
CanSerialPortFrameSetId(env->ioCanFrame->env, id);
|
||||
|
||||
sent = env->ioCanFrame->transmit(env->ioCanFrame->env, (uint8_t *) frame, 8, timeout);
|
||||
|
||||
osMutexRelease(env->txAccessQueue);
|
||||
} else {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа sendFlowFrame")
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
eTpResult vCanSerialPortFrameTpReceive(tCanSerialPortFrameTp *env, uint32_t timeout) {
|
||||
can_rx_message_type canFrame;
|
||||
|
||||
if ((env->timeoutFF > 0) && (env->timeoutFF < SystemGetMs())) {
|
||||
env->timeoutFF = 0;
|
||||
env->dataReceivedConsecutiveFrameLen = 0;
|
||||
env->dataBufLen = 0;
|
||||
env->dataBufWorkLen = 0;
|
||||
|
||||
return TP_ERROR_FF_ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
uint16_t recv = 0;
|
||||
|
||||
if (env->numBuf == 0) {
|
||||
recv = env->ioCanFrame->receive0(env->ioCanFrame->env, (uint8_t *) &canFrame, 1, timeout);
|
||||
}
|
||||
|
||||
if (env->numBuf == 1) {
|
||||
recv = env->ioCanFrame->receive1(env->ioCanFrame->env, (uint8_t *) &canFrame, 1, timeout);
|
||||
}
|
||||
|
||||
if (recv == 0)
|
||||
return TP_STANDBY;
|
||||
|
||||
bool isTesterPresent = env->ReceivedCan_func(env->callback_argCan, &canFrame);
|
||||
|
||||
if (isTesterPresent) {
|
||||
// return TP_STANDBY;
|
||||
}
|
||||
|
||||
bool isFilterFind = false;
|
||||
uint32_t reqId = 0;
|
||||
for (uint8_t i = 0; i < env->filterIdCount; ++i) {
|
||||
if (canFrame.standard_id == env->filterReqId[i]) {
|
||||
|
||||
reqId = env->filterRespId[i];
|
||||
|
||||
isFilterFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFilterFind) {
|
||||
return TP_ERROR_WRONG_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
if ((recv > 0) && (canFrame.dlc == 8)) {
|
||||
|
||||
// Flow control Frame – FC – фрейм управления потоком
|
||||
if ((canFrame.data[0] >> 4) == TP_TYPE_FRAME_FC) {
|
||||
eTpFrameFC *frame = (eTpFrameFC *) canFrame.data;
|
||||
|
||||
if (frame->status == 0)
|
||||
return TP_RECEIVED_FC_DATA;
|
||||
|
||||
return TP_ERROR_FC_ERROR;
|
||||
}
|
||||
|
||||
// Single Frame SF – Однократный фрейм
|
||||
if ((canFrame.data[0] >> 4) == TP_TYPE_FRAME_SF) {
|
||||
eTpFrameSF *frame = (eTpFrameSF *) canFrame.data;
|
||||
|
||||
if (frame->dl < env->dataBufMaxSize) {
|
||||
//memcpy(env->dataBuf, &canFrame.data[1], frame->dl);
|
||||
env->dataBufLen = frame->dl;
|
||||
|
||||
memcpy(env->dataBuf->data, &canFrame.data[1], frame->dl);
|
||||
env->dataBuf->len = env->dataBufLen;
|
||||
env->dataBuf->adrCan = canFrame.standard_id;
|
||||
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_RECEIVED_DATA;
|
||||
} else {
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_ERROR_FS_ERROR_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
// First Frame FF – Первый фрейм из серии фреймов
|
||||
if ((canFrame.data[0] >> 4) == TP_TYPE_FRAME_FF) {
|
||||
if (env->dataReceivedConsecutiveFrameLen) {
|
||||
return TP_ERROR_FF_ERROR;
|
||||
}
|
||||
|
||||
eTpFrameFF *frame = (eTpFrameFF *) canFrame.data;
|
||||
|
||||
if (env->dataBufWorkLen + (frame->dlL | (frame->dlM << 8)) > env->dataBufMaxSize) {
|
||||
return TP_ERROR_FF_ERROR_SIZE;
|
||||
}
|
||||
|
||||
uint16_t dll = frame->dlL | (frame->dlM << 8);
|
||||
if (dll > 100) {
|
||||
asm("nop");
|
||||
}
|
||||
|
||||
env->timeoutFF = SystemGetMs() + WAIT_FF_FRAME_TIMEOUT;
|
||||
|
||||
env->sn = 1;
|
||||
env->dataBufWorkLen = 0;
|
||||
env->dataReceivedConsecutiveFrameLen = (frame->dlL | (frame->dlM << 8));
|
||||
|
||||
for (uint8_t j = 2; j < 8; ++j) {
|
||||
//env->dataBuf[env->dataBufWorkLen] = canFrame.data[j];
|
||||
env->dataBuf->data[env->dataBufWorkLen] = canFrame.data[j];
|
||||
|
||||
++env->dataBufWorkLen;
|
||||
if (env->dataBufWorkLen > env->dataBufMaxSize) {
|
||||
env->timeoutFF = 0;
|
||||
env->dataReceivedConsecutiveFrameLen = 0;
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_ERROR_CF_ERROR_SIZE;
|
||||
}
|
||||
|
||||
--env->dataReceivedConsecutiveFrameLen;
|
||||
}
|
||||
|
||||
sendFlowFrame(env, reqId, WAIT_FRAME_WRITE);
|
||||
}
|
||||
|
||||
// Consecutive Frame CF – последующий фрейм.
|
||||
if ((canFrame.data[0] >> 4) == TP_TYPE_FRAME_CF) {
|
||||
|
||||
if (env->dataReceivedConsecutiveFrameLen == 0) {
|
||||
return TP_ERROR_CF_ERROR;
|
||||
}
|
||||
|
||||
eTpFrameCF *frame = (eTpFrameCF *) canFrame.data;
|
||||
|
||||
if (frame->sn != env->sn) {
|
||||
env->timeoutFF = 0;
|
||||
env->dataReceivedConsecutiveFrameLen = 0;
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_ERROR_CF_ERROR_SN;
|
||||
}
|
||||
|
||||
++env->sn;
|
||||
if (env->sn > 15)
|
||||
env->sn = 0;
|
||||
|
||||
for (uint8_t j = 1; j < 8; ++j) {
|
||||
//env->dataBuf[env->dataBufWorkLen] = canFrame.data[j];
|
||||
env->dataBuf->data[env->dataBufWorkLen] = canFrame.data[j];
|
||||
|
||||
++env->dataBufWorkLen;
|
||||
if (env->dataBufWorkLen > env->dataBufMaxSize) {
|
||||
env->timeoutFF = 0;
|
||||
env->dataReceivedConsecutiveFrameLen = 0;
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_ERROR_CF_ERROR_SIZE;
|
||||
}
|
||||
|
||||
--env->dataReceivedConsecutiveFrameLen;
|
||||
if (env->dataReceivedConsecutiveFrameLen == 0) {
|
||||
env->timeoutFF = 0;
|
||||
env->dataBufLen = env->dataBufWorkLen;
|
||||
|
||||
env->dataBuf->len = env->dataBufLen;
|
||||
env->dataBuf->adrCan = canFrame.standard_id;
|
||||
|
||||
env->dataBufWorkLen = 0;
|
||||
return TP_RECEIVED_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return TP_ERROR_FC_TIMEOUT;
|
||||
}
|
||||
|
||||
_Noreturn void CanTpProcessing_ListenerTask0(tCanSerialPortFrameTp *env) {
|
||||
while (1) {
|
||||
eTpResult result = vCanSerialPortFrameTpReceive(env, 1000);
|
||||
|
||||
if (result == TP_RECEIVED_FC_DATA) {
|
||||
if (env->isFlowControl) {
|
||||
env->isFlowControl = false;
|
||||
// LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Принят Flow control Frame");
|
||||
} else {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Принят не ожидаемый Flow control Frame");
|
||||
}
|
||||
}
|
||||
|
||||
if (result == TP_RECEIVED_DATA) {
|
||||
// LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Приняты данные: ");
|
||||
// sendLogCanHex(env, env->dataBuf->data, env->dataBuf->len);
|
||||
|
||||
env->receivedTP_func(env->callback_argTp, env->dataBuf);
|
||||
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FS_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Переполнение приемного буфера (1)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FC_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Выставлен статус ошибки в Flow control Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN,
|
||||
"0: Ошибка. Принят First Frame FF, но еще не завершен прием Consecutive Frame");
|
||||
}
|
||||
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Переполнение приемного буфера (2)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Принят не ожидаемый Consecutive Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Переполнение приемного буфера (3)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR_SN) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Ошибка. Не совпадение счетчика SN в Consecutive Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR_TIMEOUT) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "0: Истекло время ожидания приема Consecutive Frame");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_Noreturn void CanTpProcessing_ListenerTask1(tCanSerialPortFrameTp *env) {
|
||||
while (1) {
|
||||
eTpResult result = vCanSerialPortFrameTpReceive(env, 1000);
|
||||
|
||||
if (result == TP_RECEIVED_FC_DATA) {
|
||||
if (env->isFlowControl) {
|
||||
env->isFlowControl = false;
|
||||
// LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Принят Flow control Frame");
|
||||
} else {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Принят не ожидаемый Flow control Frame");
|
||||
}
|
||||
}
|
||||
|
||||
if (result == TP_RECEIVED_DATA) {
|
||||
// LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Приняты данные: ");
|
||||
// sendLogCanHex(env, env->dataBuf->data, env->dataBuf->len);
|
||||
|
||||
env->receivedTP_func(env->callback_argTp, env->dataBuf);
|
||||
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FS_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Переполнение приемного буфера (1)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FC_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Выставлен статус ошибки в Flow control Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN,
|
||||
"1: Ошибка. Принят First Frame FF, но еще не завершен прием Consecutive Frame");
|
||||
}
|
||||
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Переполнение приемного буфера (2)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Принят не ожидаемый Consecutive Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR_SIZE) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Переполнение приемного буфера (3)");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_CF_ERROR_SN) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Ошибка. Не совпадение счетчика SN в Consecutive Frame");
|
||||
}
|
||||
|
||||
if (result == TP_ERROR_FF_ERROR_TIMEOUT) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "1: Истекло время ожидания приема Consecutive Frame");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t sendSingleFrame(tCanSerialPortFrameTp *env, uint8_t *data, uint16_t size, uint32_t id, uint32_t timeout) {
|
||||
uint8_t dataTpFrame[8];
|
||||
memset(dataTpFrame, TP_FRAME_PADDING, sizeof(dataTpFrame));
|
||||
|
||||
eTpFrameSF *frame = (eTpFrameSF *) dataTpFrame;
|
||||
frame->typeFrame = TP_TYPE_FRAME_SF;
|
||||
frame->dl = size;
|
||||
|
||||
memcpy(&frame->data[0], data, size);
|
||||
|
||||
uint16_t sent = 0;
|
||||
|
||||
if (osMutexAcquire(env->txAccessQueue, 1000) == osOK) {
|
||||
|
||||
CanSerialPortFrameSetId(env->ioCanFrame->env, id);
|
||||
|
||||
sent = env->ioCanFrame->transmit(env->ioCanFrame->env, (uint8_t *) frame, 8, timeout);
|
||||
|
||||
osMutexRelease(env->txAccessQueue);
|
||||
} else {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа sendSingleFrame")
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
uint16_t sendConsecutiveFrame(tCanSerialPortFrameTp *env, uint8_t *data, uint16_t size, uint32_t id, uint8_t sn,
|
||||
uint32_t timeout) {
|
||||
uint8_t dataTpFrame[8];
|
||||
memset(dataTpFrame, TP_FRAME_PADDING, sizeof(dataTpFrame));
|
||||
|
||||
eTpFrameCF *frame = (eTpFrameCF *) dataTpFrame;
|
||||
frame->typeFrame = TP_TYPE_FRAME_CF;
|
||||
frame->sn = sn;
|
||||
|
||||
memcpy(&frame->data[0], data, size);
|
||||
|
||||
uint16_t sent = 0;
|
||||
|
||||
if (osMutexAcquire(env->txAccessQueue, 1000) == osOK) {
|
||||
|
||||
CanSerialPortFrameSetId(env->ioCanFrame->env, id);
|
||||
|
||||
sent = env->ioCanFrame->transmit(env->ioCanFrame->env, (uint8_t *) frame, 8, timeout);
|
||||
|
||||
osMutexRelease(env->txAccessQueue);
|
||||
} else {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа sendConsecutiveFrame")
|
||||
}
|
||||
|
||||
return sent;
|
||||
|
||||
}
|
||||
|
||||
bool waitFlowControl(tCanSerialPortFrameTp *env) {
|
||||
env->isFlowControl = true;
|
||||
|
||||
uint32_t timeEnd = SystemGetMs() + WAIT_FC_FRAME_TIMEOUT;
|
||||
|
||||
while (timeEnd > SystemGetMs()) {
|
||||
if (!env->isFlowControl) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (env->isFlowControl) {
|
||||
LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Таймаут ожидания Flow control Frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sendFirstFrame(tCanSerialPortFrameTp *env, uint8_t *data, uint16_t size, uint32_t id, uint32_t timeout) {
|
||||
uint8_t dataTpFrame[8];
|
||||
uint16_t pDataLen = 0;
|
||||
|
||||
memset(dataTpFrame, TP_FRAME_PADDING, sizeof(dataTpFrame));
|
||||
|
||||
eTpFrameFF *frame = (eTpFrameFF *) dataTpFrame;
|
||||
frame->typeFrame = TP_TYPE_FRAME_FF;
|
||||
frame->dlL = size;
|
||||
frame->dlM = (size >> 8);
|
||||
|
||||
memcpy(&frame->data[0], &data[pDataLen], 6);
|
||||
pDataLen += 6;
|
||||
|
||||
uint16_t sent = 0;
|
||||
|
||||
if (osMutexAcquire(env->txAccessQueue, 1000) == osOK) {
|
||||
|
||||
CanSerialPortFrameSetId(env->ioCanFrame->env, id);
|
||||
|
||||
sent = env->ioCanFrame->transmit(env->ioCanFrame->env, (uint8_t *) frame, 8, timeout);
|
||||
|
||||
osMutexRelease(env->txAccessQueue);
|
||||
} else {
|
||||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа sendFirstFrame")
|
||||
}
|
||||
|
||||
bool result = waitFlowControl(env);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
uint16_t countPacketFull = (size - 6) / 7;
|
||||
uint16_t sizePacketTail = (size - 6) % 7;
|
||||
|
||||
uint8_t sn = 1;
|
||||
|
||||
for (uint16_t i = 0; i < countPacketFull; ++i) {
|
||||
|
||||
sendConsecutiveFrame(env, &data[pDataLen], 7, id, sn, timeout);
|
||||
pDataLen += 7;
|
||||
|
||||
++sn;
|
||||
if (sn == 15)
|
||||
sn = 1;
|
||||
}
|
||||
|
||||
if (sizePacketTail) {
|
||||
sendConsecutiveFrame(env, &data[pDataLen], sizePacketTail, id, sn, timeout);
|
||||
pDataLen += sizePacketTail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
CanSerialPortFrameTpTransmit(tCanSerialPortFrameTp *env, uint8_t *data, uint16_t size, uint32_t id, uint32_t timeout) {
|
||||
bool result;
|
||||
|
||||
// Single Frame SF
|
||||
if (size <= 7) {
|
||||
result = sendSingleFrame(env, data, size, id, timeout);
|
||||
} else {
|
||||
result = sendFirstFrame(env, data, size, id, timeout);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"dep": [
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "Smart_Components_Aurus",
|
||||
"repo": "SerialPort"
|
||||
}
|
||||
],
|
||||
"cmake": {
|
||||
"inc_dirs": [
|
||||
"Inc"
|
||||
],
|
||||
"srcs": [
|
||||
"Src/**.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue