Начало

This commit is contained in:
cfif 2026-03-23 17:37:39 +03:00
parent 09013e67b2
commit 432176a0db
2 changed files with 403 additions and 20 deletions

View File

@ -7,6 +7,8 @@
#include "SerialPort.h"
#include "AtCmdCommonProtected.h"
#include "AsciiStringParsingUtils.h"
#include "memory.h"
void sendOk(tAtCmd *AtCmd) {
AtCmdPrepare(AtCmd);
@ -16,6 +18,14 @@ void sendOk(tAtCmd *AtCmd) {
AtCmdRxClear(AtCmd);
}
void sendError(tAtCmd *AtCmd) {
AtCmdPrepare(AtCmd);
AtCmdTxClear(AtCmd);
AtCmdTxAddStatic(AtCmd, "ERROR");
AtCmdTxSendLn(AtCmd);
AtCmdRxClear(AtCmd);
}
void sendVers(tAtCmd *AtCmd) {
AtCmdPrepare(AtCmd);
AtCmdTxClear(AtCmd);
@ -24,6 +34,205 @@ void sendVers(tAtCmd *AtCmd) {
AtCmdRxClear(AtCmd);
}
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
void TaskSerialToCanCyclic0_Init(tTaskSerialToCanCyclic *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue
) {
env->access = osMutexNew(NULL);
env->ioCAN = ioCAN;
env->txDataQueue = txDataQueue;
InitThreadAtrStatic(&env->thread.attr, "SerialCyclic", env->thread.controlBlock, env->thread.stack,
osPriorityNormal);
}
static _Noreturn void Serial_ToCanCyclic0_Thread(tTaskSerialToCanCyclic *env) {
for (;;) {
if (osMutexAcquire(env->access, 1000) == osOK) {
can_rx_message_type data;
if (osMessageQueueGet(env->txDataQueue, &data, NULL, 1000) == osOK) {
if (data.id_type == CAN_ID_STANDARD) {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.data, data.dlc, data.standard_id, 0, 0,
1000);
} else {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.data, data.dlc, data.extended_id, 1, 0,
1000);
}
}
osMutexRelease(env->access);
}
}
}
void TaskSerialToCanCyclic0_StartThread(tTaskSerialToCanCyclic *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (Serial_ToCanCyclic0_Thread), (void *) (env), &env->thread.attr);
}
}
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка без подтверждения-------------------------------------------------------
void TaskSerialToCanCyclic1_Init(tTaskSerialToCanCyclic *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue
) {
env->access = osMutexNew(NULL);
env->ioCAN = ioCAN;
env->txDataQueue = txDataQueue;
InitThreadAtrStatic(&env->thread.attr, "SerialCyclic", env->thread.controlBlock, env->thread.stack,
osPriorityNormal);
}
static _Noreturn void Serial_ToCanCyclic1_Thread(tTaskSerialToCanCyclic *env) {
for (;;) {
if (osMutexAcquire(env->access, 1000) == osOK) {
can_rx_message_type data;
if (osMessageQueueGet(env->txDataQueue, &data, NULL, 1000) == osOK) {
if (data.id_type == CAN_ID_STANDARD) {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.data, data.dlc, data.standard_id, 0, 1,
1000);
} else {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.data, data.dlc, data.extended_id, 1, 1,
1000);
}
}
osMutexRelease(env->access);
}
}
}
void TaskSerialToCanCyclic1_StartThread(tTaskSerialToCanCyclic *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (Serial_ToCanCyclic1_Thread), (void *) (env), &env->thread.attr);
}
}
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//конец ------------------------------Отправка без подтверждения-------------------------------------------------------
//начало ------------------------------Отправка с подтверждением-------------------------------------------------------
//начало ------------------------------Отправка с подтверждением-------------------------------------------------------
//начало ------------------------------Отправка с подтверждением-------------------------------------------------------
void TaskSerialToCanSpontany_Init(tTaskSerialToCanSpontany *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue,
tAtCmd *At_UART,
tAtCmd *At_UART_USB
) {
env->access = osMutexNew(NULL);
env->ioCAN = ioCAN;
env->At_UART = At_UART;
env->At_UART_USB = At_UART_USB;
env->txDataQueue = txDataQueue;
InitThreadAtrStatic(&env->thread.attr, "SerialSpontany", env->thread.controlBlock, env->thread.stack,
osPriorityNormal);
}
static _Noreturn void Serial_ToCanSpontany_Thread(tTaskSerialToCanSpontany *env) {
for (;;) {
if (osMutexAcquire(env->access, 1000) == osOK) {
can_rx_message_Spontany data;
if (osMessageQueueGet(env->txDataQueue, &data, NULL, 1000) == osOK) {
if (data.can_rx_message.id_type == CAN_ID_STANDARD) {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.can_rx_message.data,
data.can_rx_message.dlc, data.can_rx_message.standard_id, 0, 2,
1000);
if (sent) {
if (data.from_uart == SPONTANY_FROM_UART) {
sendOk(env->At_UART);
} else {
sendOk(env->At_UART_USB);
}
} else {
if (data.from_uart == SPONTANY_FROM_UART) {
sendError(env->At_UART);
} else {
sendError(env->At_UART_USB);
}
}
} else {
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data.can_rx_message.data,
data.can_rx_message.dlc, data.can_rx_message.extended_id, 1, 2,
1000);
if (sent) {
if (data.from_uart == SPONTANY_FROM_UART) {
sendOk(env->At_UART);
} else {
sendOk(env->At_UART_USB);
}
} else {
if (data.from_uart == SPONTANY_FROM_UART) {
sendError(env->At_UART);
} else {
sendError(env->At_UART_USB);
}
}
}
}
osMutexRelease(env->access);
}
}
}
void TaskSerialToCanSpontany_StartThread(tTaskSerialToCanSpontany *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (Serial_ToCanSpontany_Thread), (void *) (env), &env->thread.attr);
}
}
//конец ------------------------------Отправка с подтверждением-------------------------------------------------------
//конец ------------------------------Отправка с подтверждением-------------------------------------------------------
//конец ------------------------------Отправка с подтверждением-------------------------------------------------------
//начало ------------------------------Парсер команд--------------------------------------------------------------------
//начало ------------------------------Парсер команд--------------------------------------------------------------------
//начало ------------------------------Парсер команд--------------------------------------------------------------------
void SerialCommand_Scheduler(tTaskSerial *env) {
while (AtCmdReceiveNextLine(&env->At, SystemWaitForever) == AT_OK) {
@ -34,7 +243,13 @@ void SerialCommand_Scheduler(tTaskSerial *env) {
//uint32_t adr = iAsciiStringParseUnsignedLongDecimalNumber(&env->At.rxBuffer.data[1],
// &env->At.rxBuffer.data[7]);
uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[3], 4);
uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[0], 1);
uint8_t opt = data[0];
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[1], 1);
uint8_t remote = data[0];
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[3], 4);
uint32_t adr = (data[0] << 8) | data[1];
@ -46,9 +261,30 @@ void SerialCommand_Scheduler(tTaskSerial *env) {
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[7], len);
uint16_t sent = env->ioCAN->transmit(env->ioCAN->env, data, size, adr, 0, env->numberMailBox, 1000);
sendOk(&env->At);
can_rx_message_Spontany dataCan;
dataCan.from_uart = env->from_uart;
dataCan.can_rx_message.dlc = size;
dataCan.can_rx_message.id_type = CAN_ID_STANDARD;
dataCan.can_rx_message.standard_id = adr;
dataCan.can_rx_message.frame_type = remote;
dataCan.can_rx_message.filter_index = 0;
dataCan.can_rx_message.extended_id = 0;
memcpy(dataCan.can_rx_message.data, data, size);
if (opt) {
osMessageQueuePut(env->txDataQueue_Spontany, &dataCan, 0x0, 0U);
} else {
uint32_t count0 = osMessageQueueGetCount(env->txDataQueue_Cyclic0);
uint32_t count1 = osMessageQueueGetCount(env->txDataQueue_Cyclic1);
if (count0 <= count1) {
osMessageQueuePut(env->txDataQueue_Cyclic0, &dataCan.can_rx_message, 0x0, 0U);
} else {
osMessageQueuePut(env->txDataQueue_Cyclic1, &dataCan.can_rx_message, 0x0, 0U);
}
}
}
if (AtCmdRxBeginWithStatic(&env->At, "t")) {
@ -57,8 +293,14 @@ void SerialCommand_Scheduler(tTaskSerial *env) {
//uint32_t adr = iAsciiStringParseUnsignedLongDecimalNumber(&env->At.rxBuffer.data[1],
// &env->At.rxBuffer.data[9]);
uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[3], 8);
uint32_t adr = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3] << 0);
uint8_t size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[0], 1);
uint8_t opt = data[0];
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[1], 1);
uint8_t remote = data[0];
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[3], 8);
uint32_t adr = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3] << 0);
uint8_t len = &env->At.rxBuffer.data[env->At.rxBuffer.len] - &env->At.rxBuffer.data[9] - 2;
@ -68,9 +310,30 @@ void SerialCommand_Scheduler(tTaskSerial *env) {
size = iAsciiStringParseHexBytes(data, &env->At.rxBuffer.data[9], len);
env->ioCAN->transmit(env->ioCAN->env, data, size, adr, 1, env->numberMailBox, 1000);
can_rx_message_Spontany dataCan;
dataCan.from_uart = env->from_uart;
dataCan.can_rx_message.dlc = size;
dataCan.can_rx_message.id_type = CAN_ID_EXTENDED;
dataCan.can_rx_message.extended_id = adr;
dataCan.can_rx_message.frame_type = remote;
dataCan.can_rx_message.filter_index = 0;
dataCan.can_rx_message.standard_id = 0;
memcpy(dataCan.can_rx_message.data, data, size);
if (opt) {
osMessageQueuePut(env->txDataQueue_Spontany, &dataCan, 0x0, 0U);
} else {
uint32_t count0 = osMessageQueueGetCount(env->txDataQueue_Cyclic0);
uint32_t count1 = osMessageQueueGetCount(env->txDataQueue_Cyclic1);
if (count0 <= count1) {
osMessageQueuePut(env->txDataQueue_Cyclic0, &dataCan.can_rx_message, 0x0, 0U);
} else {
osMessageQueuePut(env->txDataQueue_Cyclic1, &dataCan.can_rx_message, 0x0, 0U);
}
}
sendOk(&env->At);
}
if (AtCmdRxBeginWithStatic(&env->At, "V")) {
@ -81,19 +344,37 @@ void SerialCommand_Scheduler(tTaskSerial *env) {
}
//конец ------------------------------Парсер команд--------------------------------------------------------------------
//конец ------------------------------Парсер команд--------------------------------------------------------------------
//конец ------------------------------Парсер команд--------------------------------------------------------------------
//начало ------------------------------Обработчик UART команд-----------------------------------------------------------
//начало ------------------------------Обработчик UART команд-----------------------------------------------------------
//начало ------------------------------Обработчик UART команд-----------------------------------------------------------
void TaskSerialUART_Init(tTaskSerial *env,
uint8_t numberMailBox,
spontany_from_uart from_uart,
tSerialPortIO *ioUART,
tSerialPortFrameIO *ioCAN
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue_Spontany,
osMessageQueueId_t txDataQueue_Cyclic0,
osMessageQueueId_t txDataQueue_Cyclic1
) {
env->access = osMutexNew(NULL);
env->numberMailBox = numberMailBox;
env->from_uart = from_uart;
env->ioUART = ioUART;
env->ioCAN = ioCAN;
env->txDataQueue_Spontany = txDataQueue_Spontany;
env->txDataQueue_Cyclic0 = txDataQueue_Cyclic0;
env->txDataQueue_Cyclic1 = txDataQueue_Cyclic1;
SerialPortClearRxBuffer(env->ioUART);
AtCmdInit(
@ -127,19 +408,34 @@ void TaskSerialUART_StartThread(tTaskSerial *env) {
}
}
//конец ------------------------------Обработчик UART команд-----------------------------------------------------------
//конец ------------------------------Обработчик UART команд-----------------------------------------------------------
//конец ------------------------------Обработчик UART команд-----------------------------------------------------------
//начало ------------------------------Обработчик UART USB команд-------------------------------------------------------
//начало ------------------------------Обработчик UART USB команд-------------------------------------------------------
//начало ------------------------------Обработчик UART USB команд-------------------------------------------------------
void TaskSerialUSB_Init(tTaskSerial *env,
uint8_t numberMailBox,
spontany_from_uart from_uart,
tSerialPortIO *ioUART,
tSerialPortFrameIO *ioCAN
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue_Spontany,
osMessageQueueId_t txDataQueue_Cyclic0,
osMessageQueueId_t txDataQueue_Cyclic1
) {
env->access = osMutexNew(NULL);
env->numberMailBox = numberMailBox;
env->from_uart = from_uart;
env->ioUART = ioUART;
env->ioCAN = ioCAN;
env->txDataQueue_Spontany = txDataQueue_Spontany;
env->txDataQueue_Cyclic0 = txDataQueue_Cyclic0;
env->txDataQueue_Cyclic1 = txDataQueue_Cyclic1;
SerialPortClearRxBuffer(env->ioUART);
AtCmdInit(
@ -172,3 +468,7 @@ void TaskSerialUSB_StartThread(tTaskSerial *env) {
env->thread.id = osThreadNew((osThreadFunc_t) (Serial_USB_Thread), (void *) (env), &env->thread.attr);
}
}
//конец ------------------------------Обработчик UART USB команд-------------------------------------------------------
//конец ------------------------------Обработчик UART USB команд-------------------------------------------------------
//конец ------------------------------Обработчик UART USB команд-------------------------------------------------------

View File

@ -10,6 +10,11 @@
#include "AtCmdCommon.h"
#include "CanSerialPortFrame.h"
typedef enum {
SPONTANY_FROM_UART,
SPONTANY_FROM_UART_USB
} spontany_from_uart;
typedef struct {
tAtCmd At;
@ -18,9 +23,13 @@ typedef struct {
tSerialPortIO *ioUART;
tSerialPortFrameIO *ioCAN;
uint8_t numberMailBox;
spontany_from_uart from_uart;
osMutexId_t access;
osMessageQueueId_t txDataQueue_Spontany;
osMessageQueueId_t txDataQueue_Cyclic0;
osMessageQueueId_t txDataQueue_Cyclic1;
struct {
osThreadId_t id;
uint32_t stack[1024];
@ -31,19 +40,93 @@ typedef struct {
} tTaskSerial;
typedef struct {
tSerialPortFrameIO *ioCAN;
osMutexId_t access;
osMessageQueueId_t txDataQueue;
struct {
osThreadId_t id;
uint32_t stack[1024];
StaticTask_t controlBlock;
osThreadAttr_t attr;
} thread;
} tTaskSerialToCanCyclic;
typedef struct {
can_rx_message_type can_rx_message;
spontany_from_uart from_uart;
} can_rx_message_Spontany;
typedef struct {
tSerialPortFrameIO *ioCAN;
osMutexId_t access;
osMessageQueueId_t txDataQueue;
tAtCmd *At_UART;
tAtCmd *At_UART_USB;
struct {
osThreadId_t id;
uint32_t stack[1024];
StaticTask_t controlBlock;
osThreadAttr_t attr;
} thread;
} tTaskSerialToCanSpontany;
void TaskSerialUART_Init(tTaskSerial *env,
uint8_t numberMailBox,
spontany_from_uart from_uart,
tSerialPortIO *ioUART,
tSerialPortFrameIO *ioCAN
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue_Spontany,
osMessageQueueId_t txDataQueue_Cyclic0,
osMessageQueueId_t txDataQueue_Cyclic1
);
void TaskSerialUART_StartThread(tTaskSerial *env);
void TaskSerialUSB_Init(tTaskSerial *env,
uint8_t numberMailBox,
tSerialPortIO *ioUART,
tSerialPortFrameIO *ioCAN
spontany_from_uart from_uart,
tSerialPortIO *ioUART,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue_Spontany,
osMessageQueueId_t txDataQueue_Cyclic0,
osMessageQueueId_t txDataQueue_Cyclic1
);
void TaskSerialUSB_StartThread(tTaskSerial *env);
void TaskSerialToCanCyclic0_Init(tTaskSerialToCanCyclic *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue
);
void TaskSerialToCanCyclic0_StartThread(tTaskSerialToCanCyclic *env);
void TaskSerialToCanCyclic1_Init(tTaskSerialToCanCyclic *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue);
void TaskSerialToCanCyclic1_StartThread(tTaskSerialToCanCyclic *env);
void TaskSerialToCanSpontany_Init(tTaskSerialToCanSpontany *env,
tSerialPortFrameIO *ioCAN,
osMessageQueueId_t txDataQueue,
tAtCmd *At_UART,
tAtCmd *At_UART_USB
);
void TaskSerialToCanSpontany_StartThread(tTaskSerialToCanSpontany *env);
#endif //HVAC_DEV_ARBITERCOMMAND_H