• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Не работают ets_printf и os_printf

Алексей.

Active member
при выводе форматных строк делает ошибки с выводом чисел
Смотреть без слёз нельзя ESP8266 Non-OS SDK API Reference


Prototype: os_printf(const char *s)
декларирована функция с одним аргументом, совсем не переменным числом, а с одним
Example: os_printf("SDK version: %s \n", system_get_sdk_version());
пример как бы уже с двумя
ничего удивительного что в коде масса ошибок, это традиция, ардуина-иде популяризирует это "изделие" тем самым обеспечивает определенный спрос на него, в ретейл такое вряд ли пройдет, а вот для "поиграть" сгодится.
 
Последнее редактирование:

valerivp

Member
всем спасибо!

проблема решается так:
Код:
#include "user_interface.h"

void setup() {
  Serial.begin(115200);
  Serial.println();
  uart_set_debug(UART0);
  os_printf("I'm os_printf\n");
}
 

Алексей.

Active member
valerivp, Объясните пожалуйста для чего Вы используете Serial.begin(115200); если и без него напрямую пользуетесь api из uart.h
uart_set_debug Вы согласны вызывать, а uart_init Вам вызывать не хочется?
Пусть в Serial.begin сначала заблокируется вывод лога и вызовет uart_init, а мы уж сами вывод лога разблокируем.
Очень странный подход.
 

valerivp

Member
valerivp, Объясните пожалуйста для чего Вы используете Serial.begin(115200); если и без него напрямую пользуетесь api из uart.h
uart_set_debug Вы согласны вызывать, а uart_init Вам вызывать не хочется?
Пусть в Serial.begin сначала заблокируется вывод лога и вызовется uart_init, а мы уж сами вывод лога разблокируем.
Очень странный подход.
Код:
Serial.begin()
я использую для:
  • установки скорости порта
  • прочей инициализации объекта Serial (потому что в своем проекте я использую Serial.print)

функция os_printf мне понадобилась исключительно для того, чтобы выводились отладочные сообщения SDK / Ардуино
 

Алексей.

Active member
В трех строках кода
void HardwareSerial::begin(unsigned long baud, SerialConfig config, SerialMode mode, uint8_t tx_pin)
{
if(uart_get_debug() == _uart_nr) {
uart_set_debug(UART_NO);
}
if (_uart) {
free(_uart);
}
_uart = uart_init(_uart_nr, baud, (int) config, (int) mode, tx_pin);
_peek_char = -1;
}
Выполняется блокировка вывода лога, если уарт совпадает
и выполняется тот самый uart_init для заданной скорости, конфига SERIAL_8N1, режима SERIAL_8N1, и номера пина 1
Больше никаких инициализаций не выполняется :)
os_printf Вы вызывать не хотите, вместо нее вызываете Serial.print так что ли, типа os_printf не кошерная.
Тогда всё становится на свои места, чем больше обёрток, тем пухлее код (бинарный), круто.
 

valerivp

Member
Алексей., я считаю, что для использования каких либо библиотек, я не должен в совершенстве знать, как они устроены.
Для Serial положено вызвать begin - я его и вызываю.
Serial.print и os_printf обеспечивают похожий, но совершенно разный функционал.

Лично мне гораздо удобнее писать
Код:
Serial << F("value:") << value << F(",info:") << info ...
чем
Код:
os_printf("value:%????")
- я даже не хочу думать, какие буквы мне надо написать в форматной строке.

и меня очень мало волнует объем и производительность кода, пока эти показатели укладываются в рамки которые меня устраивают.
мое время мне дороже байтов и тактов.
 

Алексей.

Active member
Говорите про Serial.print а сами используете потоковый вывод Serial << "some text"
Сначала утверждаете "я не должен в совершенстве знать, как они устроены" а потом когда код выходит из под контроля обращаетесь за помощью, ну конечно, за Вас другие уж точно разобрались, а Вы не верите.
А как в SDK работает Serial.begin и Serial.print ? Таких функций в SDK нет.
Это функции из Arduino и там UART-ы переназначены.
 

valerivp

Member
Говорите про Serial.print а сами используете потоковый вывод Serial << "some text"
Сначала утверждаете "я не должен в совершенстве знать, как они устроены" а потом когда код выходит из под контроля обращаетесь за помощью, ну конечно, за Вас другие уж точно разобрались, а Вы не верите.
Мне кажется, что для использования потокового вывода (Serial << ) объект Serial должен быть корректно инициализирован. Именно поэтому я вызываю begin

А когда поведение системы отличается от ожидаемого, только тогда я начинаю думать - "почему же он так?"
и мыслительный процесс у меня выдает порядок действий:
  • Спросить у Яндекса - он много знает
  • Спросить на форуме - может кто наступал на эти грабли
  • Прикинуть что проще/более приемлемо - разобраться или обойти
  • Разобраться или обойти
 

valerivp

Member
А как в SDK работает Serial.begin и Serial.print ? Таких функций в SDK нет.
Это функции из Arduino и там UART-ы переназначены.
Лично мне глубоко все равно, где кончается SDK и начинается Adruino и сторонние библиотеки. Я привык быть неразборчивым в средствах, лишь бы они приводили к нужному результату с минимальными трудозатратами.
 

pvvx

Активный участник сообщества
Смотреть без слёз нельзя ESP8266 Non-OS SDK API Reference


Prototype: os_printf(const char *s)
декларирована функция с одним аргументом, совсем не переменным числом, а с одним
Example: os_printf("SDK version: %s \n", system_get_sdk_version());
пример как бы уже с двумя
ничего удивительного что в коде масса ошибок, это традиция, ардуина-иде популяризирует это "изделие" тем самым обеспечивает определенный спрос на него, в ретейл такое вряд ли пройдет, а вот для "поиграть" сгодится.
Там в самом коде процедуры ets_printf ошибки (она находиться в ROM), а не в описаниях в Arduino к ней.
При вызове коротких форматных строк типа ets_printf("%u", x) или подобных (счас точно уже не помню, т.к. не вожусь с ESP8266 более), она ничего не выводит или режет вывод, показывает меньше цифр и и прочие глюки. Не говоря уже о том, что не поддерживает float и массу стандартных форматов.
 

pvvx

Активный участник сообщества
и меня очень мало волнует объем и производительность кода, пока эти показатели укладываются в рамки которые меня устраивают.
мое время мне дороже байтов и тактов.
<< дает увеличение кода на 100 килобайт и тормоз. Т.е. вам придется взять другой чип.
Я вижу время у вас много - подождете ещё пяток или пятьдесят лет, когда появятся чипы, удовлетворяющие ваши требования (c учетом потребления уже имеющихся устройств при работе с ними в обычном СИ).

#include <iostream>
using namespace std;
void setup() { cout << "std: Hello, world!" << endl; }
void loop() {}
Скетч использует 158260 байт

void setup() { printf("Printf: Hello, world!\r\n"); }
void loop() {}
Скетч использует 28592 байт (там инициализация чипа + RTOS + барахло Arduino + стандартный printf + их данные и буфера, т.е. включая bss)

PS: Мой совет вам - не тратьте на это вообще время - наймите программиста :)
 
Последнее редактирование:

valerivp

Member
Скетч использует 28592 байт (там инициализация чипа + RTOS + барахло Arduino + стандартный printf + их данные и буфера, т.е. включая bss)
а когда я добавил нужные мне библиотеки стало еще больше! ужас!
326 755 bytes (used 31% of a 1 044 464 byte maximum)

целых 31%

надо срочно нанять программиста, который запихнет в 25%.
За 50000$
Потом скажет - для этого устройства ESP8266 избыточна. И глючна. И ему не нравится. И надо все переписать. И вообще он просто хочет еще 50000$.

А мне глубоко пофигу, сколько байт занимает программа 22% или 50%. Важно только что меньше 100%. Хотя в данном чипе - нужно меньше 50% - чтобы на OTA осталось.

Для моих задач чипа хватает с головой. Не будет хватать - возьму ESP32. И я ожидаю, что код Ардуино будет работать в другом чипе с минимальными изменениями. А если писать на чистом железе - очень много переделывать придется.
 

pvvx

Активный участник сообщества
а когда я добавил нужные мне библиотеки стало еще больше! ужас!
Вам же уже сказал, что у вас вагон времени на ожидание заливки больших объемов через COM порт в чип :)
Та и зачем вам скорость и вообще все эти С++ прибамбасы "<<" - чтобы мигать светодиодом? :)
На большее ESP8266 не годится. А примеры я приводил на другом чипе... т.к. на ESP в Arduino ничего не работает из типа такого [inline]cout << "std: Hello, world!" << endl;[/inline]
Да и вообще там проблем немерено. Пример - не распечатать uint64_t никаким методом :)
И если добить до поддержки C++ либ, то прошивка не лезет в простые модули ESP8266. Его XIP в 1 МБ не хватает + Flash для OTA нужна увеличенная.
 
Последнее редактирование:

pvvx

Активный участник сообщества
ESP-32S.
Код:
#include <iostream>
using namespace std;

void setup() {
  cout << "cout: Hello, world!" << endl;
  cerr << "cerr: Hello, world!" << endl;
  uint64_t x = 0xffffffffffffffff;
  cout << "uint64 x = " << x << endl;
}
void loop() {}
"Скетч использует 347563 байт (33%) памяти устройства. Всего доступно 1044464 байт."
Код:
....
cout: Hello, world!
cerr: Hello, world!
uint64 x = 18446744073709551615
Но только так можно напечатать uint64, затратив 300 КБ на ESP-32 :)
 

Сергей_Ф

Moderator
Команда форума
@AndrF, компиляция идёт компилятором с той же скоростью. Просто Ардуино ИДЕ считает, что надо перекомпилировать все библиотеки заново по малейшему поводу, а зачастую и без повода. Вот и собирает весь проект по новой.
 

pvvx

Активный участник сообщества
@AndrF, компиляция идёт компилятором с той же скоростью. Просто Ардуино ИДЕ считает, что надо перекомпилировать все библиотеки заново по малейшему поводу, а зачастую и без повода. Вот и собирает весь проект по новой.
Это зависит от описания. Скрипта по сборке. Обычно там разделено на создание не менее 3-х библиотек разных частей разделов, которые потом линкуются в единый итого...
А перекомпиляция делается при смене настроек. По другому поводу пока не заметил. Если смените тип интерфейса программирования, то меняются опции идущие на вход компиляции и среда не знает - есть ли там у вас зависимость от этого и пересобирает от греха подальше :)
А в vMicro видимо ничего не меняется и надо вручную пересобирать, как это принято для мощных сред... Сменили внешние define - тыкаете "пересобрать всё" в ручную. :)

Возможно в vMicro у вас включена многопоточная сборка... Это ускоряет обычно, на современных истинных многоядерниках до 10..25 раз сборку.Больше 25 раз выдавить пока не удалось на 10 ядрах... Так-же ускорение сборки дает использование RAM-диска. Дает ускорение ещё в 2 раза, в отличии от NVMe на PCIE. Скорость сборки gcc в Windows что с NVMe в за 3 ГигаБайта трафиком, что с IDE со 100 Мегайбайт трансфером одинакова. Причина почему, пока не установлена :)
Полная сборка с нуля всего проекта типа Arduino для ESP при многопотоке и RAM диске должна занимать около 3..4 секунуд (с выводом бинарников - там не параллелится) .
 
Последнее редактирование:

valerivp

Member
Замеры vMicro (+-3сек):
сборка проекта ESP8266 полная - 1мин
то же, многопоточная - 15 сек

изменение одного файла - от нажатия F5 до старта ESP - 25сек

полная пересборка при изменении глобального define - автоматическая
 

pvvx

Активный участник сообщества
Замеры vMicro (+-3сек):
сборка проекта ESP8266 полная - 1мин
то же, многопоточная - 15 сек

изменение одного файла - от нажатия F5 до старта ESP - 25сек

полная пересборка при изменении глобального define - автоматическая
150..200 файлов (после clean) (не учитывая сотни хидеров) полных исходников SDK на RTL, а не куцый ESP8266 с закрытыми либами, занимает 5..6 сек на дешевом Ryzen 1700x (Win10, компиляция в среде WSL, типа-рам диск):
https://esp8266.ru/forum/threads/moj-sborschik-i-flesher.2268/page-12#post-43498
в одиночный поток - что-то к минуте... (там в SDK вообще более 1700 файлов *.c и *.h)
Заливка и запуск проекта (для теста - web-свалка) в модуль - Eclipse: Build Finished (took 4s.428ms)
Всё без разгонов и каких-то спец. извращений. Не нужны они на постоянно работающих (годами) компах...
Пытаюсь ещё ужать раза в два и есть на то резервы... Сегодня ещё один шаг оптимизации по сборке долепил... Выйдет на данном компе к 5 сек всё, если с нуля проект в первый раз собирать... SSD/NVMe не сильно помогают. На них к 10 сек сборка, как и на простом HDD. Причуда Windows по "кешированию" дисков...
 
Последнее редактирование:
Сверху Снизу