From ab3a8bc8204dda6c519e47ad1d8462948357d09e Mon Sep 17 00:00:00 2001 From: "ru.sadekov" Date: Wed, 29 Oct 2025 13:28:36 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D0=BB=D0=B0=D0=B4=D0=BA=D0=B0,=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BA=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=B1=D1=83=D1=84=D0=B5=D1=80=D0=B0=20=D0=BF=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D1=81=D0=B8=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hdlc/hdlc_type.h | 2 +- src/main.c | 2 +- src/worker/worker.c | 179 ++++++++++++++++++++----------------- src/worker/worker.h | 6 +- src/worker/worker_master.c | 6 +- src/worker/worker_slave.c | 5 +- src/worker/worker_tools.c | 20 ++++- 7 files changed, 127 insertions(+), 93 deletions(-) diff --git a/src/hdlc/hdlc_type.h b/src/hdlc/hdlc_type.h index 99ab948..a84866c 100644 --- a/src/hdlc/hdlc_type.h +++ b/src/hdlc/hdlc_type.h @@ -12,7 +12,7 @@ // ---------------------------------------------------------------------------------- #define HDLC_INFO_LENGTH 16 -#define HDLC_PACKET_LENGTH 2+2+HDLC_INFO_LENGTH+2 +#define HDLC_PACKET_LENGTH 1+2+2+HDLC_INFO_LENGTH+2+1 #define HDLC_PACKET_FLAG 0x7e #define HDLC_PACKET_ESCAPE 0xab diff --git a/src/main.c b/src/main.c index 1e36554..f163673 100644 --- a/src/main.c +++ b/src/main.c @@ -45,7 +45,7 @@ int main(void) { break; case OS_wait: - TOOL_msleep(1000); + TOOL_msleep(50); printf("\n\n"); break; diff --git a/src/worker/worker.c b/src/worker/worker.c index 0ce5157..051948b 100644 --- a/src/worker/worker.c +++ b/src/worker/worker.c @@ -5,19 +5,19 @@ #include "hdlc.h" #include "fifo.h" +extern void WORK_formattedPrintArray(char* str, uint8_t* array, size_t size); workerHost_s* WORK_workerInit (workerHost_s* worker, hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer) { if (!worker->isInitialized) { printf("WORKX: Starting master worker initialization\n"); worker->packet = packet; - worker->fifo = fifo; + worker->fifoWrite = fifo; + worker->fifoRead = NULL; worker->isInitialized = true; worker->byteBuffer = buffer; - FIFO_init(worker->fifo); - - if (DO_UNIT_TESTS){WORK_testFifo(worker->fifo);} + FIFO_init(worker->fifoWrite); printf("WORKX: Master initialization done\n"); WORK_printBlocks(worker, 3); @@ -46,9 +46,14 @@ int WORK_preparePackage(workerHost_s *worker) { printf("WORKX: .. Preparing package\n"); // Перемещение структуры в массив на передачу - size_t structSize = sizeof(hdlcPacket_s); + // Вычитаем байты начала и конца сообщения + size_t structSize = HDLC_PACKET_LENGTH-2; + // size_t structSize = sizeof(hdlcPacket_s); + uint8_t tmpPtr = 0; - uint8_t *packPtr = (uint8_t*)&worker->packet; + uint8_t *packPtr = (uint8_t*)worker->packet; + + worker->byteBuffer[tmpPtr++] = HDLC_PACKET_FLAG; for (size_t s = 0; s < structSize; s++, tmpPtr++) { // Нашли флаг в теле сообщения if (packPtr[s] == HDLC_PACKET_FLAG) { @@ -58,6 +63,11 @@ int WORK_preparePackage(workerHost_s *worker) { worker->byteBuffer[tmpPtr] = packPtr[s]; } + worker->byteBuffer[tmpPtr] = HDLC_PACKET_FLAG; + worker->byteBufferLength = tmpPtr+1; + WORK_formattedPrintArray("prepared bytes:", + worker->byteBuffer, worker->byteBufferLength); + return 0; } @@ -65,33 +75,21 @@ int WORK_preparePackage(workerHost_s *worker) { // Отправка пакета int WORK_sendPackage(workerHost_s *worker) { printf("WORKX: .. Sending package\n"); - if (FIFO_isUsable(worker->fifo) == 0) { - if (worker->fifo->count > 0) { - FIFO_put(worker->fifo, &worker->byteBuffer[worker->byteBufferHead]); - if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) { - worker->byteBufferHead++; - } else { - worker->byteBufferHead = 0; - return -2; - } - } else { - // fifo опустошился - return 1; - } - return 0; + + if (worker->byteBufferHead > worker->byteBufferLength) { + return -2; } - return 0; -} - -// Ожидание пакета -inline int WORK_waitPackage(workerHost_s *worker) { - printf("WORKX: .. Waiting for a package\n"); - if (FIFO_isUsable(worker->fifo) == 0) { - if (worker->fifo->count > 0) { - FIFO_get(worker->fifo, &worker->byteBuffer[worker->byteBufferHead]); - if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) { + if (FIFO_isUsable(worker->fifoWrite) == 0) { + if (worker->fifoWrite->count < FIFO_DATA_SIZE) { + FIFO_put(worker->fifoWrite, worker->byteBuffer[worker->byteBufferHead]); + if (worker->byteBufferHead < worker->byteBufferLength) { worker->byteBufferHead++; + } else if (worker->byteBufferHead == worker->byteBufferLength) { + // Передан весь буфер через фифо + WORK_formattedPrintArray("sent bytes:", + worker->byteBuffer, worker->byteBufferLength); + return 0; } else { worker->byteBufferHead = 0; return -2; @@ -99,35 +97,46 @@ inline int WORK_waitPackage(workerHost_s *worker) { } else { return 1; } - return 0; + return -1; } return -1; } -inline int WORK_receivePackage(workerHost_s *worker) { +// Ожидание пакета +int WORK_waitPackage(workerHost_s *worker) { + printf("WORKX: .. Waiting for a package\n"); + if (FIFO_isUsable(worker->fifoRead) == 0) { + if (worker->fifoRead->count > 0) { + // Появились данные в fifo + return 0; + } + } + return -1; +} + +int WORK_receivePackage(workerHost_s *worker) { printf("WORKX: .. Receiving package\n"); - // Receiving in buffer - - static int fifoEmptyCounter = 0; - static int bufPtr = 0; - uint8_t buf = 0; - int res = FIFO_get(worker->fifo, &buf); - // Байт из fifo забран - if (res == 0) { - fifoEmptyCounter = 0; - bufPtr++; + if (FIFO_isUsable(worker->fifoRead) == 0) { + if (worker->fifoRead->count > 0) { + FIFO_get(worker->fifoRead, &worker->byteBuffer[worker->byteBufferHead]); + if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) { + worker->byteBufferHead++; + } else { + worker->byteBufferHead = 0; + return -2; + } + } else { + if (worker->byteBufferHead > 0) { + // Приняли данные. Сейчас fifo пуст, можно обрабатывать пакет + // fifo пуст, можно обрабатывать пакет + WORK_formattedPrintArray("receives bytes:", + worker->byteBuffer, worker->byteBufferLength); + return 0; + } + return 1; + } } - // fifo опустошён - if (res == 1) { - fifoEmptyCounter++; - } - if (fifoEmptyCounter > 3) { - fifoEmptyCounter = 0; - bufPtr = 0; - return 0; - } - return -1; } @@ -137,83 +146,87 @@ int WORK_parsePackage(workerHost_s *worker) { // Поиск пакета в массиве uint8_t *first = NULL, *last = NULL; - uint8_t tmpBuf[WORK_BYTE_BUFFER_SIZE] = {0}; - uint8_t bufPtr=0; - for (size_t s = 0; s < WORK_BYTE_BUFFER_SIZE; s++, bufPtr++) { + size_t bufPtrI = 0, bufLen = 0; + uint8_t tmpArr[WORK_BYTE_BUFFER_SIZE] = {0}; + // Выносим из принятого массива только нагрузку в буфер + for (bufPtrI = 0; bufPtrI < WORK_BYTE_BUFFER_SIZE; bufPtrI++) { // Найден флаг - if (worker->byteBuffer[bufPtr] == HDLC_PACKET_FLAG) { + if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_FLAG) { if (!first) { - first = &tmpBuf[s]; + first = &worker->byteBuffer[bufPtrI]; first++; // Скипаем байт флага } else if (!last) { - last = &tmpBuf[s]; + last = &worker->byteBuffer[bufPtrI]; last--; + break; } } // Найден escape-флаг - if (worker->byteBuffer[bufPtr] == HDLC_PACKET_ESCAPE) { - if (worker->byteBuffer[bufPtr+1] == HDLC_PACKET_FLAG) { - bufPtr++; + if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_ESCAPE) { + if (worker->byteBuffer[bufPtrI+1] == HDLC_PACKET_FLAG) { + bufPtrI++; } - } - tmpBuf[s] = worker->byteBuffer[bufPtr]; + } } + WORK_formattedPrintArray("received bytes:", first, bufPtrI); // Разбор пакета в структуру if (first && last) { if (last > first) { - size_t len = last - first; + bufLen = last - first; // Так как может быть меньше в теории - if (len <= HDLC_PACKET_LENGTH) { - if (len > 2) { // Считываем адрес - worker->packet->address = ((uint16_t)*first << 8) | *(first+1); + if (bufLen <= HDLC_PACKET_LENGTH-2) { + if (bufLen > 2) { // Считываем адрес + uint16_t a = ((uint16_t)*first << 8) | *(first+1); + worker->packet->address = ((uint16_t)*(first+1) << 8) | *(first); first += 2; } - if (len > 4) { // Считываем управляющее поле - worker->packet->control = ((uint16_t)*first << 8) | *(first+1); + if (bufLen > 4) { // Считываем управляющее поле + worker->packet->control = ((uint16_t)*(first+1) << 8) | *(first); first += 2; } - if (len > 6) { // Считываем контрольную сумму - worker->packet->fcs = ((uint16_t)*(last-1) << 8) | *last; + if (bufLen > 6) { // Считываем контрольную сумму + worker->packet->fcs = ((uint16_t)*(last) << 8) | *(last-1); last -= 2; } - if ((len > 8) && (last > first)) { // Считываем информационный пакет + if ((bufLen > 8) && (last > first)) { // Считываем информационный пакет int j = 0; // От переполнения - if (last-first >= HDLC_INFO_LENGTH) { + size_t infoLen = last - first; + if (infoLen > HDLC_INFO_LENGTH) { return -1; } // Заполнение данными - for (uint8_t* i = first; i <= last; ++i) { + for (uint8_t* i = first; i < last; i++) { worker->packet->info[j] = *i; j++; } // Чистка хвоста - for (; j < HDLC_INFO_LENGTH; ++j) { + for (; j < HDLC_INFO_LENGTH; j++) { worker->packet->info[j] = 0; } } } } // (last > first) } // (first && last) - - memset(worker->byteBuffer, 0, WORK_BYTE_BUFFER_SIZE); - memcpy(worker->byteBuffer, tmpBuf, WORK_BYTE_BUFFER_SIZE); - - for (uint8_t i = 0; i < WORK_BYTE_BUFFER_SIZE/2; i++) { - printf("0x%d, ", worker->byteBuffer[i]); + else { + // неправильный пакет + return -1; } - printf("\n"); + + WORK_formattedPrintArray("parsed bytes:", worker->byteBuffer, bufPtrI); + // Проверка контрольной суммы разобранного пакета uint16_t crc = worker->packet->fcs; worker->packet->fcs = 0; - if (CRC16_compute((uint8_t*) worker->packet, sizeof(workerHost_s)) == crc) { + if (CRC16_compute((uint8_t*) &worker->packet, sizeof(workerHost_s)) == crc) { printf("WORKX: .. CRC OK"); + return 0; } else { printf("WORKX: .. WRONG CRC"); return -1; diff --git a/src/worker/worker.h b/src/worker/worker.h index 1d7fcaf..f9d40ba 100644 --- a/src/worker/worker.h +++ b/src/worker/worker.h @@ -15,14 +15,16 @@ // Структура устройства typedef struct { hdlcPacket_s *packet; - fifo_s *fifo; + fifo_s *fifoRead; + fifo_s *fifoWrite; uint8_t *byteBuffer; uint8_t byteBufferHead; + size_t byteBufferLength; bool isInitialized; } workerHost_s; #define WORK_BYTE_BUFFER_SIZE 128 - + workerHost_s* WORK_workerInit (workerHost_s* worker, hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer); diff --git a/src/worker/worker_master.c b/src/worker/worker_master.c index ad7c20c..6975158 100644 --- a/src/worker/worker_master.c +++ b/src/worker/worker_master.c @@ -6,9 +6,9 @@ static hdlcPacket_s hdlcMasterPacket = {0}; fifo_s hdlcMasterFifo; +extern fifo_s hdlcSlaveFifo; static workerHost_s hdlcMaster = {0}; static uint8_t masterBuffer[WORK_BYTE_BUFFER_SIZE]; -extern fifo_s hdlcSlaveFifo; int WORK_master (void) { @@ -38,6 +38,8 @@ int WORK_master (void) { case WSMASTER_waitClient: res = WORK_waitClient(&hdlcSlaveFifo); if (res == 0) { + // Дождались клиента на линии, сохраняем указатель на его фифо + hdlcMaster.fifoRead = &hdlcSlaveFifo; masterState = WSMASTER_preparingPackage; } break; @@ -50,6 +52,8 @@ int WORK_master (void) { hdlcMaster.packet->fcs = 0; uint16_t crc = CRC16_compute((uint8_t*) hdlcMaster.packet, sizeof(workerHost_s)); hdlcMaster.packet->fcs = crc; + hdlcMaster.byteBufferHead = 0; + res = WORK_execute(WORK_preparePackage, &hdlcMaster); if (res == 0) { masterState = WSMASTER_sendingPackage; diff --git a/src/worker/worker_slave.c b/src/worker/worker_slave.c index 21e14a0..0c3aef6 100644 --- a/src/worker/worker_slave.c +++ b/src/worker/worker_slave.c @@ -32,7 +32,10 @@ int WORK_slave(void) { break; case WSSLAVE_waitClient: - res = WORK_waitClient(&hdlcMasterFifo); + res = WORK_waitClient(&hdlcMasterFifo); + if (res == 0) { + hdlcSlave.fifoRead = &hdlcMasterFifo; + } break; case WSSLAVE_waitingPackage: diff --git a/src/worker/worker_tools.c b/src/worker/worker_tools.c index e574ce2..bebd24d 100644 --- a/src/worker/worker_tools.c +++ b/src/worker/worker_tools.c @@ -4,10 +4,22 @@ static inline void WORK_printArray (uint8_t* array, size_t size) { for (size_t s = 0; s < size; s++) { - printf("%d", array[s]); + printf("%d, ", array[s]); } } + +void WORK_formattedPrintArray(const char* str, uint8_t* array, size_t size) { + printf("WORKX: %s (%d bytes):", str, (int)size); + for (size_t s = 0; s < size; s++) { + printf("%d, ", array[s]); + } + printf("\n"); +} + +// printf("FILL:");for (int i = 0; i < 50; i++) {printf("%d:", worker->byteBuffer[i]);} printf("\n"); + + // Параметрический вывод пакета worker int WORK_printBlocks(workerHost_s *worker, uint8_t mode) { if (worker == NULL) { @@ -32,16 +44,16 @@ int WORK_printBlocks(workerHost_s *worker, uint8_t mode) { // Вывод содержимого буфера fifo if (mode & 3) { - size_t size = sizeof(worker->fifo->data) / sizeof(worker->fifo->data[0]); + size_t size = sizeof(worker->fifoWrite->data) / sizeof(worker->fifoWrite->data[0]); printf("TOOL: .. FIFO:\n"); printf("TOOL: .... Data (%d items): ", (int)size); for (size_t i = 0; i < size; i++) { - printf("%02X ", worker->fifo->data[i]); + printf("%02X ", worker->fifoWrite->data[i]); } printf("\n"); - printf("TOOL: .. Pointer: %d ", worker->fifo->head); + printf("TOOL: .. Pointer: %d ", worker->fifoWrite->head); } return 0;