Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
LTA_mcu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
CI / CD Analytics
Repository Analytics
Value Stream Analytics
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Александр Пчелин
LTA_mcu
Commits
cc944181
Commit
cc944181
authored
Apr 29, 2026
by
Александр Пчелин
Browse files
Options
Browse Files
Download
Plain Diff
Добавлен рабочий скрипт для апи
parents
39bf9ab4
401288d2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
68 additions
and
67 deletions
+68
-67
src/cli_protocol/cli_protocol.c
src/cli_protocol/cli_protocol.c
+63
-53
src/cli_protocol/cli_protocol.h
src/cli_protocol/cli_protocol.h
+3
-7
src/cli_protocol/cli_protocol_cfg.h
src/cli_protocol/cli_protocol_cfg.h
+2
-7
No files found.
src/cli_protocol/cli_protocol.c
View file @
cc944181
...
@@ -10,7 +10,6 @@
...
@@ -10,7 +10,6 @@
//!
//!
//! Расширение протокола: новые команды регистрируются через cli_register_command().
//! Расширение протокола: новые команды регистрируются через cli_register_command().
//!
//!
//! Таймаут соединения: 20 секунд бездействия.
//! Максимальный размер поля данных: 64 байта.
//! Максимальный размер поля данных: 64 байта.
//!
//!
//! @note Для работы необходимо наличие LMCAL, ring_buffer, а также tsp_dev_info из модуля tcp.h.
//! @note Для работы необходимо наличие LMCAL, ring_buffer, а также tsp_dev_info из модуля tcp.h.
...
@@ -37,8 +36,8 @@
...
@@ -37,8 +36,8 @@
// Макрос для преобразования ASCII HEX-символа в 4-битное значение (0-15), 0xFF при ошибке
// Макрос для преобразования ASCII HEX-символа в 4-битное значение (0-15), 0xFF при ошибке
#define HEX_CHAR_TO_NIBBLE(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
#define HEX_CHAR_TO_NIBBLE(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : \
((c) >= 'A' && (c) <= 'F') ? ((c) - 'A' + 10) : \
((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : 0xFF)
((c) >= 'a' && (c) <= 'f') ? ((c) - 'a' + 10) : 0xFF)
//************************************ Локальные переменные *************************************************
//************************************ Локальные переменные *************************************************
static
ringbuf_t
fifo_rx
;
// Кольцевой буфер приёма байт из UART
static
ringbuf_t
fifo_rx
;
// Кольцевой буфер приёма байт из UART
...
@@ -127,22 +126,16 @@ void cli_send_string(const char* str)
...
@@ -127,22 +126,16 @@ void cli_send_string(const char* str)
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
static
void
uart_wait_tx_done
(
void
)
static
void
uart_wait_tx_done
(
void
)
{
{
// Попытка использовать функцию LMCAL, если она доступна
#if CLI_UART_CHANNEL == LMCAL_UART_CHANNEL0
#ifdef LMCAL_UART_TX_COMPLETE
#define CLI_USART USART5
uint32_t
timeout
=
100000
;
// ~100 мс при типичной скорости
#elif CLI_UART_CHANNEL == LMCAL_UART_CHANNEL1
while
(
!
lmcal_uart_tx_complete
(
CLI_UART_CHANNEL
)
&&
--
timeout
);
#define CLI_USART USART0
#else
#else
// Резервный вариант с прямым доступом к регистрам (для GD32)
#define CLI_USART USART0
#if CLI_UART_CHANNEL == LMCAL_UART_CHANNEL0
#define CLI_USART USART5
#elif CLI_UART_CHANNEL == LMCAL_UART_CHANNEL1
#define CLI_USART USART0
#else
#define CLI_USART USART0
#endif
volatile
uint32_t
timeout
=
100000
;
while
(
usart_flag_get
(
CLI_USART
,
USART_FLAG_TC
)
==
RESET
&&
--
timeout
);
#endif
#endif
volatile
u32
timeout
=
100000
;
while
(
usart_flag_get
(
CLI_USART
,
USART_FLAG_TC
)
==
RESET
&&
--
timeout
);
}
}
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
...
@@ -193,27 +186,19 @@ static void send_error(u8 cmd, u8 err)
...
@@ -193,27 +186,19 @@ static void send_error(u8 cmd, u8 err)
static
void
handle_cmd_open
(
const
u8
*
data
,
u8
len
)
static
void
handle_cmd_open
(
const
u8
*
data
,
u8
len
)
{
{
(
void
)
len
;
(
void
)
len
;
// Проверяем, не открыто ли уже соединение
if
(
cli_connected
)
{
if
(
cli_connected
)
{
send_error
(
CLI_CMD_OPEN
,
CLI_ERR_INTERNAL
);
send_error
(
CLI_CMD_OPEN
,
CLI_ERR_INTERNAL
);
return
;
return
;
}
}
// Проверка пароля, если он задан
if
(
len
!=
cli_password_len
||
memcmp
(
data
,
cli_password
,
len
)
!=
0
)
{
if
(
cli_password_len
>
0
)
{
send_error
(
CLI_CMD_OPEN
,
CLI_ERR_INTERNAL
);
if
(
len
!=
cli_password_len
||
memcmp
(
data
,
cli_password
,
len
)
!=
0
)
{
return
;
// Неверный пароль - возвращаем ошибку "неизвестная команда"
send_error
(
CLI_CMD_OPEN
,
CLI_ERR_UNKNOWN_CMD
);
return
;
}
}
}
// Пароль верен или не требуется
cli_connected
=
true
;
cli_connected
=
true
;
if
(
cli_get_tick
)
{
if
(
cli_get_tick
)
cli_last_activity
=
cli_get_tick
();
cli_last_activity
=
cli_get_tick
();
}
send_response
(
CLI_CMD_OPEN
,
NULL
,
0
);
send_response
(
CLI_CMD_OPEN
,
NULL
,
0
);
}
}
...
@@ -298,21 +283,30 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
...
@@ -298,21 +283,30 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INVALID_ARG
);
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INVALID_ARG
);
return
;
return
;
}
}
u32
addr
=
0
;
u32
addr
=
0
;
for
(
u8
i
=
0
;
i
<
4
;
i
++
)
addr
=
(
addr
<<
8
)
|
data
[
i
];
for
(
u8
i
=
0
;
i
<
4
;
i
++
)
addr
=
(
addr
<<
8
)
|
data
[
i
];
u8
size
=
data
[
4
];
u8
size
=
data
[
4
];
if
(
size
==
0
||
size
>
CLI_DATA_MAX_SIZE
)
{
if
(
size
==
0
||
size
>
CLI_DATA_MAX_SIZE
)
{
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INVALID_ARG
);
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INVALID_ARG
);
return
;
return
;
}
}
// Проверка допустимых диапазонов с учётом размера
// Проверка на переполнение адреса
u32
end_addr
=
addr
+
size
;
if
(
end_addr
<
addr
)
{
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INTERNAL
);
return
;
}
// Проверка допустимых диапазонов (GD32F450: Flash 2MB, SRAM 192KB)
bool
valid
=
false
;
bool
valid
=
false
;
// Flash: 1 МБ (0x08000000 - 0x080FFFFF) – типично для GD32F450VG
if
((
addr
>=
0x08000000
)
&&
(
(
addr
+
size
)
<=
0x080
FFFFF
))
{
if
((
addr
>=
0x08000000
)
&&
(
end_addr
<=
0x081
FFFFF
))
{
valid
=
true
;
valid
=
true
;
// Flash (банк 0 + банк 1 = 2 МБ)
}
else
if
((
addr
>=
0x20000000
)
&&
(
(
addr
+
size
)
<=
0x2001
FFFF
))
{
}
else
if
((
addr
>=
0x20000000
)
&&
(
end_addr
<=
0x2002
FFFF
))
{
valid
=
true
;
// SRAM (1
28
КБ)
valid
=
true
;
// SRAM (1
92
КБ)
}
}
if
(
valid
)
{
if
(
valid
)
{
...
@@ -322,6 +316,7 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
...
@@ -322,6 +316,7 @@ static void handle_cmd_read_mem(const u8* data, u8 len)
}
}
send_response
(
CLI_CMD_READ_MEM
,
buf
,
size
);
send_response
(
CLI_CMD_READ_MEM
,
buf
,
size
);
}
else
{
}
else
{
printf
(
"READ_MEM error: addr=0x%08X, size=%d, end=0x%08X
\n
"
,
addr
,
size
,
end_addr
);
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INTERNAL
);
send_error
(
CLI_CMD_READ_MEM
,
CLI_ERR_INTERNAL
);
}
}
}
}
...
@@ -341,21 +336,31 @@ static void handle_cmd_write_mem(const u8* data, u8 len)
...
@@ -341,21 +336,31 @@ static void handle_cmd_write_mem(const u8* data, u8 len)
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INVALID_ARG
);
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INVALID_ARG
);
return
;
return
;
}
}
u32
addr
=
0
;
u32
addr
=
0
;
for
(
u8
i
=
0
;
i
<
4
;
i
++
)
addr
=
(
addr
<<
8
)
|
data
[
i
];
for
(
u8
i
=
0
;
i
<
4
;
i
++
)
addr
=
(
addr
<<
8
)
|
data
[
i
];
u8
size
=
len
-
4
;
u8
size
=
len
-
4
;
if
(
size
>
CLI_DATA_MAX_SIZE
)
{
if
(
size
>
CLI_DATA_MAX_SIZE
)
{
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INVALID_ARG
);
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INVALID_ARG
);
return
;
return
;
}
}
// Проверка: только SRAM с учётом размера
// Проверка на переполнение
if
((
addr
>=
0x20000000
)
&&
((
addr
+
size
)
<=
0x2001FFFF
))
{
u32
end_addr
=
addr
+
size
;
if
(
end_addr
<
addr
)
{
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INTERNAL
);
return
;
}
// Запись разрешена только в SRAM
if
((
addr
>=
0x20000000
)
&&
(
end_addr
<=
0x2002FFFF
))
{
for
(
u8
i
=
0
;
i
<
size
;
i
++
)
{
for
(
u8
i
=
0
;
i
<
size
;
i
++
)
{
*
(
volatile
u8
*
)(
addr
+
i
)
=
data
[
4
+
i
];
*
(
volatile
u8
*
)(
addr
+
i
)
=
data
[
4
+
i
];
}
}
send_response
(
CLI_CMD_WRITE_MEM
,
NULL
,
0
);
send_response
(
CLI_CMD_WRITE_MEM
,
NULL
,
0
);
}
else
{
}
else
{
printf
(
"WRITE_MEM error: addr=0x%08X, size=%d, end=0x%08X
\n
"
,
addr
,
size
,
end_addr
);
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INTERNAL
);
send_error
(
CLI_CMD_WRITE_MEM
,
CLI_ERR_INTERNAL
);
}
}
}
}
...
@@ -457,16 +462,16 @@ fun_res_t cli_protocol_init(void)
...
@@ -457,16 +462,16 @@ fun_res_t cli_protocol_init(void)
const
u8
default_pass
[]
=
CLI_DEFAULT_PASSWORD_BYTES
;
const
u8
default_pass
[]
=
CLI_DEFAULT_PASSWORD_BYTES
;
cli_protocol_set_password
(
default_pass
,
sizeof
(
default_pass
));
cli_protocol_set_password
(
default_pass
,
sizeof
(
default_pass
));
cli_send_string
(
"
\r\n
------ LTA PROTOCOL ENABLED -----
\r\n
"
);
cli_send_string
(
"
\r\n
********** LTA PROTOCOL ENABLED **********
\r\n
"
);
cli_send_string
(
"
- T0001 - open without password
\r\n
"
);
cli_send_string
(
"
|> T000131333537 - open with password '1357' (hex bytes 0x31,0x33,0x35,0x37)
\r\n
"
);
cli_send_string
(
"
- T000131333537 - open with password '1357' (hex bytes 0x31,0x33,0x35,0x37)
\r\n
"
);
cli_send_string
(
"
|> T0101 - close connection
\r\n
"
);
cli_send_string
(
"
- T0101 - close connection
\r\n
"
);
cli_send_string
(
"
|> T0201AABB - ping with data 0xAA,0xBB
\r\n
"
);
cli_send_string
(
"
- T0201AABB - ping with data 0xAA,0xBB
\r\n
"
);
cli_send_string
(
"
|> T0A01 - get device info
\r\n
"
);
cli_send_string
(
"
- T0A01 - get device info
\r\n
"
);
cli_send_string
(
"
|> T14010800000004 - read 4 bytes from 0x08000000
\r\n
"
);
cli_send_string
(
"
- T14010800000004 - read 4 bytes from 0x08
000000
\r\n
"
);
cli_send_string
(
"
|> T14012000000004 - read 4 bytes from 0x20
000000
\r\n
"
);
cli_send_string
(
"
- T150120000000AABB
- write 0xAA,0xBB to SRAM 0x20000000
\r\n
"
);
cli_send_string
(
"
|> T150120000000AABB
- write 0xAA,0xBB to SRAM 0x20000000
\r\n
"
);
cli_send_string
(
"
--------------------------------------------------
\r\n
"
);
cli_send_string
(
"
******************************************************
\r\n
"
);
cli_send_string
(
"> "
);
cli_send_string
(
"
|
> "
);
return
ERR_OK
;
return
ERR_OK
;
}
}
...
@@ -498,14 +503,20 @@ void cli_protocol_process(void)
...
@@ -498,14 +503,20 @@ void cli_protocol_process(void)
cli_cmd_buffer
[
cli_cmd_index
++
]
=
ch
;
cli_cmd_buffer
[
cli_cmd_index
++
]
=
ch
;
state
=
RECEIVING
;
state
=
RECEIVING
;
break
;
break
;
case
RECEIVING
:
case
RECEIVING
:
if
(
ch
==
'\r'
||
ch
==
'\n'
)
{
if
(
ch
==
'\r'
||
ch
==
'\n'
)
{
while
(
cli_cmd_index
>
0
&&
(
cli_cmd_buffer
[
cli_cmd_index
-
1
]
==
' '
||
cli_cmd_buffer
[
cli_cmd_index
-
1
]
==
'\t'
))
{
cli_cmd_index
--
;
}
if
(
cli_cmd_index
>
0
)
{
if
(
cli_cmd_index
>
0
)
{
cli_cmd_buffer
[
cli_cmd_index
]
=
CLI_MSG_TERMINATOR
;
cli_cmd_buffer
[
cli_cmd_index
]
=
CLI_MSG_TERMINATOR
;
cli_cmd_index
++
;
cli_cmd_index
++
;
parse_and_execute
();
parse_and_execute
();
cli_send_string
(
"> "
);
cli_send_string
(
"
|
> "
);
}
}
state
=
EXPECT_NL
;
state
=
EXPECT_NL
;
}
else
{
}
else
{
...
@@ -517,7 +528,6 @@ void cli_protocol_process(void)
...
@@ -517,7 +528,6 @@ void cli_protocol_process(void)
}
}
}
}
break
;
break
;
case
EXPECT_NL
:
case
EXPECT_NL
:
if
(
ch
==
'\n'
)
{
if
(
ch
==
'\n'
)
{
state
=
WAIT_CMD
;
state
=
WAIT_CMD
;
...
@@ -530,7 +540,7 @@ void cli_protocol_process(void)
...
@@ -530,7 +540,7 @@ void cli_protocol_process(void)
}
}
}
}
// Таймаут соединения
// Таймаут соединения
(работает только если cli_get_tick != NULL)
if
(
cli_connected
&&
cli_get_tick
)
{
if
(
cli_connected
&&
cli_get_tick
)
{
if
((
cli_get_tick
()
-
cli_last_activity
)
>
CLI_CONNECTION_TIMEOUT_MS
)
{
if
((
cli_get_tick
()
-
cli_last_activity
)
>
CLI_CONNECTION_TIMEOUT_MS
)
{
cli_connected
=
false
;
cli_connected
=
false
;
...
...
src/cli_protocol/cli_protocol.h
View file @
cc944181
...
@@ -10,9 +10,9 @@
...
@@ -10,9 +10,9 @@
//************************************ Коды команд (по протоколу 1.1) *************************************
//************************************ Коды команд (по протоколу 1.1) *************************************
typedef
enum
{
typedef
enum
{
CLI_CMD_OPEN
=
0x00U
,
// T00 - открыть соединение (
опционально
с паролем)
CLI_CMD_OPEN
=
0x00U
,
// T00 - открыть соединение (с паролем)
CLI_CMD_CLOSE
=
0x01U
,
// T01 - закрыть соединение
CLI_CMD_CLOSE
=
0x01U
,
// T01 - закрыть соединение
CLI_CMD_PING
=
0x02U
,
// T02 - проверка соединения (ping)
– эхо переданных данных
CLI_CMD_PING
=
0x02U
,
// T02 - проверка соединения (ping)
CLI_CMD_GET_INFO
=
0x0AU
,
// T0A - получить информацию об устройстве (имя, серийный, версия)
CLI_CMD_GET_INFO
=
0x0AU
,
// T0A - получить информацию об устройстве (имя, серийный, версия)
CLI_CMD_READ_MEM
=
0x14U
,
// T14 - чтение памяти (адрес 4 байта + размер 1 байт)
CLI_CMD_READ_MEM
=
0x14U
,
// T14 - чтение памяти (адрес 4 байта + размер 1 байт)
CLI_CMD_WRITE_MEM
=
0x15U
,
// T15 - запись памяти (адрес 4 байта + данные, только SRAM)
CLI_CMD_WRITE_MEM
=
0x15U
,
// T15 - запись памяти (адрес 4 байта + данные, только SRAM)
...
@@ -102,10 +102,6 @@ void cli_protocol_set_password(const u8* pass, u8 len);
...
@@ -102,10 +102,6 @@ void cli_protocol_set_password(const u8* pass, u8 len);
//! @return true – пароль верен, false – неверен
//! @return true – пароль верен, false – неверен
bool
cli_protocol_verify_password
(
const
u8
*
pass
,
u8
len
);
bool
cli_protocol_verify_password
(
const
u8
*
pass
,
u8
len
);
//---------------------------------------------------------------------
//! @brief Сброс блокировки после превышения попыток ввода пароля
void
cli_protocol_reset_block
(
void
);
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//! @brief Регистрация новой команды
//! @brief Регистрация новой команды
//! @param cmd Указатель на структуру с кодом и обработчиком
//! @param cmd Указатель на структуру с кодом и обработчиком
...
@@ -114,4 +110,4 @@ void cli_protocol_reset_block(void);
...
@@ -114,4 +110,4 @@ void cli_protocol_reset_block(void);
fun_res_t
cli_register_command
(
const
cli_command_t
*
cmd
);
fun_res_t
cli_register_command
(
const
cli_command_t
*
cmd
);
#endif
#endif
\ No newline at end of file
\ No newline at end of file
src/cli_protocol/cli_protocol_cfg.h
View file @
cc944181
...
@@ -16,13 +16,8 @@
...
@@ -16,13 +16,8 @@
//************************************ Пароль по умолчанию **************************************************
//************************************ Пароль по умолчанию **************************************************
// Пароль по умолчанию "1357"
// Пароль по умолчанию "1357"
#define CLI_DEFAULT_PASSWORD_BYTES {0x31, 0x33, 0x35, 0x37}
#define CLI_DEFAULT_PASSWORD_BYTES {0x31, 0x33, 0x35, 0x37}
#define CLI_DEFAULT_PASSWORD_LEN 4
#define CLI_DEFAULT_PASSWORD_LEN 4
#define CLI_MAX_COMMANDS 256 // Максимальное количество регистрируемых команд (0x00..0xFF)
#define CLI_MAX_COMMANDS 256 // Максимальное количество регистрируемых команд (0x00..0xFF)
#define CLI_PASSWORD_MAX_LEN 15 // Максимальная длина пароля в байтах
#define CLI_PASSWORD_MAX_LEN 15 // Максимальная длина пароля в байтах
#define CLI_ACTIVITY_TIMEOUT_TICKS 20000U // ~20 сек при вызове каждые 1 мс
#endif
#endif
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment