Отладка, подготовка к вынесению отдельного буфера под парсинг

This commit is contained in:
ru.sadekov 2025-10-29 13:28:36 +03:00
parent 7b6eaa563b
commit ab3a8bc820
7 changed files with 127 additions and 93 deletions

View File

@ -12,7 +12,7 @@
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
#define HDLC_INFO_LENGTH 16 #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_FLAG 0x7e
#define HDLC_PACKET_ESCAPE 0xab #define HDLC_PACKET_ESCAPE 0xab

View File

@ -45,7 +45,7 @@ int main(void) {
break; break;
case OS_wait: case OS_wait:
TOOL_msleep(1000); TOOL_msleep(50);
printf("\n\n"); printf("\n\n");
break; break;

View File

@ -5,19 +5,19 @@
#include "hdlc.h" #include "hdlc.h"
#include "fifo.h" #include "fifo.h"
extern void WORK_formattedPrintArray(char* str, uint8_t* array, size_t size);
workerHost_s* WORK_workerInit (workerHost_s* worker, workerHost_s* WORK_workerInit (workerHost_s* worker,
hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer) { hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer) {
if (!worker->isInitialized) { if (!worker->isInitialized) {
printf("WORKX: Starting master worker initialization\n"); printf("WORKX: Starting master worker initialization\n");
worker->packet = packet; worker->packet = packet;
worker->fifo = fifo; worker->fifoWrite = fifo;
worker->fifoRead = NULL;
worker->isInitialized = true; worker->isInitialized = true;
worker->byteBuffer = buffer; worker->byteBuffer = buffer;
FIFO_init(worker->fifo); FIFO_init(worker->fifoWrite);
if (DO_UNIT_TESTS){WORK_testFifo(worker->fifo);}
printf("WORKX: Master initialization done\n"); printf("WORKX: Master initialization done\n");
WORK_printBlocks(worker, 3); WORK_printBlocks(worker, 3);
@ -46,9 +46,14 @@ int WORK_preparePackage(workerHost_s *worker) {
printf("WORKX: .. Preparing package\n"); 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 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++) { for (size_t s = 0; s < structSize; s++, tmpPtr++) {
// Нашли флаг в теле сообщения // Нашли флаг в теле сообщения
if (packPtr[s] == HDLC_PACKET_FLAG) { if (packPtr[s] == HDLC_PACKET_FLAG) {
@ -58,6 +63,11 @@ int WORK_preparePackage(workerHost_s *worker) {
worker->byteBuffer[tmpPtr] = packPtr[s]; 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; return 0;
} }
@ -65,33 +75,21 @@ int WORK_preparePackage(workerHost_s *worker) {
// Отправка пакета // Отправка пакета
int WORK_sendPackage(workerHost_s *worker) { int WORK_sendPackage(workerHost_s *worker) {
printf("WORKX: .. Sending package\n"); printf("WORKX: .. Sending package\n");
if (FIFO_isUsable(worker->fifo) == 0) {
if (worker->fifo->count > 0) { if (worker->byteBufferHead > worker->byteBufferLength) {
FIFO_put(worker->fifo, &worker->byteBuffer[worker->byteBufferHead]); return -2;
if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) {
worker->byteBufferHead++;
} else {
worker->byteBufferHead = 0;
return -2;
}
} else {
// fifo опустошился
return 1;
}
return 0;
} }
return 0;
}
if (FIFO_isUsable(worker->fifoWrite) == 0) {
// Ожидание пакета if (worker->fifoWrite->count < FIFO_DATA_SIZE) {
inline int WORK_waitPackage(workerHost_s *worker) { FIFO_put(worker->fifoWrite, worker->byteBuffer[worker->byteBufferHead]);
printf("WORKX: .. Waiting for a package\n"); if (worker->byteBufferHead < worker->byteBufferLength) {
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) {
worker->byteBufferHead++; worker->byteBufferHead++;
} else if (worker->byteBufferHead == worker->byteBufferLength) {
// Передан весь буфер через фифо
WORK_formattedPrintArray("sent bytes:",
worker->byteBuffer, worker->byteBufferLength);
return 0;
} else { } else {
worker->byteBufferHead = 0; worker->byteBufferHead = 0;
return -2; return -2;
@ -99,35 +97,46 @@ inline int WORK_waitPackage(workerHost_s *worker) {
} else { } else {
return 1; return 1;
} }
return 0; return -1;
} }
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"); printf("WORKX: .. Receiving package\n");
// Receiving in buffer if (FIFO_isUsable(worker->fifoRead) == 0) {
if (worker->fifoRead->count > 0) {
static int fifoEmptyCounter = 0; FIFO_get(worker->fifoRead, &worker->byteBuffer[worker->byteBufferHead]);
static int bufPtr = 0; if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) {
uint8_t buf = 0; worker->byteBufferHead++;
int res = FIFO_get(worker->fifo, &buf); } else {
// Байт из fifo забран worker->byteBufferHead = 0;
if (res == 0) { return -2;
fifoEmptyCounter = 0; }
bufPtr++; } 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; return -1;
} }
@ -137,83 +146,87 @@ int WORK_parsePackage(workerHost_s *worker) {
// Поиск пакета в массиве // Поиск пакета в массиве
uint8_t *first = NULL, *last = NULL; uint8_t *first = NULL, *last = NULL;
uint8_t tmpBuf[WORK_BYTE_BUFFER_SIZE] = {0}; size_t bufPtrI = 0, bufLen = 0;
uint8_t bufPtr=0; uint8_t tmpArr[WORK_BYTE_BUFFER_SIZE] = {0};
for (size_t s = 0; s < WORK_BYTE_BUFFER_SIZE; s++, bufPtr++) { // Выносим из принятого массива только нагрузку в буфер
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) { if (!first) {
first = &tmpBuf[s]; first = &worker->byteBuffer[bufPtrI];
first++; // Скипаем байт флага first++; // Скипаем байт флага
} else if (!last) { } else if (!last) {
last = &tmpBuf[s]; last = &worker->byteBuffer[bufPtrI];
last--; last--;
break;
} }
} }
// Найден escape-флаг // Найден escape-флаг
if (worker->byteBuffer[bufPtr] == HDLC_PACKET_ESCAPE) { if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_ESCAPE) {
if (worker->byteBuffer[bufPtr+1] == HDLC_PACKET_FLAG) { if (worker->byteBuffer[bufPtrI+1] == HDLC_PACKET_FLAG) {
bufPtr++; bufPtrI++;
} }
} }
tmpBuf[s] = worker->byteBuffer[bufPtr];
} }
WORK_formattedPrintArray("received bytes:", first, bufPtrI);
// Разбор пакета в структуру // Разбор пакета в структуру
if (first && last) { if (first && last) {
if (last > first) { if (last > first) {
size_t len = last - first; bufLen = last - first;
// Так как может быть меньше в теории // Так как может быть меньше в теории
if (len <= HDLC_PACKET_LENGTH) { if (bufLen <= HDLC_PACKET_LENGTH-2) {
if (len > 2) { // Считываем адрес if (bufLen > 2) { // Считываем адрес
worker->packet->address = ((uint16_t)*first << 8) | *(first+1); uint16_t a = ((uint16_t)*first << 8) | *(first+1);
worker->packet->address = ((uint16_t)*(first+1) << 8) | *(first);
first += 2; first += 2;
} }
if (len > 4) { // Считываем управляющее поле if (bufLen > 4) { // Считываем управляющее поле
worker->packet->control = ((uint16_t)*first << 8) | *(first+1); worker->packet->control = ((uint16_t)*(first+1) << 8) | *(first);
first += 2; first += 2;
} }
if (len > 6) { // Считываем контрольную сумму if (bufLen > 6) { // Считываем контрольную сумму
worker->packet->fcs = ((uint16_t)*(last-1) << 8) | *last; worker->packet->fcs = ((uint16_t)*(last) << 8) | *(last-1);
last -= 2; last -= 2;
} }
if ((len > 8) && (last > first)) { // Считываем информационный пакет if ((bufLen > 8) && (last > first)) { // Считываем информационный пакет
int j = 0; int j = 0;
// От переполнения // От переполнения
if (last-first >= HDLC_INFO_LENGTH) { size_t infoLen = last - first;
if (infoLen > HDLC_INFO_LENGTH) {
return -1; return -1;
} }
// Заполнение данными // Заполнение данными
for (uint8_t* i = first; i <= last; ++i) { for (uint8_t* i = first; i < last; i++) {
worker->packet->info[j] = *i; worker->packet->info[j] = *i;
j++; j++;
} }
// Чистка хвоста // Чистка хвоста
for (; j < HDLC_INFO_LENGTH; ++j) { for (; j < HDLC_INFO_LENGTH; j++) {
worker->packet->info[j] = 0; worker->packet->info[j] = 0;
} }
} }
} }
} // (last > first) } // (last > first)
} // (first && last) } // (first && last)
else {
memset(worker->byteBuffer, 0, WORK_BYTE_BUFFER_SIZE); // неправильный пакет
memcpy(worker->byteBuffer, tmpBuf, WORK_BYTE_BUFFER_SIZE); return -1;
for (uint8_t i = 0; i < WORK_BYTE_BUFFER_SIZE/2; i++) {
printf("0x%d, ", worker->byteBuffer[i]);
} }
printf("\n");
WORK_formattedPrintArray("parsed bytes:", worker->byteBuffer, bufPtrI);
// Проверка контрольной суммы разобранного пакета // Проверка контрольной суммы разобранного пакета
uint16_t crc = worker->packet->fcs; uint16_t crc = worker->packet->fcs;
worker->packet->fcs = 0; 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"); printf("WORKX: .. CRC OK");
return 0;
} else { } else {
printf("WORKX: .. WRONG CRC"); printf("WORKX: .. WRONG CRC");
return -1; return -1;

View File

@ -15,14 +15,16 @@
// Структура устройства // Структура устройства
typedef struct { typedef struct {
hdlcPacket_s *packet; hdlcPacket_s *packet;
fifo_s *fifo; fifo_s *fifoRead;
fifo_s *fifoWrite;
uint8_t *byteBuffer; uint8_t *byteBuffer;
uint8_t byteBufferHead; uint8_t byteBufferHead;
size_t byteBufferLength;
bool isInitialized; bool isInitialized;
} workerHost_s; } workerHost_s;
#define WORK_BYTE_BUFFER_SIZE 128 #define WORK_BYTE_BUFFER_SIZE 128
workerHost_s* WORK_workerInit (workerHost_s* worker, workerHost_s* WORK_workerInit (workerHost_s* worker,
hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer); hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer);

View File

@ -6,9 +6,9 @@
static hdlcPacket_s hdlcMasterPacket = {0}; static hdlcPacket_s hdlcMasterPacket = {0};
fifo_s hdlcMasterFifo; fifo_s hdlcMasterFifo;
extern fifo_s hdlcSlaveFifo;
static workerHost_s hdlcMaster = {0}; static workerHost_s hdlcMaster = {0};
static uint8_t masterBuffer[WORK_BYTE_BUFFER_SIZE]; static uint8_t masterBuffer[WORK_BYTE_BUFFER_SIZE];
extern fifo_s hdlcSlaveFifo;
int WORK_master (void) { int WORK_master (void) {
@ -38,6 +38,8 @@ int WORK_master (void) {
case WSMASTER_waitClient: case WSMASTER_waitClient:
res = WORK_waitClient(&hdlcSlaveFifo); res = WORK_waitClient(&hdlcSlaveFifo);
if (res == 0) { if (res == 0) {
// Дождались клиента на линии, сохраняем указатель на его фифо
hdlcMaster.fifoRead = &hdlcSlaveFifo;
masterState = WSMASTER_preparingPackage; masterState = WSMASTER_preparingPackage;
} }
break; break;
@ -50,6 +52,8 @@ int WORK_master (void) {
hdlcMaster.packet->fcs = 0; hdlcMaster.packet->fcs = 0;
uint16_t crc = CRC16_compute((uint8_t*) hdlcMaster.packet, sizeof(workerHost_s)); uint16_t crc = CRC16_compute((uint8_t*) hdlcMaster.packet, sizeof(workerHost_s));
hdlcMaster.packet->fcs = crc; hdlcMaster.packet->fcs = crc;
hdlcMaster.byteBufferHead = 0;
res = WORK_execute(WORK_preparePackage, &hdlcMaster); res = WORK_execute(WORK_preparePackage, &hdlcMaster);
if (res == 0) { if (res == 0) {
masterState = WSMASTER_sendingPackage; masterState = WSMASTER_sendingPackage;

View File

@ -32,7 +32,10 @@ int WORK_slave(void) {
break; break;
case WSSLAVE_waitClient: case WSSLAVE_waitClient:
res = WORK_waitClient(&hdlcMasterFifo); res = WORK_waitClient(&hdlcMasterFifo);
if (res == 0) {
hdlcSlave.fifoRead = &hdlcMasterFifo;
}
break; break;
case WSSLAVE_waitingPackage: case WSSLAVE_waitingPackage:

View File

@ -4,10 +4,22 @@
static inline void WORK_printArray (uint8_t* array, size_t size) { static inline void WORK_printArray (uint8_t* array, size_t size) {
for (size_t s = 0; s < size; s++) { 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 // Параметрический вывод пакета worker
int WORK_printBlocks(workerHost_s *worker, uint8_t mode) { int WORK_printBlocks(workerHost_s *worker, uint8_t mode) {
if (worker == NULL) { if (worker == NULL) {
@ -32,16 +44,16 @@ int WORK_printBlocks(workerHost_s *worker, uint8_t mode) {
// Вывод содержимого буфера fifo // Вывод содержимого буфера fifo
if (mode & 3) { 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: .. FIFO:\n");
printf("TOOL: .... Data (%d items): ", (int)size); printf("TOOL: .... Data (%d items): ", (int)size);
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
printf("%02X ", worker->fifo->data[i]); printf("%02X ", worker->fifoWrite->data[i]);
} }
printf("\n"); printf("\n");
printf("TOOL: .. Pointer: %d ", worker->fifo->head); printf("TOOL: .. Pointer: %d ", worker->fifoWrite->head);
} }
return 0; return 0;