Отладка WORK_parsePackage

This commit is contained in:
ru.sadekov 2025-10-24 12:43:49 +03:00
parent 14e71a3ccc
commit bfe0df9256
18 changed files with 261 additions and 116 deletions

30
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/test-kod-bez",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "CMake: build"
}
]
}

18
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"files.associations": {
"worker_type.h": "c",
"main.h": "c",
"stdio.h": "c",
"stdint.h": "c",
"stdbool.h": "c",
"unistd.h": "c",
"stdlib.h": "c",
"time.h": "c",
"hdlc_type.h": "c",
"hdlc.h": "c",
"fifo_type.h": "c",
"chrono": "c",
"span": "c",
"worker.h": "c"
}
}

View File

@ -1,12 +1,12 @@
cmake_minimum_required(VERSION 4.1 FATAL_ERROR)
set(PROJECT_NAME testKodBez)
set(PROJECT_NAME test-kod-bez)
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
project(${PROJECT_NAME} LANGUAGES C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
add_executable(${PROJECT_NAME} ${SOURCE_DIR}/main.c)
@ -29,6 +29,9 @@ set(SOURCES
)
target_include_directories(${PROJECT_NAME} PRIVATE ${HEADERS})
# target_compile_definitions(${PROJECT_NAME} PRIVATE __USE_POSIX199309 __USE_ISOC11)
target_compile_definitions(${PROJECT_NAME} PRIVATE _POSIX_C_SOURCE=199309L _ISOC11_SOURCE)
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "bin")

View File

@ -1 +1,2 @@
#include "fifo.h"

View File

@ -4,4 +4,5 @@
#include "fifo_type.h"
#endif // FIFO_H

View File

@ -4,7 +4,7 @@
#include <stdint.h>
// Структура FIFO
// Структура состояний FIFO
typedef enum {
FIFOS_empty = 0,
FIFOS_ready,
@ -12,6 +12,7 @@ typedef enum {
FIFOS_error
} fifoState;
// Структура FIFO
typedef struct {
uint8_t data[8];
uint8_t pointer;

View File

@ -2,40 +2,11 @@
#include "hdlc.h"
#include "hdlc_type.h"
typedef enum {
HDLCCFT_info = 0,
HDLCCFT_control,
HDLCCFT_unnumbered,
HDLCCFT_undefined
} controlFieldType_e;
int HDLC_printControlField (hdlcControlField16b_u field);
controlFieldType_e HDLC_checkControlField (uint16_t value);
int HDLC_printControlField (hdlcControlField16b_s field);
controlFieldType_e HDLC_checkControlField (uint16_t value) {
controlFieldType_e controlFieldType;
// Определяем тип информационного кадра:
// 0b0... - информационный,
// 0b10... - управляющий,
// 0b11... - ненумерованный
if (((value >> 7) & 1) == 0) {
controlFieldType = HDLCCFT_info;
} else {
if (((value >> 6) & 1) == 0) {
controlFieldType = HDLCCFT_control;
} else {
controlFieldType = HDLCCFT_unnumbered;
}
}
return controlFieldType;
}
int HDLC_printControlField (hdlcControlField16b_s field) {
int HDLC_printControlField (hdlcControlField16b_u field) {
printf ("HDLC: Printing fields:\n");
printf ("HDLC: .. Type:\n");
printf ("HDLC: .. Send sequence: %d\n", field.bits.sendSequence);
@ -46,8 +17,8 @@ int HDLC_printControlField (hdlcControlField16b_s field) {
}
hdlcControlField16b_s HDLC_parseControlField (uint16_t value) {
hdlcControlField16b_s fieldUnion;
hdlcControlField16b_u HDLC_parseControlField (uint16_t value) {
hdlcControlField16b_u fieldUnion;
// fieldUnion.value = TOOL_reverseBits16(value);
fieldUnion.value = value;
@ -59,7 +30,7 @@ hdlcControlField16b_s HDLC_parseControlField (uint16_t value) {
int HDLC_isControlFieldValid (uint16_t value) {
if ((HDLC_checkControlField != HDLCCFT_info) || (value == 0)) {
if ((value == 0xffff) || (value == 0)) {
printf ("HDLC: Wrong control field:\n");
// Так как обрабатывается только вариант с информационным пакетом
return -1;

View File

@ -5,6 +5,7 @@
#include <stdint.h>
#include "hdlc_type.h"
// Cтруктура поля управления
typedef union {
struct __attribute__((packed)) {
uint8_t receiveSequence : 7;
@ -13,10 +14,10 @@ typedef union {
uint8_t type : 1;
} bits;
uint16_t value;
} hdlcControlField16b_s;
} hdlcControlField16b_u;
int HDLC_isControlFieldValid (uint16_t value);
hdlcControlField16b_s HDLC_parseControlField (uint16_t value);
hdlcControlField16b_u HDLC_parseControlField (uint16_t value);
#endif // HDLC_H

View File

@ -4,16 +4,22 @@
#include "fifo_type.h"
#define hdlcInfoLength 16
// ----------------------------------------------------------------------------------
// Фрейм HDLC
// Флаг FD | Адрес | Управляющее поле | Информационное поле | FCS | Флаг FD
// 8 бит | кратно 8 | 8 или 16 бит | 0 или более байт | 16 бит | 8 бит
// ----------------------------------------------------------------------------------
#define HDLC_INFO_LENGTH 16
#define HDLC_PACKET_LENGTH 2+2+HDLC_INFO_LENGTH+2
// Структура пакета (фрейма) HDLC
// Флаг FD | Адрес | Управляющее поле | Информационное поле | FCS | Флаг FD
// 8 бит | кратно 8 | 8 или 16 бит | 0 или более бит, кратно 8 | 16 бит | 8 бит
typedef struct {
const uint8_t flag;
const uint16_t address;
uint16_t address;
uint16_t control;
uint8_t info[hdlcInfoLength];
uint8_t info[HDLC_INFO_LENGTH];
uint16_t fcs;
// const uint8_t closeFlag;
} hdlcPacket_s;

View File

@ -47,13 +47,13 @@ int main(void) {
break;
case OS_wait:
sleep (1);
TOOL_msleep(1000);
break;
default:
printf("OS: Wrong state, going to first state");
bigLoopOsState = OS_first;
sleep (3);
TOOL_msleep(3000);
printf("\033[2J\033[H");
break;
}
@ -61,7 +61,7 @@ int main(void) {
bigLoopOsState++;
// Для контроля
sleep (1);
TOOL_msleep(100);
}
return 0;

View File

@ -6,7 +6,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
// Конфигурация
static const uint16_t hdlcMasterAddress = 0b10000000;
@ -15,6 +14,7 @@ static const uint16_t hdlcSlaveAddress = 0b11000000;
// Вспомогательные функции
uint16_t CRC16_compute(uint8_t *data, size_t length);
uint16_t TOOL_reverseBits16(uint16_t value);
void TOOL_msleep(long milliseconds);
// Потоки ОС
int WORK_master(void);

View File

@ -1,6 +1,7 @@
// Файл с общими функциями и конфигурацией
#include "main.h"
#include <time.h>
// Вычисление контрольной суммы CRC16
@ -50,3 +51,17 @@ uint16_t TOOL_reverseBitsN(uint16_t value, uint8_t n) {
return reversed;
}
void TOOL_msleep(long milliseconds) {
struct timespec ts;
ts.tv_sec = milliseconds / 1000; // Seconds part
ts.tv_nsec = (milliseconds % 1000) * 1000000; // Nanoseconds part
// nanosleep can be interrupted by signals, so we loop if interrupted
while (nanosleep(&ts, &ts) == -1) {
// If interrupted, remaining time is in ts, so we continue sleeping
// unless an actual error occurred (other than EINTR)
// For simplicity, this example assumes EINTR is the only -1 cause.
}
}

View File

@ -5,37 +5,22 @@
#include "hdlc.h"
#include "fifo.h"
int WORK_prepareTestPackage(uint8_t *buffer, size_t size) {
memset(buffer, 0, size);
for (size_t i = 0; i < size; i++) {
buffer[i] = i;
}
return 0;
}
// Подготовка пакета для отправки
int WORK_preparePackage(workerHost_s *worker) {
printf("WORKX: .. Preparing package\n");
worker->packet->control = 0b0100110011110000;
WORK_prepareTestPackage(worker->packet->info, hdlcInfoLength);
// memcpy(packet->info, testInfo, hdlcInfoLength);
worker->packet->fcs = CRC16_compute(worker->packet->info, hdlcInfoLength);
WORK_fillBuffer8b(worker->packet->info, HDLC_INFO_LENGTH);
// memcpy(packet->info, testInfo, HDLC_INFO_LENGTH);
worker->packet->fcs = CRC16_compute(worker->packet->info, HDLC_INFO_LENGTH);
return 0;
}
int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker) {
if (callback == NULL) {
return -1;
}
int res = callback(worker);
return res;
}
// Отправка пакета
int WORK_sendPackage(workerHost_s *worker) {
printf("WORKX: .. Sending package\n");
return 0;
}
@ -43,32 +28,117 @@ int WORK_sendPackage(workerHost_s *worker) {
// Ожидание пакета
int WORK_waitPackage(workerHost_s *worker) {
printf("WORKX: .. Waiting for a package\n");
return 0;
}
int WORK_receivePackage(workerHost_s *worker) {
printf("WORKX: .. Receiving package\n");
// Receiving in buffer
WORK_testFill(worker->byteBuffer, WORK_BYTE_BUFFER_SIZE);
return 0;
}
int WORK_parsePackage(workerHost_s *worker) {
printf("WORKX: .. Parsing package\n");
uint8_t *first = NULL, *last = NULL;
// Поиск пакета в массиве
for (size_t i = 0; i < WORK_BYTE_BUFFER_SIZE; i++) {
if (worker->byteBuffer[i] == worker->packet->flag) {
if (!first) {
first = &worker->byteBuffer[i];
first++; // Скипаем байт флага
} else if (!last) {
last = &worker->byteBuffer[i];
last--;
}
}
}
// Разбор пакета в структуру
if (first && last) {
if (last > first) {
size_t len = last - first;
// Так как может быть меньше в теории
if (len <= HDLC_PACKET_LENGTH) {
if (len > 2) { // Считываем адрес
worker->packet->address = ((uint16_t)*first << 8) | *(first+1);
first += 2;
}
if (len > 4) { // Считываем управляющее поле
worker->packet->control = ((uint16_t)*first << 8) | *(first+1);
first += 2;
}
if (len > 6) { // Считываем контрольную сумму
worker->packet->fcs = ((uint16_t)*(last-1) << 8) | *last;
last -= 2;
}
if ((len > 8) && (last > first)) { // Считываем информационный пакет
int j = 0;
// От переполнения
if (last-first >= HDLC_INFO_LENGTH) {
return -1;
}
// Заполнение данными
for (uint8_t* i = first; i <= last; ++i) {
worker->packet->info[j] = *i;
j++;
}
// Чистка хвоста
for (; j < HDLC_INFO_LENGTH; ++j) {
worker->packet->info[j] = 0;
}
}
}
}
}
// HDLC_parseControlField (worker->packet->control);
// printf("WORKX: .. Info value: %d\n", field.value);
return 0;
}
int WORK_checkPackage(workerHost_s *worker) {
// Проверка поля управления
if (HDLC_isControlFieldValid(worker->packet->control)){
printf("WORKX: Package is info. Parsing...\n");
hdlcControlField16b_s field = HDLC_parseControlField (worker->packet->control);
printf("WORKX: Package has been parsed...\n");
printf("WORKX: .. Checking package\n");
int res = 0;
res = HDLC_isControlFieldValid(worker->packet->control);
// Проверка поля управления
if (res != 0) {
return res;
}
printf("WORKX: .. Package is info ...\n");
// Проверка контрольной суммы
printf("WORKX: Package checked\n");
printf("WORKX: .. Package checked\n");
return 0;
}
// Вызов функций обработчика хоста
int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker) {
if (callback == NULL) {
printf("WORKX: .. Wrong object\n");
return -1;
}
int res = callback(worker);
if (res != 0) {
printf("WORKX: .. Error\n");
}
return res;
}

View File

@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "hdlc_type.h"
@ -19,9 +20,8 @@ typedef struct {
bool isInitialized;
} workerHost_s;
#define workByteBufferSize 128
#define WORK_BYTE_BUFFER_SIZE 128
int WORK_printBlocks(workerHost_s *worker, uint8_t mode);
int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker);
int WORK_preparePackage(workerHost_s *worker);
@ -31,8 +31,11 @@ int WORK_receivePackage(workerHost_s *worker);
int WORK_checkPackage(workerHost_s *worker);
int WORK_parsePackage(workerHost_s *worker);
int WORK_prepareTestPackage(uint8_t *buffer, size_t size);
int WORK_fillBuffer8b(uint8_t *buffer, size_t size);
// tools
int WORK_printBlocks(workerHost_s *worker, uint8_t mode);
int WORK_testFill(uint8_t* buffer, size_t bufferSize);
#endif //WORKER_H

View File

@ -7,29 +7,33 @@
static hdlcPacket_s hdlcMasterPacket = {hdlcFlag, hdlcMasterAddress};
static fifo_s hdlcMasterFifo;
static workerHost_s hdlcMaster = {0};
static uint8_t masterBuffer[WORK_BYTE_BUFFER_SIZE];
workerHost_s* WORK_masterInit () {
if (!hdlcMaster.isInitialized) {
printf("WORKM: Starting master worker initialization\n");
printf("WMAST: Starting master worker initialization\n");
hdlcMaster.packet = &hdlcMasterPacket;
hdlcMaster.fifo = &hdlcMasterFifo;
hdlcMaster.isInitialized = true;
printf("WORKM: Master initialization done\n");
hdlcMaster.byteBuffer = masterBuffer;
printf("WMAST: Master initialization done\n");
WORK_printBlocks(&hdlcMaster, 3);
return &hdlcMaster;
}
// Ошибка в пакете, повторная инициализация
hdlcMaster.isInitialized = false;
return NULL;
}
static uint8_t masterBuffer[workByteBufferSize];
int WORK_master (void) {
static workerState_e masterState = WORKSTATE_first;;
static workerHostState_e masterState = WORKSTATE_first;
if (masterState >= WORKSTATE_last) {
masterState = WORKSTATE_first;
}
printf("WORKM: In master worker\n");
printf("WMAST: In master worker\n");
int res = 0;
@ -40,7 +44,6 @@ int WORK_master (void) {
// Инициализация хоста
case WORKSTATE_initializing:
printf("WORKM: Initializing\n");
if (WORK_masterInit() != NULL) {
masterState = WORKSTATE_preparingPackage;
}
@ -48,7 +51,6 @@ int WORK_master (void) {
// Подготовка пакета
case WORKSTATE_preparingPackage:
printf("WORKM: Preparing package\n");
res = WORK_execute(WORK_preparePackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_sendingPackage;
@ -57,7 +59,6 @@ int WORK_master (void) {
// Отправка пакета
case WORKSTATE_sendingPackage:
printf("WORKM: Sending package\n");
res = WORK_execute(WORK_sendPackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_waitingPackage;
@ -66,7 +67,6 @@ int WORK_master (void) {
// Ожидание ответа
case WORKSTATE_waitingPackage:
printf("WORKM: Waiting package\n");
res = WORK_execute(WORK_waitPackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_receivingPackage;
@ -75,7 +75,6 @@ int WORK_master (void) {
// Получение пакета
case WORKSTATE_receivingPackage:
printf("WORKM: Receiving package\n");
res = WORK_execute(WORK_receivePackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_parsingPackage;
@ -84,7 +83,6 @@ int WORK_master (void) {
// Парсинг пакета
case WORKSTATE_parsingPackage:
printf("WORKM: Parsing package\n");
res = WORK_execute(WORK_parsePackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_checkingPackage;
@ -93,7 +91,6 @@ int WORK_master (void) {
// Проверка пакета
case WORKSTATE_checkingPackage:
printf("WORKM: Checking package\n");
res = WORK_execute(WORK_checkPackage, &hdlcMaster);
if (res == 0) {
masterState = WORKSTATE_last;
@ -102,8 +99,9 @@ int WORK_master (void) {
// Цикл завершён, повторяем
case WORKSTATE_last:
printf("WORKM: Job done. Starting from the beginning\n");
masterState = WORKSTATE_preparingPackage;
printf("WMAST: Job done. Starting from the beginning\n");
masterState = WORKSTATE_first;
// Либо переходить сразу на подготовку пакета
break;
}

View File

@ -7,11 +7,11 @@ static workerHost_s hdlcSlave = {0};
workerHost_s* WORK_slaveInit () {
if (!hdlcSlave.isInitialized) {
printf("WORKM: Starting slave worker initialization\n");
printf("WSLAV: Starting slave worker initialization\n");
hdlcSlave.packet = &hdlcSlavePacket;
hdlcSlave.fifo = &hdlcSlaveFifo;
hdlcSlave.isInitialized = true;
printf("WORKS: Slave initialization done\n");
printf("WSLAV Slave initialization done\n");
WORK_printBlocks(&hdlcSlave, 3);
}
@ -21,7 +21,7 @@ workerHost_s* WORK_slaveInit () {
int WORK_slave(void) {
WORK_slaveInit();
printf("WORKS: In slave worker\n");
printf("WSLAV: In slave worker\n");
return 0;
}

View File

@ -38,3 +38,30 @@ int WORK_printBlocks(workerHost_s *worker, uint8_t mode) {
return 0;
}
// Тестовое заполнение буфера
int WORK_testFill(uint8_t* buffer, size_t bufferSize) {
static uint8_t testbuffer[50] = {
0xaa,0xbb,
0x7e,
0xa1, 0xa2,
0xc1, 0xc2,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xde,
0xcc, 0xcd,
0x7e
};
for (int i = 0; i < 50; i++) {
buffer[i] = testbuffer[i];
}
return 0;
}
// Заполнение массива
int WORK_fillBuffer8b(uint8_t *buffer, size_t size) {
memset(buffer, 0, size);
for (size_t i = 0; i < size; i++) {
buffer[i] = i;
}
return 0;
}

View File

@ -2,16 +2,16 @@
#ifndef WORKER_TYPE_H
#define WORKER_TYPE_H
// Перечисление статусов машины состояния
typedef enum {
WORKE_first = 0,
WORKE_masterWorker,
WORKE_slaveWorker,
WORKE_wait,
WORKE_last
} workerState_e;
// Перечисление статусов машины состояния общего обработчика
// typedef enum {
// WORKE_first = 0,
// WORKE_masterWorker,
// WORKE_slaveWorker,
// WORKE_wait,
// WORKE_last
// } workerState_e;
// Перечисление статусов хоста
// Перечисление статусов конкретного хоста
typedef enum {
WORKSTATE_first = 0,
WORKSTATE_initializing,