• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос На каких языках можно написать прошивку

tolyan23

New member
На каких языках можно написать прошивку? Какие преимущества недостатки каждого
Что то я запутался SDK, LUA, eclipse luna. Куча новых непонятных слов. Где то встречал упоминание что lua глючный (нестабильный) зато прошивку быстро писать. Мне нужен максимально надежный (от производителя?) язык программирования/компилятор. Т.е. чтобы простая прошивка работала стабильно и надежно без глюков (я имею ввиду глюки вносимые компилятором).
Хочу сделать датчик wifi поэтому
программа минимум читать/устанавливать GIPO отправлять/принимать http запросы
(типа таких http://127.0.0.1:81/objects/?object=ws&op=m&m=refreshData&P=755&Tout=28)
программа максимум простая страничка настройки параметров
 

jmms

Moderator
Команда форума
Возможно вам подойдет https://github.com/marcoschwartz/aREST это скетч для ардуино ide, при помощи простых get запросов изменять состояние gpio.
Если в кратце (поверхностно) по вашему вопросу: nodemcu это прошивка, вы модете вгружать в устройство на базе этой прошивки скрипты на языке lua, но работает это относительно стабильно (нужно обладать серьезными навыками чтобы эти скрипты работали стабильно), но начать легко. Другой возможный вариант - писать скетчи на c++, используя arduino ide. Лично я выбрал этот вариант, писать на c++ чуть сложней, но работает стабильней.
 

gerkimuyda

New member
Решил темы не плодить. Так как в Си не разбираюсь, попробую задать вопрос на форуме:
Как в SDK вернуть из функции строку, чтобы можно было ее использовать как параметр, например в printf("%s", myfunc("text"));
1.Если вернуть указатель на локальную переменную - то локальная переменная уничтожается при выходе из функции.
2.Если локальную переменную сделать static - то второй вызов функции портит первый возврат. Например: printf("1=%s 2=%s", myfunc("text1"), myfunc("text2") ); - вернет "1=text2 2=text2"
3.Большинство вариантов возврата, которые мне попадались - используют переменную, которую передают в функцию, и потом ее возвращают или из нее забирают значение myfunc(*buf, "text"), но мне надо именно через return, без дополнительно передаваемых параметров *buf.
4. malloc - расходует память при каждом вызове и автоматически не освобождает ее.

При пункте 4 возникает интересный вопрос, зачем разработчики Mangoose написали такой код:
Код:
char *strdup(const char *src) {
  size_t len = strlen(src) + 1;
  char *ret = malloc(len);
  if (ret != NULL) {
    strcpy(ret, src);
  }
  return ret;
}
Ведь, как я понял, без free() память будет утекать? Или я не правильно что-то понял?

пс: может через asm push или внутреннюю функцию SDK можно окольными путями получить желаемое?
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@gerkimuyda передайте в функцию указатель на строку и внутри заполняйте строку по этому указателю. Потом вернёте его же, если надо.
 

gerkimuyda

New member
Получается №3 вариант, для которого надо заранее создать переменную, а я хочу избавиться от этих лишних телодвижений, реализовав все необходимое внутри функции (внутри библиотеки). И опять-же, при двойном вызове функции в рамках одного printf - мы получим вариант №2.
Чтобы было понятнее - любые вспомогательные действия должны остаться внутри создаваемой библиотеки (можно за пределами данной функции, которая является частью библиотеки), и за ее пределами нет надобности знать о [или помогать в] ее самодостаточной работоспособности.

И все-же интересен вопрос про MangooseOS - это их ошибка, которая положит систему, или я не правильно понял код и действия аллокатора памяти?
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@gerkimuyda тогда вам нужно пользоваться malloc и принудительно освобождать память когда переменная не нужна. Это Си, там всё ручками. Пример вы сами привели.
 

gerkimuyda

New member
Посмотрел, как делает возврат строки lwip_open_src_template_proj/lwip/core/sntp.c
(я имена функций изменил и код из них выкинул, оставив только используемый принцип)
Код:
char reult[100];

char * s3(char *str, char *result) {
  os_sprintf(result, "%s", str);
  return result;
}

char * s2(char *str) {
  return s3(str, reult);
}

char * s1(char *str) {
  return s2(str);
}

ets_uart_printf("%s", s1("text");
Данный способ такой же, как и №2, хотя менее удобный.
Т.е. в таком случае проще написать:

Код:
char * myfunc(char * str) {
  static char st[100];
  os_sprintf(st, "%s", str);
  return st;
}
Память тут выделяется один раз во время первого использования функции, но двойной вызов функции надо разделять, т.к. вторая перезапишет возврат первой (ведь они обе ссылают свой результат на один и тотже кусок памяти)
ets_uart_printf("1=%s 2=%s", myfunc("text1"), myfunc("test2") ); //выдаст '1=test2 2=text2'

А про MangooseOS кто-то объяснит, зачем они каждый раз откусывают кусок памяти и не возвращают его? Отложенный "синий экран смерти" ?
 
Последнее редактирование:
Сверху Снизу