Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#include "commands.h" //здесь описан макрос REGISTER_COMMAND
REGISTER_COMMAND("command1_name", function_obrabotka1);
REGISTER_COMMAND("cmd2", func2);
ARRAY_SPREAD_DEF(const struct shell_cmd, __shell_cmds);
extern const struct shell_cmd __shell_cmds[];
ARRAY_SPREAD_ADD(__shell_cmds, {
.name = "foo",
.func = foo_func,
});
SECTIONS {
.rodata : {
*(SORT(.array_spread.*.rodata))
}
}
но в исходниках массив представляется именно Си-шным массивомА что вы здесь имели в виду? Что существует указатель по которому можно работать с распределённым массивом, как с обычным? Так это и у меня так.
extern const struct shell_cmd __shell_cmds[];
Вообще создаётся впечатление, что мы идём параллельными, но разными путями.Не без этого =)
SECTIONS {
.rodata : {
_start_secname = .;
*(.secname)
_stop_secname = .;
}
}
и при этом не занимают места, потому что это просто символы линкера, а не байты в памяти. Это позволяет ещё чуть-чуть уменьшить overhead.Указатели в нашем решении тоже не занимают байтов в памяти, это такие же символы, которые определяются через массивы нулевой длины.
@AutoCmd
@Cmd(name = "help", help = "Shows all available commands", man = '''...'''
module help {
source "help.c"
...
}
int main(int argc, char **argv) {
...
}
Перенесли из-за желания сделать команды максимально стандартными, тем самым уменьшив порог вхождения. Как бонус, получили возможность собирать команды из нашей ОС на unix хостах (без изменений), наоборот — тоже получается достаточно хорошо.Это понятно. Но, как я понимаю, относится к сигнатуре обработчика команд, а не к способу регистрации команд.
При добавлении новой команды нужно сообщать системе сборки о новом файле. Описание лежит рядом с исходником, как например Cat.my и cat.c.Вариант, если к каждому исходнику всё равно прилагается его описание для MyBuild. Иначе придётся плодить дополнительные файлы. Но даже в этом варианте добавление/удаление новой команды требует редактирования двух файлов.
забыть изменить мануал можно и в текущем файлеМожно, но если этот мануал у тебя идёт рядом с самой функцией, то глазами на него натыкаешься, когда код редактируешь. А вот если у тебя тело функции от мануала отстоит строк хотя бы на 30 — то легко забыть.
В отдаленных планах, кстати, есть отказ и от этого. То есть команда неотличима от обычного приложения с функцией main, а при сборке глобальные символы (в т.ч. main) манглятся, и команда регистрируется «как обычно».Перенесли из-за желания сделать команды максимально стандартными, тем самым уменьшив порог вхождения. Как бонус, получили возможность собирать команды из нашей ОС на unix хостах (без изменений), наоборот — тоже получается достаточно хорошо.Это понятно. Но, как я понимаю, относится к сигнатуре обработчика команд, а не к способу регистрации команд.
Но даже в этом варианте добавление/удаление новой команды требует редактирования двух файлов.Для нас это что-то вроде неизбежного зла. Любой модуль так и так требует этих двух файлов, да и забыть поправить справку к команде не такая уж беда.
REGISTER_COMMAND(«command1_name», function_obrabotka1);
REGISTER_COMMAND(«cmd2», func2);
Вариант, если к каждому исходнику всё равно прилагается его описание для MyBuild. Иначе придётся плодить дополнительные файлы. Но даже в этом варианте добавление/удаление новой команды требует редактирования двух файлов.
memcpy( menu[0].welcome_string, "Hello! Welcome to the test menu.\n", string_lengths[0] );
заменить на menu[0].welcome_string = "Hello! Welcome to the test menu.\n";
Или потом эти данные как-то изменяются?CLI можно взять из открытой кодовой базы zephyr project
zephyr\subsys\shell
или Nordic Semiconductor SDK
ncs\v2.0.1\zephyr\subsys\shell
У меня тоже есть пост про CLI(шку)
https://habr.com/ru/post/694408/
Command line interpreter на микроконтроллере своими руками