Initializing the repository

This commit is contained in:
2025-05-06 16:44:21 +03:00
commit f693d28c78
9 changed files with 491 additions and 0 deletions

31
.clang-format Normal file
View File

@@ -0,0 +1,31 @@
AccessModifierOffset: -4
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveDeclarations: Consecutive
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: None
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: All
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakTemplateDeclarations: Yes
ColumnLimit: 100
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IndentExternBlock: NoIndent
IndentPPDirectives: AfterHash
IndentWidth: 4
NamespaceIndentation: None
PackConstructorInitializers: Never
PointerAlignment: Right
ReflowComments: Always
SortIncludes: CaseSensitive
TabWidth: 4
UseTab: Never

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.vscode
.idea
cache
build

33
CMakeLists.txt Normal file
View File

@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.0)
project(jlv135_cli C)
# Настройка кросс-компиляции
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER arm-uclinuxfdpiceabi-gcc)
set(CMAKE_STRIP arm-uclinuxfdpiceabi-strip)
# Настройки компиляции
set(CMAKE_C_FLAGS "-Os -fdata-sections -ffunction-sections -mno-unaligned-access")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections")
# Создание исполняемого файла
add_executable(${PROJECT_NAME}
src/jl_modbus/jl_modbus_config.c
src/jl_modbus/jl_config.c
src/jlv135_cli/main.c)
# Настройка библиотек
target_link_libraries(${CMAKE_PROJECT_NAME} pthread)
# Добавление каталогов для поиска заголовков
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
inc)
# Опция strip
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_custom_command(
TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
COMMAND strip $<TARGET_FILE:${CMAKE_PROJECT_NAME}>
COMMENT "Stripping debug symbols (Release only)"
)
endif()

22
inc/jl_modbus/jl_config.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef JLV135_CLI_CONFIG_H
#define JLV135_CLI_CONFIG_H
#include <stddef.h>
#include <stdbool.h>
#define JLV135_BACKUP_BLOCKS_ADDRESS 0x40400
#define JLV135_DEV_MTD_BLOCK "/dev/mtdblock0"
void
jl_config_load(const char *name, void *def, size_t size);
bool
jl_config_read(int block_num, void *data, size_t size);
bool
jl_config_write(int block_num, void *data, size_t size);
void
jl_config_save(const char *name, void *def, size_t size);
#endif // JLV135_CLI_CONFIG_H

View File

@@ -0,0 +1,54 @@
#ifndef JLV135_CLI_MODBUS_CONFIG_H
#define JLV135_CLI_MODBUS_CONFIG_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef struct jl_version
{
uint16_t major;
uint16_t minor;
uint16_t path;
} jl_version_t;
typedef struct jl_modbus_tcp_port
{
uint32_t addr;
uint16_t port;
uint16_t repeate;
uint16_t timeout;
} jl_modbus_tcp_port_t;
static const uint32_t jl_modbus_rs485_baud_rates[] = {9600, 19200, 38400, 57600, 115200};
typedef struct jl_modbus_rs485_port
{
uint16_t speed;
uint16_t prop_p;
uint16_t prop_s;
uint16_t repeate;
uint16_t timeout;
} jl_modbus_rs485_port_t;
typedef struct jl_modbus_config
{
uint16_t num_port;
uint16_t addr;
uint16_t tcycle;
jl_modbus_rs485_port_t port_rtu;
jl_modbus_tcp_port_t port_tcp;
} jl_modbus_config_t;
// -------------------------- Методы -------------------------- //
bool
jl_modbus_rs485_baud_rate_is_index_valid(size_t index);
uint32_t
jl_modbus_rs485_baud_rate_get_baud_by_index(size_t index);
int32_t
jl_modbus_rs485_baud_rate_get_index_by_baud(uint32_t baud);
#endif // JLV135_CLI_MODBUS_CONFIG_H

6
inc/jlv135_cli/jl_util.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef JL135_CLI_UTIL
#define JL135_CLI_UTIL
#define jl_array_size(x) (sizeof(x) / sizeof(x[0]))
#endif // JL135_CLI_UTIL

173
src/jl_modbus/jl_config.c Normal file
View File

@@ -0,0 +1,173 @@
#include <jl_modbus/jl_config.h>
#include <stdio.h>
#include <string.h>
#if JL_CONFIG_SAVE_TO_FILE
static const char *jl_config_path = JL_CONFIG_SAVE_TO_FILE_PATH;
void
jl_config_load(const char *name, void *def, size_t size)
{
char filename[256] = {0};
strcat(filename, jl_config_path);
strcat(filename, name);
strcat(filename, ".bcfg");
// printf("jl_config_load [%s]\n", filename);
FILE *f = fopen(filename, "rb");
if (f != NULL)
{
fread(def, 1, size, f);
fclose(f);
// printf("Load %s\n", name);
return;
}
jl_config_save(name, def, size);
}
void
jl_config_save(const char *name, void *def, size_t size)
{
char filename[256] = {0};
strcat(filename, jl_config_path);
strcat(filename, name);
strcat(filename, ".bcfg");
// printf("jl_config_save [%s]\n", filename);
FILE *f = fopen(filename, "wb");
if (f != NULL)
{
// printf("Save %s\n", name);
fwrite(def, 1, size, f);
fclose(f);
sync();
}
}
#else
const int backup_block_size = 0x80;
struct backup_block_t
{
char name[32];
int num;
} backup_blocks[] = {{.name = "wifi", .num = 0},
{.name = "modbus", .num = 1},
{.name = "display", .num = 2},
{.name = "feature", .num = 3},
{.name = "datatime", .num = 4},
{.name = "sensor", .num = 5},
{.name = "secure", .num = 6},
{.name = "service", .num = 7},
{{0}}};
bool
jl_config_read(int block_num, void *data, size_t size)
{
FILE *mtd0 = fopen(JLV135_DEV_MTD_BLOCK, "rb");
size_t read_size = 0;
if (mtd0)
{
bool isSeek =
fseek(mtd0, JLV135_BACKUP_BLOCKS_ADDRESS + backup_block_size * block_num, SEEK_SET) ==
0;
if (isSeek)
{
read_size = fread(data, 1, size, mtd0);
}
}
else
{
return false;
}
fclose(mtd0);
return read_size == size;
}
bool
jl_config_write(int block_num, void *data, size_t size)
{
FILE *mtd0 = fopen(JLV135_DEV_MTD_BLOCK, "r+b");
size_t write_size = 0;
if (mtd0)
{
bool isSeek =
fseek(mtd0, JLV135_BACKUP_BLOCKS_ADDRESS + backup_block_size * block_num, SEEK_SET) ==
0;
if (isSeek)
{
write_size = fwrite(data, 1, size, mtd0);
rewind(mtd0);
}
}
else
{
return false;
}
fclose(mtd0);
return write_size == size;
}
void
jl_config_load(const char *name, void *def, size_t size)
{
struct backup_block_t *block = backup_blocks;
while (*block->name)
{
if (strcmp(block->name, name) == 0)
{
unsigned char mem[size];
bool empty = true;
if (!jl_config_read(block->num, mem, size))
{
return;
}
for (int i = 0; i < size; i++)
{
if (mem[i] != 0xFF)
{
empty = false;
break;
}
}
if (empty)
{
jl_config_save(name, def, size);
}
else
{
memcpy(def, mem, size);
}
return;
}
block++;
}
}
void
jl_config_save(const char *name, void *def, size_t size)
{
struct backup_block_t *block = backup_blocks;
while (*block->name)
{
if (strcmp(block->name, name) == 0)
{
unsigned char temp[size];
if (jl_config_read(block->num, temp, size) && memcmp(temp, def, size) == 0)
{
return;
}
jl_config_write(block->num, def, size);
return;
}
block++;
}
}
#endif

View File

@@ -0,0 +1,29 @@
#include <jl_modbus/jl_modbus_config.h>
#include <jlv135_cli/jl_util.h>
bool
jl_modbus_rs485_baud_rate_is_index_valid(size_t index)
{
size_t sz = jl_array_size(jl_modbus_rs485_baud_rates);
return index < sz;
}
uint32_t
jl_modbus_rs485_baud_rate_get_baud_by_index(size_t index)
{
return jl_modbus_rs485_baud_rate_is_index_valid(index) ? jl_modbus_rs485_baud_rates[index] : 0;
}
int32_t
jl_modbus_rs485_baud_rate_get_index_by_baud(uint32_t baud)
{
size_t sz = jl_array_size(jl_modbus_rs485_baud_rates);
for (size_t i = 0; i < sz; i++)
{
if (jl_modbus_rs485_baud_rates[i] == baud)
{
return (int32_t)i;
}
}
return -1;
}

139
src/jlv135_cli/main.c Normal file
View File

@@ -0,0 +1,139 @@
#include <jl_modbus/jl_config.h>
#include <jl_modbus/jl_modbus_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define JLV135_CLI_OK 0
#define JLV135_CLI_ERROR 1
void
print_version(jl_version_t *ver)
{
printf("Version:\n");
printf(" major: %u\n", ver->major);
printf(" minor: %u\n", ver->minor);
printf(" path: %u\n\n", ver->path);
}
// Функция для печати TCP порта
void
print_tcp_port(jl_modbus_tcp_port_t *tcp)
{
printf("Modbus TCP Port:\n");
printf(" addr: %u\n", tcp->addr);
printf(" port: %u\n", tcp->port);
printf(" repeate: %u\n", tcp->repeate);
printf(" timeout: %u\n\n", tcp->timeout);
}
void
print_rs485_baud_rates(uint16_t speed_index)
{
if (jl_modbus_rs485_baud_rate_is_index_valid(speed_index))
{
printf(" speed: %u\n", jl_modbus_rs485_baud_rates[speed_index]);
}
else
{
printf(" speed: %s\n", "unknown");
}
}
// Функция для печати RS485 порта
void
print_rs485_port(jl_modbus_rs485_port_t *rs485)
{
printf("Modbus RS485 Port:\n");
print_rs485_baud_rates(rs485->speed);
printf(" prop_p: %u\n", rs485->prop_p);
printf(" prop_s: %u\n", rs485->prop_s);
printf(" repeate: %u\n", rs485->repeate);
printf(" timeout: %u\n\n", rs485->timeout);
}
// Функция для печати конфигурации Modbus
void
print_modbus_config(jl_modbus_config_t *config)
{
printf("Modbus Config:\n");
printf(" num_port: %u\n", config->num_port);
printf(" addr: %u\n", config->addr);
printf(" tcycle: %u\n", config->tcycle);
printf("\n");
// Печатаем вложенные структуры
print_rs485_port(&config->port_rtu);
print_tcp_port(&config->port_tcp);
}
int
main(int argc, const char *argv[])
{
jl_modbus_config_t conf = {};
jl_config_load("modbus", &conf, sizeof(jl_modbus_config_t));
if (argc == 1)
{
print_modbus_config(&conf);
}
else
{
bool modbus_mode = false; // Флаг, что был передан --modbus
bool modbus_rs485_mode = true; // Флаг, что был передан --rs485
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--modbus") == 0)
{
modbus_mode = true;
continue;
}
else if (modbus_mode)
{
// Эти параметры обрабатываются только если был --modbus
if (modbus_mode && strcmp(argv[i], "--rs485") == 0)
{
modbus_rs485_mode = true;
continue;
}
else if (modbus_rs485_mode && strcmp(argv[i], "--speed") == 0)
{
if (i + 1 < argc)
{
long val = strtol(argv[i + 1], NULL, 10);
int idx = jl_modbus_rs485_baud_rate_get_index_by_baud(val);
if (idx == -1)
{
fprintf(stderr, "Error: invalid speed value\n");
return JLV135_CLI_ERROR;
}
else
{
conf.port_rtu.speed = idx;
jl_config_save("modbus", &conf, sizeof(jl_modbus_config_t));
}
break;
}
else
{
fprintf(stderr, "Error: --speed requires a value\n");
return JLV135_CLI_ERROR;
}
}
else
{
fprintf(stderr, "Unknown parameter for --modbus: %s\n", argv[i]);
return JLV135_CLI_ERROR;
}
}
else
{
fprintf(stderr, "Unknown parameter: %s (did you forget --modbus?)\n", argv[i]);
return JLV135_CLI_ERROR;
}
}
}
return JLV135_CLI_OK;
}