Нас часто спрашивают, чем Embox отличается от других ОС для микроконтроллеров, например, FreeRTOS? Сравнивать проекты между собой, конечно, правильно. Но параметры, по которым порой предлагают сравнение, лично меня повергают в легкое недоумение. Например, сколько нужно памяти для работы Embox? А какое время переключения между задачами? А в Embox поддерживается modbus? В данной статье на примере вопроса про modbus мы хотим показать, что отличием Embox является другой подход к процессу разработки.
Давайте разработаем устройство, в составе которого будет работать в том числе modbus server. Наше устройство будет простым. Ведь оно предназначено только для демонстрации modbus, Данное устройство будет позволять управлять светодиодами по протоколу Modbus. Для связи с устройством будем использовать ethernet соединение.
Modbus открытый коммуникационный протокол. Широко применяется в промышленности для организации связи между электронными устройствами. Может использоваться для передачи данных через последовательные линии связи RS-485, RS-422, RS-232 и сети TCP/IP (Modbus TCP).
Протокол modbus достаточно простой чтобы реализовать его самостоятельно. Но поскольку любая новая реализация функциональности может содержать ошибки, давайте используем что-нибудь готовое.
Одной из самых популярных реализаций протокола modbus является открытый проект libmodbus. Его и будем использовать. Это позволит сократить время разработки и уменьшить количество ошибок. При этом мы сможем сосредоточиться на реализации бизнес логики, а не на изучении протокола.
Наш проект будем вести в отдельном репозитории. При желании все можно скачать и воспроизвести самостоятельно.
Разработка прототипа на Linux
Начнем с разработки прототипа на хосте. Для того чтобы можно было использовать libmodbus в качестве библиотеки его нужно скачать, сконфигурировать и собрать.
Для этих целей я набросал Makefile
libmodbus-$(LIBMODBUS_VER).tar.gz:
wget http://libmodbus.org/releases/libmodbus-$(LIBMODBUS_VER).tar.gz
$(BUILD_BASE)/libmodbus/lib/pkgconfig/libmodbus.pc : libmodbus-$(LIBMODBUS_VER).tar.gz
tar -xf libmodbus-$(LIBMODBUS_VER).tar.gz
cd libmodbus-$(LIBMODBUS_VER); ./configure --prefix=$(BUILD_BASE)/libmodbus --enable-static --disable-shared; make install; cd ..;
Собственно из параметров конфигурации мы используем только prefix чтобы собрать библиотеку локально. А поскольку мы хотим использовать библиотеку не только на хосте, соберем ее статическую версию.
Теперь нам нужен modbus сервер. В проекте libmodbus есть примеры, давайте на основе какого-нибудь простого сервера сделаем свою реализацию.
ctx = modbus_new_tcp(ip, port);
header_len = modbus_get_header_length(ctx);
query = malloc(MODBUS_TCP_MAX_ADU_LENGTH);
modbus_set_debug(ctx, TRUE);
mb_mapping = mb_mapping_wrapper_new();
if (mb_mapping == NULL) {
fprintf(stderr, "Failed to allocate the mapping: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
listen_socket = modbus_tcp_listen(ctx, 1);
for (;;) {
client_socket = modbus_tcp_accept(ctx, &listen_socket);
if (-1 == client_socket) {
break;
}
for (;;) {
int query_len;
query_len = modbus_receive(ctx, query);
if (-1 == query_len) {
/* Connection closed by the client or error */
break;
}
if (query[header_len - 1] != MODBUS_TCP_SLAVE) {
continue;
}
mb_mapping_getstates(mb_mapping);
if (-1 == modbus_reply(ctx, query, query_len, mb_mapping)) {
break;
}
leddrv_updatestates(mb_mapping->tab_bits);
}
close(client_socket);
}
printf("exiting: %s\n", modbus_strerror(errno));
close(listen_socket);
mb_mapping_wrapper_free(mb_mapping);
free(query);
modbus_free(ctx);
Здесь все стандартно. Пара мест, которые представляют интерес, это функции mb_mapping_getstates и leddrv_updatestates. Это как раз функционал, который и реализует наше устройство.
static modbus_mapping_t *mb_mapping_wrapper_new(void) {
modbus_mapping_t *mb_mapping;
mb_mapping = modbus_mapping_new(LEDDRV_LED_N, 0, 0, 0);
return mb_mapping;
}
static void mb_mapping_wrapper_free(modbus_mapping_t *mb_mapping) {
modbus_mapping_free(mb_mapping);
}
static void mb_mapping_getstates(modbus_mapping_t *mb_mapping) {
int i;
leddrv_getstates(mb_mapping->tab_bits);
for (i = 0; i < mb_mapping->nb_bits; i++) {
mb_mapping->tab_bits[i] = mb_mapping->tab_bits[i] ? ON : OFF;
}
}
Таким образом, нам нужны leddrv_updatestates, которая задает состояние светодиодов, и leddrv_getstates, которая получает состояние светодиодов.
static unsigned char leddrv_leds_state[LEDDRV_LED_N];
int leddrv_init(void) {
static int inited = 0;
if (inited) {
return 0;
}
inited = 1;
leddrv_ll_init();
leddrv_load_state(leddrv_leds_state);
leddrv_ll_update(leddrv_leds_state);
return 0;
}
...
int leddrv_getstates(unsigned char leds_state[LEDDRV_LED_N]) {
memcpy(leds_state, leddrv_leds_state, sizeof(leddrv_leds_state));
return 0;
}
int leddrv_updatestates(unsigned char new_leds_state[LEDDRV_LED_N]) {
memcpy(leddrv_leds_state, new_leds_state, sizeof(leddrv_leds_state));
leddrv_ll_update(leddrv_leds_state);
return 0;
}
Так как мы хотим чтобы наше ПО работало и на плате и на хосте, нам понадобятся разные реализации функций установки и получения состояния светодиодов. Давайте для хоста хранить состояние в обычном файле. Это позволит получать состояние светодиодов в других процессах.
Например, если мы захотим проверить состояния через вебсайт мы запустим вебсайт и укажем в качестве источника данных этот файл.
void leddrv_ll_update(unsigned char leds_state[LEDDRV_LED_N]) {
int i;
int idx;
char buff[LEDDRV_LED_N * 2];
for (i = 0; i < LEDDRV_LED_N; i++) {
char state = !!leds_state[i];
fprintf(stderr, "led(%03d)=%d\n", i, state);
buff[i * 2] = state + '0';
buff[i * 2 + 1] = ',';
}
idx = open(LED_FILE_NAME, O_RDWR);
if (idx < 0) {
return;
}
write(idx, buff, (LEDDRV_LED_N * 2) - 1);
close(idx);
}
...
void leddrv_load_state(unsigned char leds_state[LEDDRV_LED_N]) {
int i;
int idx;
char buff[LEDDRV_LED_N * 2];
idx = open(LED_FILE_NAME, O_RDWR);
if (idx < 0) {
return;
}
read(idx, buff, (LEDDRV_LED_N * 2));
close(idx);
for (i = 0; i < LEDDRV_LED_N; i++) {
leds_state[i] = buff[i * 2] - '0';
}
}
Нам нужно указать файл где будет сохранено начальное состояние светодиодов. Формат файла простой. Через запятую перечисляются состояние светодиодов, 1 — светодиод включен, а 0 -выключен. В нашем устройстве 80 светодиодов, точнее 40 пар светодиодов. Давайте предположим, что по умолчанию четные светодиоды будут выключены а нечетные включены. Содержимое файла
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1
Запускаем сервер
./led-server
led(000)=0
led(001)=1
...
led(078)=0
led(079)=1
Теперь нам нужен клиент для управления нашим устройством. Его тоже очень просто разрабатываем на базе примера из libmodbus
ctx = modbus_new_tcp(ip, port);
if (ctx == NULL) {
fprintf(stderr, "Unable to allocate libmodbus context\n");
return -1;
}
modbus_set_debug(ctx, TRUE);
modbus_set_error_recovery(ctx,
MODBUS_ERROR_RECOVERY_LINK |
MODBUS_ERROR_RECOVERY_PROTOCOL);
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n",
modbus_strerror(errno));
modbus_free(ctx);
return -1;
}
if (1 == modbus_write_bit(ctx, bit_n, bit_value)) {
printf("OK\n");
} else {
printf("FAILED\n");
}
/* Close the connection */
modbus_close(ctx);
modbus_free(ctx);
Запускаем клиент. Установим 78 светодиод, который по умолчанию выключен
./led-client set 78
Connecting to 127.0.0.1:1502
[00][01][00][00][00][06][FF][05][00][4E][FF][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4E><FF><00>
OK
На сервере увидим:
...
led(076)=0
led(077)=1
led(078)=1
led(079)=1
Waiting for an indication...
ERROR Connection reset by peer: read
То есть светодиод установлен. Давайте выключим его.
./led-client clr 78
Connecting to 127.0.0.1:1502
[00][01][00][00][00][06][FF][05][00][4E][00][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4E><00><00>
OK
На сервере увидим сообщение об изменении:
...
led(076)=0
led(077)=1
led(078)=0
led(079)=1
Waiting for an indication...
ERROR Connection reset by peer: read
Запустим http сервер. О разработке веб-сайтов мы рассказывали в статье. К тому же веб-сайт нам нужен только для более удобной демонстрации работы modbus. Поэтому не буду сильно вдаваться в подробности. Сразу приведу cgi скрипт:
#!/bin/bash
echo -ne "HTTP/1.1 200 OK\r\n"
echo -ne "Content-Type: application/json\r\n"
echo -ne "Connection: close\r\n"
echo -ne "\r\n"
if [ $REQUEST_METHOD = "GET" ]; then
echo "Query: $QUERY_STRING" >&2
case "$QUERY_STRING" in
"c=led_driver&a1=serialize_states")
echo [ $(cat ../emulate/conf/leds.txt) ]
;;
"c=led_driver&a1=serialize_errors")
echo [ $(printf "0, %.0s" {1..79}) 1 ]
;;
"c=led_names&a1=serialize")
echo '[ "one", "two", "WWWWWWWWWWWWWWWW", "W W W W W W W W " ]'
;;
esac
elif [ $REQUEST_METHOD = "POST" ]; then
read -n $CONTENT_LENGTH POST_DATA
echo "Posted: $POST_DATA" >&2
fi
И напомню что запустить можно с помощью любого http сервера с поддержкой CGI. Мы используем встроенный в python сервер. Запускаем следующей командой:
python3 -m http.server --cgi -d .
Откроем наш сайт в браузере:
Установим 78 светодиод с помощью клиента:
./led-client -a 127.0.0.1 set 78
Connecting to 127.0.0.1:1502
[00][01][00][00][00][06][FF][05][00][4E][FF][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4E><FF><00>
OK
сбросим 79 светодиод:
./led-client -a 127.0.0.1 clr 79
Connecting to 127.0.0.1:1502
[00][01][00][00][00][06][FF][05][00][4F][00][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4F><00><00>
OK
На сайте увидим разницу:
Собственно все, на Linux наша библиотека прекрасно работает.
Адаптация к Embox и запуск на эмуляторе
Библиотека libmodbus
Теперь нам нужно перенести код в Embox. начнем с самого проекта libmodbus.
Все просто. Нам нужно описание модуля (Mybuild):
package third_party.lib
@Build(script="$(EXTERNAL_MAKE)")
@BuildArtifactPath(cppflags="-I$(ROOT_DIR)/build/extbld/third_party/lib/libmodbus/install/include/modbus")
module libmodbus {
@AddPrefix("^BUILD/extbld/^MOD_PATH/install/lib")
source "libmodbus.a"
@NoRuntime depends embox.compat.posix.util.nanosleep
}
Мы с помощью аннотации Build(script="$(EXTERNAL_MAKE)") указываем что используем Makefile для работы с внешними проектами.
С помощью аннотации BuildArtifactPath добавляем пути для поиска заголовочных файлов к тем модулям, которые будут зависеть от этой библиотеки.
И говорим что нам нужна библиотека source «libmodbus.a»
PKG_NAME := libmodbus
PKG_VER := 3.1.6
PKG_SOURCES := http://libmodbus.org/releases/$(PKG_NAME)-$(PKG_VER).tar.gz
PKG_MD5 := 15c84c1f7fb49502b3efaaa668cfd25e
PKG_PATCHES := accept4_disable.patch
include $(EXTBLD_LIB)
libmodbus_cflags = -UHAVE_ACCEPT4
$(CONFIGURE) :
export EMBOX_GCC_LINK=full; cd $(PKG_SOURCE_DIR) && ( CC=$(EMBOX_GCC) ./configure --host=$(AUTOCONF_TARGET_TRIPLET) prefix=$(PKG_INSTALL_DIR) CFLAGS=$(libmodbus_cflags) )
touch $@
$(BUILD) :
cd $(PKG_SOURCE_DIR) && ( $(MAKE) install MAKEFLAGS='$(EMBOX_IMPORTED_MAKEFLAGS)'; )
touch $@
Makefile для сборки тоже простой и очевидный. Единственное, отмечу что используем внутренний компилятор ($(EMBOX_GCC) ) Embox и в качестве платформы (--host) передаем ту, которая задана в Embox ($(AUTOCONF_TARGET_TRIPLET)).
Подключаем проект к Embox
Напомню, что для удобства разработки мы создали отдельный репозиторий. Для того чтобы подключить его к Embox достаточно указать Embox где лежит внешний проект.
Делается это с помощью команды
make ext_conf EXT_PROJECT_PATH=<path to project>
в корне Embox. Например,
make ext_conf EXT_PROJECT_PATH=~/git/embox_project_modbus_iocontrol
modbus-server
Исходный код modbus сервера не требует изменений. То есть мы используем тот же код, который разработали на хосте. Нам нужно добавить Mybuild:
package iocontrol.modbus.cmd
@AutoCmd
@Build(script="true")
@BuildDepends(third_party.lib.libmodbus)
@Cmd(name="modbus_server")
module modbus_server {
source "modbus_server.c"
@NoRuntime depends third_party.lib.libmodbus
}
В котором с помощью аннотаций мы укажем что это у нас команда, а также что она зависит от библиотеки libmodbus.
Нам также понадобятся библиотеки эмуляции. Не буду приводить Mybuild для них, они тривиальны, лишь отмечу, что исходники также используются без изменений.
Нам также нужно собрать нашу систему вместе с modbus сервером.
Добавляем наши модули в mods.conf:
include iocontrol.modbus.http_admin
include iocontrol.modbus.cmd.flash_settings
include iocontrol.modbus.cmd.led_names
include third_party.lib.libmodbus
include iocontrol.modbus.cmd.modbus_server
include iocontrol.modbus.cmd.led_driver
include embox.service.cgi_cmd_wrapper(cmds_check=true, allowed_cmds="led_driver led_names flash_settings")
include iocontrol.modbus.lib.libleddrv_ll_stub
А наш файл leds.txt со статусами светодиодов кладем в корневую файловую систему. Но так как нам нужен изменяемый файл, давайте добавим RAM disk и скопируем наш файл на этот диск. Содержимое system_start.inc:
"export PWD=/",
"export HOME=/",
"netmanager",
"service telnetd",
"service httpd http_admin",
"ntpdate 0.europe.pool.ntp.org",
"mkdir -v /conf",
"mount -t ramfs /dev/static_ramdisk /conf",
"cp leds.txt /conf/leds.txt",
"led_driver init",
"service modbus_server",
"tish",
Этого достаточно запустим Embox на qemu:
./scripts/qemu/auto_qemu
modbus и httpd сервера запускаются автоматически при старте. Установим такие же значения с помощью modbus клиента, только указав адрес нашего QEMU (10.0.2.16):
./led-client -a 10.0.2.16 set 78
Connecting to 10.0.2.16:1502
[00][01][00][00][00][06][FF][05][00][4E][FF][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4E><FF><00>
OK
и соответственно
./led-client -a 10.0.2.16 clr 79
Connecting to 10.0.2.16:1502
[00][01][00][00][00][06][FF][05][00][4F][00][00]
Waiting for a confirmation...
<00><01><00><00><00><06><FF><05><00><4F><00><00>
Откроем браузер:
Как и ожидалось все тоже самое. Мы можем управлять устройством через modbus протокол уже на Embox.
Запуск на микроконтроллере
Для запуска на микроконтроллере будем использовать STM32F4-discovery. На вышеприведенных скриншотах страниц браузера, видно что используется 80 ног вывода, объединенные в пары, и еще можно заметить что у этих пар есть другие свойства, например можно задать имя, или пара может подсвечиваться. На самом деле, код был взят из реального проекта и из него для упрощения были убраны лишние части. 80 выходных пинов было получено с помощью дополнительных микросхем сдвиговых регистров.
Но на плате STM32F4-discovery всего 4 светодиода. Было бы удобно задавать количество светодиодов, чтобы не модифицировать исходный код В Embox есть механизм позволяющий параметризировать модули. Нужно в описании модуля (Mybuild) добавить опцию
package iocontrol.modbus.lib
static module libleddrv {
option number leds_quantity = 80
...
}
И можно будет использовать в коде
#ifdef __EMBOX__
#include <framework/mod/options.h>
#include <module/iocontrol/modbus/lib/libleddrv.h>
#define LEDDRV_LED_N OPTION_MODULE_GET(iocontrol__modbus__lib__libleddrv,NUMBER,leds_quantity)
#else
#define LEDDRV_LED_N 80
#endif
При этом менять этот параметр можно будет указав его в файле mods.conf
include iocontrol.modbus.lib.libleddrv(leds_quantity=4)
если параметр не указывается, то используется тот который задан в модуле по умолчанию, то есть 80.
Нам нужно еще управлять реальными линиями вывода. Код следующий:
struct leddrv_pin_desc {
int gpio; /**< port */
int pin; /**< pin mask */
};
static const struct leddrv_pin_desc leds[] = {
#include <leds_config.inc>
};
void leddrv_ll_init(void) {
int i;
for (i = 0; i < LEDDRV_LED_N; i++) {
gpio_setup_mode(leds[i].gpio, leds[i].pin, GPIO_MODE_OUTPUT);
}
}
void leddrv_ll_update(unsigned char leds_state[LEDDRV_LED_N]) {
int i;
for (i = 0; i < LEDDRV_LED_N; i++) {
gpio_set(leds[i].gpio, leds[i].pin,
leds_state[i] ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
}
}
В файле mods.conf нам нужна конфигурация для нашей платы. К ней добавляем наши модули:
include iocontrol.modbus.http_admin
include iocontrol.modbus.cmd.flash_settings
include iocontrol.modbus.cmd.led_names
include third_party.lib.libmodbus
include iocontrol.modbus.cmd.modbus_server
include iocontrol.modbus.cmd.led_driver
include embox.service.cgi_cmd_wrapper(cmds_check=true, allowed_cmds="led_driver led_names flash_settings")
include iocontrol.modbus.lib.libleddrv(leds_quantity=4)
include iocontrol.modbus.lib.libleddrv_ll_stm32_f4_demo
По сути дела, те же модули как и для ARM QEMU, за исключением конечно драйвера.
Собираем, прошиваем, запускаем. И с помощью того же modbus клиента управляем светодиодами. Нужно только поставить правильный адрес, и не забыть что у нас всего 4 светодиода на плате.
Работу на плате stm32f4-discovery можно увидеть на этом коротком видео:
Выводы
На этом простом примере мы постарались показать, в чем же основное отличие Embox от других ОС для микроконтроллеров. В том числе которые имеют POSIX совместимость. Ведь мы по сути дела, взяли готовый модуль, разработали бизнес логику на Linux используя при этом несколько приложений. И запустили все это на нашей целевой платформе. Тем самым существенно упростив и ускорив саму разработку.
Да, конечно, приложение демонстрационное и не сложное. Сам протокол modbus так же можно было бы реализовать самостоятельно. Но в этом случае нам нужно было бы разбираться в протоколе modbus. А наш подход позволяет сосредоточится каждому специалисту на своей части. Ну и конечно, большинство проблем решаются на хосте, что гораздо более удобно чем разрабатывать напрямую на плате.
Indemsys
Не понял все же в чем заключается упрощение.
Не хватает сравнения, как этот процесс мог бы выглядеть на другой RTOS.
abondarev Автор
Хм, ну тут сложно проводить сравнение. Ведь в случае с RTOS ами обычно просто делается новая библиотека под конкретную платформу, ну или берется уже написаная и самостоятельно прикручивается. При этом все обычно происходит на целевой платформе. В случае с Linux дистрибутивом берем и устанавливаем нужные пакеты. В случае с Linux в виде yocto project и аналогов, составляем рецепты которые компиляруют файловую систему в статике. Разрабатывать конечно можно на обычном хосте. Вот последний вариант иблизок к Embox. Но при этом конечно все ядро не нужно тащить и мы влезаем в несколько киллобайт. как написано встатье про EFM
Indemsys
Но почему разработка на Linux-е рассматривается как некое упрощение?
Фактически же делается двойная работа.
Сначала делается симуляция на линуксе и для этого делаются cgi скрипты ( которые тоже надо отлаживать), а потом все равно надо все отлаживать на целевой платформе.
Есть же STM32CubeMonitor, быстрый STLink, симуляторы прямо в IDE под STM и прочие средства делающие разработку и отладку на платформе STM быстрой и удобной.
abondarev Автор
Не понял где двойная работа? Запустили на хосте один раз, а на плате заработало. Чем сложнее функциональность тем больше выгода. Конечно если речь идет о мигании светодиодом, то выгода сомнительная. Но даже в этом урезанном примере, есть файловая система, сеть, потоки, веб сайт и так далее. При этом на плате вообще не отлаживалось ничего, просто запустилось!
Indemsys
Вот в это я и не верю.
Сколько раз я соединялся по modbus с промышленными контроллерами это всегда был челендж. 90% времени уходит на исследование проблем коммуникации.
Поскольку отсутствует исчерпывающая документация. О какой симуляции в линуксе может идти речь?
А если вы применили modbus для соединения одного своего дивайса с другим, то это исскуственный пример. Это история не про реальный modbus, а про то как сотворили оверхед. Т.е. по любому выполнили лишнюю работу.
Я даже не верю что линуксовые либы вообще можно использовать на STM32 без хитроумных рефакторингов, поскольку на STM самый дефицитный ресурс RAM, а в линуксе безоглядно используют heap. Да даже ограничения на стек заставляют стократно перепроверять все линуксовые сорсы чтобы не дай бог там не надумали делать массивы на стеке или списки со строками в автоматических переменных. Эт я еще не упомянул ретаргетинг С-ишных функций.
Тот же libmodbus вы должны были проверить на фрагментацию и исчерпание кучи, поскольку там вовсю используют malloc. Т.е. либо вы нам не рассказали о том как вы симмулируете фрагментацию на линуксе, либо вы не можете утвержадать что ваше приложение рабочее, поскольку не отлаживали его на целевой платформе.
Вот если в линуксовой либе специально указывают что она годная для embedded, то это другой разговор. Сам с удовольствием использую различные парсеры, интерпретаторы, протоколы из линукса. Но для этого не требуется сам линукс. Это лишний компонент.
abondarev Автор
Верить или не верить это личное право каждого человека!
Но не понимаю, что вас смущает? Вы например верите, что можете разработать ПО (с тем же libmodbus) на хосте (x86) и запустить на малине, без каких то изменений (пересобрать понятно прийдется)?
Может в этом проблема? Я не потрицаю что есть нюансы связанные с аппаратурой, но 90 % времени от всей задачи. Конечно не останется ни на какую бизнес логику.
Пример естественно упрощенный, для лучшего понимания самого процесса разработки. Но оврхеда, как и лишней работы, не вижу. Вижу что не пришлось разбираться в тонкостях modbus. Уверен что там есть тонкие места, которые потребуют времени и тщательного изучения вопроса. Ну да, еще естественно, остльное ПО, включая драйвера, которые имеют стандартный интерфейс, один раз разработал, потом используешь, нашел огибку правишь в общем месте.
Вот не пойму, о чем вы говорите. Посмотрите в нашем блоге, куча софта запущено на STM32 без изменений Первое же (https://habr.com/ru/company/embox/blog/538416/). Или посмотрите особенности запуска плюсовх приложений. Я к тому что это делается, не скажу что это легко, но Embox автоматизировал этот процесс и с ним это делать быстро и просто.
Опять к сожалению не понял. Вы имеете в виду проффелирование распределения памяти? Но это опять же гораздо легче делать со средствами на хосте. Смотрите уже упомянутую статью
То есть если в libmodbus появится надпись что можно запускать на STM32 с помощью Embox. Вы будете использовать Embox, или саму библиотеку?
В общем повторюсь, Ваше право использовать то что Вы считаете правильным! Мы лишь предлагаем подход. Попробовать его, использовать или нет, это ваше решение. Наш взгляд с немного другого ракурса. Для меня например, удивительно когда люди 90 % времени на разработку тратят на аппаратуру, на функционал, понятно остается очень мало времени.
Indemsys
Точно, если такая надпись будет, то это будет верный сигнал о возможности легкого переноса библиотеки на любую RTOS.
А пока вы не показали как на линуксе вычислили минимальный размер heap для этой библиотеки.
Да я вижу что вы немало времени провели над анализом расхода памяти в симуляциях под линуксом. Это говорит о том что проблему прекрасно понимаете и сорсы вы все таки дорабатываете. Либо вынуждены брать чипы с большим объемом памяти.
Но на целевой платформе эти тестовые прогоны в любом случае точнее. Поскольку они учитывают и расход памяти низкоуровневым слоем работы с периферией. Уж периферию то никак в линуксе просимулировать не удастся.
Конечно если вы эти статьи пишете для самого себя с целью само убеждения, то понять можно.
Но вроде как посыл был в утверждении превосходства вашего метода.
Так вот фактов превосходства представлено не было на мой взгляд.
abondarev Автор
Ну хотя бы проблему понимаю, троечку поставите ?:)
а где Вы видете что немало времени?
А это откуда Вы взяли?
С чего это вдруг? Точнее конечно, это правда если сравнивать x86 64 разряда и 32 битную версию, но если распределяется память одинакового размера, то вообще непонятно, откуда возьмется разница.
Не понял о чем все таки Вы. куча это куча, пулы в драйверах это пулы. То есть это принципиально разные памяти. В одном случае мы используем Линукс. Как я и сказал, там гораздо более развитые профайлеры и отладчики. Во втором случае, это уже относится к разработке драйверов и там нужен свой учет памяти. Например в Embox можно задать количество сетевых пакетов, которые будут выделяться из специального пула
С целью самоубеждения, я могу писать что угодно, но публиковать при этом не нужно :)
Все то Вам кажется, Вы во что то верите или не верите…
Не смущает что Вы видете где то какую то попытку и при этом говорите что не видете фактов этой попытки?
Так вот никакого превосходства нет, так же как и серебрянной пули. Все зависит от ситуации и задачи. В статье предложен не превосходный а отличный метод. Для каких то случаев он позволяет упростить разработку, для каких то нет. Для ваших задач (90% сложности аппаратная часть) сомневаюсь что наш подход следует применять. 90% сложности бизнес логика, вот тут следует подумать.
Indemsys
Контроль за кучей стоит делать сразу в приложении на целевой платформе.
Тогда не надо будет мучится в симуляторах под линуксом.
Мучится — это потому что такой процесс требует времени и создания симуляции реальных условий.
Опять же кучу лучше сделать единой для всего, и для драйверов периферии и для верхнего уровня, так буде более экономно.
Словом ну ничего не способствует портированию линуксовых библиотек на STM32.
Как косвенное доказательство — отсутствие таких библиотек в STM32Cube.
abondarev Автор
Где у нас симуляция для профилирования кучи? Не пойму кто вообще мущается? Мы на Линуксе, точно нет. Там все обычно, никаких мучений. Может Вы мучаетесь на целевой платформе? В это верю, там все гораздо сложнее.
что значит более экономично? А как на счет более надежно? А как на счет более быстро? А как, хотя все таки более экономично? То есть Вы устверждаете, что если в системе есть ряд объектов с известными свойствами (одного размера) то более экономично поместить их в общую кучу? Вы что то там говорили про фрагментируемость…
Ну и да никто не отменяет всякие нюансы по памяти, например кешируемость регионов см статью
Ну и да, добавим еще разные шины и памяти в микроконтроллерах, наличие DMA.
Embox вроде способствует, делая этот процесс значительно проще :)
Как прямое докозательство — наличие порта ucLinux
Как прямое доказательство — появление серии STM32MP1
Indemsys
Значительно проще все делает только значительное количество RAM.
Кстати я посмотрел ваш репозитарий проекта Embox.
Во-первых там черт ногу сломает, какая-то масса непонятных названий директорий сторонних опенсорсных проектов даже косвенно не намекающих зачем они нужны.
Во-вторых, действительно важные и мощные проекты типа SQLite, каких-то скриптовых движков, компрессоров и т.д. отлично портируются сразу на embedded платформу без линукса и симуляций.
То что действительно можно смело без привязки к аппаратуре симулировать — GUI. Для STM32 есть не менее 3-х прекрасных библиотек с которыми идут их демо платы, и они имеют адаптеры симуляции под Windows, но не под линукс. QT потрированный на STM32 по сравнению с ними мягко говоря бледнеет.
С другой стороны я не понял как можно компилировать библиотеку libmodbus под линукс и быть уверенным что она так же заработает на STM если у компиляторов разный retargeting
Как например выводить диагностические, отладочные, аварийные сообщения и куда?
Сколько они еще заберут стека, а сколько займут процессорного времени?
Вопросы риторические.
abondarev Автор
Не понял
по вашему мы каким то магическим образом увеличиваем объем памяти?
Или вы имеете в виду что на хосте памяти больше по этому и проще, такя и говорю, те вещи которые можно сделать на хосте, проще делать на хосте.
Зачем? Ну не нравится Вам идея, ну пройдите мимо. Зачем убеждать нас что мы не правы?
В том то и проблема, вопрос, зачем вы полезли туда, если хотели найти что то непонятное, то и нашли. Если бы вам было бы что то нужно, ну скажем, есть ПО под линукс, и вам нужно запустить его под микроконтроллер, или запустить в реалтайм окружении, или еще по каким то реальным задачам. Вы бы попытались найти то что нужно.
То есть Вы таки нашли, важные и нужные части? Почему Вы считаете, что какие то вещи нужны для embedded а какие то фигня, только загрязняющая репозиторий?
Что то есть сомнения на счет отлично портируются. В нашем то случае портировать не нужно,
./configure; make; make install
. Да, конечно это в том случае если есть возможность, если ПО написано так что требуется 16 мб стек, то наверное его не стоит запускать на МК, ну или действительно аддаптировать.Как Вы все таки непонятно выражаетесь.
Ну есть 3 библиотеки под STM, мы позволяем использовать lvgl nuklear, qt. То есть у разработчика увеличивается выбор. Но главное никакой симуляции, ничего не нужно портироватью Запускается под ЛИнукс, на QEMU (можно например ARM) и уходит 90 % проблемб остальные 10% да приходится отлаживать на плате. Но только 10 %. И повторюсь, если у вас задачи, заключающиеся в настройке аппаратуры, например опрос какого то датчика, то врядли вам нужна оптимизация работы. Берем ардуино и вперед.
В нашей жизни ни в чем нельзя быть уверенным. Речь о том что уверенности становится существенно больше.
Что значит куда? Они как в линуксе выводятся куда указывают stdin stdout stderr. Куда направите туда и выведется, можете зайти по телнету и запустить ваше приложение, вывод будет у вас в консоли.
Столько сколько написано…
так зачем вы их задаете?
Зачем вы тратите время на доказательство что наш подход ошибочен? Повторюсь ситуации могут быть разные, и если вам такой подход не улучшает жизнь, то не нужно на это тратить время
Indemsys
Понятно.
Т.е. вы сразу какое бы простенькое приложение ни было всегда неявно требуете наличие TCP стека, файловой системы и операционной системы.
Потому что все должно сработать как в линуксе.
Оверхед доказан?
Лезу я в ваш репозитарий потому что вы сами предлагаете в него лезть. Для чего тогда все эти статьи?
Ок, я залез. Там пусто. Предлагается видимо идти в места расположения оригинальных пакетов. Но все что есть для этого — это какие-то невнятные аббревиатуры, даже минимальных подсказок нет. Спрашивается зачем такое выкладывать и пиарить? Где демки на этих проектах, доказавающие работоспособность?
Скажем из тройки lvgl nuklear, qt достоин внимания только lvgl.
Но он одинаково трудно портируется что под линукс что под windows. Там надо писать драйвер и под Chrom-ART там конечно драйвера нет!
Т.е. отсутствие преимущества доказано?
Ну и не забывайте что эти коменты читает весь интернет.
От того как вы отвечаете зависит в какой-то мере успешность вашего пиара.
Я же просто хочу отделить рациональные вещи от чисто субъективных предпочтений.
По сути диалог и заходит в область сравнения (которого вашей статье так не хватает) что есть в линуксе для embedded и что есть в RTOS растущих от железа.
abondarev Автор
Что вам понятно. В каком месте что то доказано, о каком Оверхеде вы горорите? Подобными комментариями вы доказываете только что вообще не понимаете о чем говорите!
Как по вашему Embox запускается с 4кб RAM? См. статью, где там оверхед?
В который раз говорю, статьи не для вас, а для тех у кого возникают похожие проблемы и ситуации. И мы не предлагаем лезть в репозиторий, а не запрещаем. Да хотим чтобы использовали, но если вам не нужно, то зачем вы лезете куда не понимаете?
простите, а вы не того, будете мне говорить, что мне выкладывать а что нет?
Вашу ж мать, при чем тут пиар? Мы сделали что то, рассказали миру, не хотите не пользуйтесь.
А вот об этом вас никто не просил. Вы высказали мнение, что это не нужно, но из аргументов привели только, «я так не делаю». Даже не посмотрели, что ниже, ктото написал, что симулирует на Linux а потом переносит на FreeRTOS (без Embox). Кто то очень хорошо описал, что Linux не следит за временами и так далее.
То есть повторюсь, никто вас не приглашал арбитром или экзаминатором. Мир слегка многообразнее чем вам кажется. И если в вашей работе таких проблем нет, то не факт что их вообще нет.
И не вам решать кто достоин внимания а кто нет!