Easyelectronics.ru

Электроника для всех
Текущее время: 24 сен 2020, 19:55

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 10:39 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
Вчера вечером пробило на написать свою реализацию printf для MK. Точнее два варианта - snprintf для печати в строку и cb_printf для печати вызовом callback-функции. Не поддерживает тип float и int64_t. Возможно в будущем добавлю эти типы, если понадобится. В моём случае для STMF4 размер прошивки при добавлении моей реализации printf увеличивается на 1800 байт при уровне оптимизации -O2.
Вкратце о возможностях:
Поддерживает флаги # {пробел} + - 0
Поддерживает ширину
Поддерживает типы d, i, u, o, x, X, c, s, p
Зависит только от файла stdarg.h (для работы с ...)
Для работы нужно лишь два файла micro_printf.c и micro_printf.h.

Исходники вот тут: https://github.com/art-den/micro_printf

Использовать как-то так:
Код:
#include "micro_printf.h"
...
char buffer[64];
snprintf(buffer, sizeof(buffer), "value=%+8i", 42);


или так:
Код:
#include "micro_printf.h"
...
int my_putchar(void* data, char character)
{
    put_uart_char(character);
    return 1; // ok, continue print
}
...
char buffer[64];
cb_printf(my_putchar, NULL, "value=%+8i", 42);


PS: Используя ещё одну ф-цию cb_vprintf можно написать свой printf который сразу будет печатать на любое устройство без указания callback-а.
PPS: Думаю, это не самая худшая реализация printf-а.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 10:51 
Старожил

Зарегистрирован: 08 июл 2013, 17:00
Сообщения: 691
А в чём преимущества перед стандартными функциями printf() и sprintf()?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 10:56 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
Я просто решил развлечься и наваять ещё один printf в добавок к существующим, который занимает мало место в прошивке )))
Тот printf, который идёт с gcc, тащит с собой другие либы, а самое главное - использует выделение памяти, что для меня не приемлемо.
Ещё преимущество - если надо печатать напрямую в разные девайсы, то со стандартным printf это не получится, а с cb_printf или cb_vprintf - легко.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:05 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2063
Свой велосипед, даже с квадратными колёсами, всегда понятнее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:11 
Старожил

Зарегистрирован: 20 окт 2015, 18:14
Сообщения: 377
ArtDen писал(а):
В моём случае для STMF4 размер прошивки при добавлении моей реализации printf увеличивается на 1800 байт при уровне оптимизации -O2.
А при добавлении стандартного?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:17 
Старожил

Зарегистрирован: 20 окт 2015, 18:14
Сообщения: 377
Код:
unsigned char c = (unsigned char)*format_str++;
      unsigned char flag =
         (c == '-') ? FMT_FLAG_MINUS :
         (c == '+') ? FMT_FLAG_PLUS :
         (c == ' ') ? FMT_FLAG_SPACE :
         (c == '0') ? FMT_FLAG_ZERO :
         (c == '#') ? FMT_FLAG_OCTOTHORP : 0;

Когда-то такого рода конструкции напрочь выносили мозг :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:28 
Старожил

Зарегистрирован: 08 июл 2013, 17:00
Сообщения: 691
Цитата:
если надо печатать напрямую в разные девайсы, то со стандартным printf это не получится

Почему не получится? В том же Кейле нужно определять функцию вывода одного символа. Тут как раз можно реализовать перенаправление вывода.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:34 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
sva_omsk писал(а):
ArtDen писал(а):
В моём случае для STMF4 размер прошивки при добавлении моей реализации printf увеличивается на 1800 байт при уровне оптимизации -O2.
А при добавлении стандартного?

Хм... Добавил -specs=nosys.specs в флаги линкера и стандартный snprintf стал занимать всего 2500 байт в прошивке (но он тоже не "умеет" float-ы) :D Вот я ступил. Надо было сразу так сделать.
Правда, родной printf не умеет печатать с callback-ом, что для меня тоже важно (надо отдельно печатать и на экран и в usart без промежуточных строковых буферов)


Последний раз редактировалось ArtDen 04 фев 2020, 11:59, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:35 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
tonyk писал(а):
Почему не получится? В том же Кейле нужно определять функцию вывода одного символа. Тут как раз можно реализовать перенаправление вывода.


А можно пример как в 2 девайса печатать разные вещи? Например, в usart - логирование, а на экран - сообщение для пользователя?

В моём случае мне надо дописать (можно в отдельном файле) вот это:
Код:
static int uart_print_callback(void* data, char character)
{
   uart1_putchat(character);
   return 1;
}

void printf_uart(const char* format, ...)
{
   va_list arg_list;
   va_start(arg_list, format);
   int result = cb_vprintf(uart_print_callback, NULL, format, arg_list);
   va_end(arg_list);
}

static int screen_print_callback(void* data, char character)
{
   screen_print(character);
   return 1;
}

void printf_screen(const char* format, ...)
{
   va_list arg_list;
   va_start(arg_list, format);
   int result = cb_vprintf(screen_print_callback, NULL, format, arg_list);
   va_end(arg_list);
}


А потом можно использовать вот так:
Код:
printf_uart("Failed at ethernet init. Error code = %i, Ext code = %i\n", error_code, ext_code);
printf_screen(u8"Ошибка инициализации сетевого устройства %s\n", explain_error_code(error_code))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:57 
Старожил

Зарегистрирован: 11 сен 2012, 11:19
Сообщения: 5883
ArtDen писал(а):
и стандартный snprintf стал занимать всего 2500 килобайт

????
Спешим, лясипеды ваяем...
Этих мини, микро, нано print'ЭФОВ на гитхабе вагон и маленькая тележка.
Недавно приспичило на софт_ядро 51ое , ибо кейловский пургу нес, и то нашлось...


Последний раз редактировалось dosikus_2 04 фев 2020, 12:01, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 11:57 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
dosikus_2 писал(а):
Спешим...

ыпечатолся ))
Велосипеды - это не всегда плохо. А свой велосипед - это свой велосипед )) Его всегда можно легко доработать и сделать с преферансом и куртизанками ))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 12:32 
Старожил

Зарегистрирован: 06 окт 2014, 20:14
Сообщения: 827
А бываю-ли ВЕЛОСИПЕДЫ или это миф? На мой скромный взгляд, процесс вызревания стандарта на века, это редкий уникальный случай, в основном за ВЕЛОСИПЕД выдают свой собственный СУБЪЕКТИВНЫЙ (стандарт на века) взгляд на реальность и, надо сказать, что большинство, научилось делать это столь настойчиво, что нет нет да поверишь, вот он ВЕЛОСИПЕД (стандарт на века), ан нет опять ложный опенок от уважаемого вендора. Так что, прочь стеснительность, оправдательный тон и прочую шелуху, как говорил один инструктор по вождению автомобиля, "если нарушаете, нарушайте уверенно..."

P.S. Уважаемые вендоры, кстати, придумали в свое время термин ИНКАПСУЛЯЦИЯ, что аналогично детскому "А я в домике..." и, страхует от критики. Так сказать, позаботились о СВОИХ говнокодерах, толерантность так сказать, мейнстрим. А что такое полиморфизм, сформулированный ими-же термин, похоже никто не вкурил до сих пор.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 13:21 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
ArtDen писал(а):
[/
Тот printf, который идёт с gcc, тащит с собой д.

tiny printf в помощь! Это тыщу лет назад написанная штука


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 14:15 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3559
Откуда: Китай, Пекин
интересно а с какой целью перед передачей кудато там... обязательно переводить из бинарного представления в текстовое?
это такой спорт?
что мешает передать и... уже на той стороне, распечатать, или график построить?

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 14:47 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
BusMaster писал(а):
tiny printf в помощь! Это тыщу лет назад написанная штука

Ну вот захотелось свой printf ))

cheblin писал(а):
интересно а с какой целью перед передачей кудато там... обязательно переводить из бинарного представления в текстовое?
это такой спорт?
что мешает передать и... уже на той стороне, распечатать, или график построить?

Я давно убедился, что чем проще, тем лучше. При логировании для отладки проще запустить программу-терминал (или даже перенаправить выдачу МК с терминала в файл) и увидеть глазами что происходит. Если же надо передавать бинарные данные без логирования, я так и делаю. Просто передаю бинарные данные.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:00 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3459
ArtDen писал(а):
А можно пример как в 2 девайса печатать разные вещи? Например, в usart - логирование, а на экран - сообщение для пользователя?

А потом можно использовать вот так:
Код:
printf_uart("Failed at ethernet init. Error code = %i, Ext code = %i\n", error_code, ext_code);
printf_screen(u8"Ошибка инициализации сетевого устройства %s\n", explain_error_code(error_code))

можно задать функцию которой printf непосредственно выводит символы
точнее даже сделать указатель на неё и менять по желанию

__write = __write_uart;
printf("Failed at ethernet init. Error code = %i, Ext code = %i\n", error_code, ext_code);

__write = __write_screen;
printf(u8"Ошибка инициализации сетевого устройства %s\n", explain_error_code(error_code))

только не забывать про non-reentrantность printf.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:06 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
_pv писал(а):
только не забывать про non-reentrantность printf.

Вот именно. В твоём примере, если использовать RTOS с вытесняющей многозадачностью, можно удивиться, почему это данные, предназначение для UART, попадают на экран, и наоборот. В моём случае это гарантированно работает корректно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:24 
Старожил

Зарегистрирован: 08 июл 2013, 17:00
Сообщения: 691
Цитата:
В твоём примере, если использовать RTOS с вытесняющей многозадачностью, можно удивиться, почему это данные, предназначение для UART, попадают на экран, и наоборот. В моём случае это гарантированно работает корректно.

Можно пояснить, как сделана синхронизация между несколькими задачами RTOS? Я не заметил никаких объектов синхронизации. Например, две задачи пишут строки в лог-файл.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:29 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
Я не заявлял, что если две задачи будут писать в один лог, то всё будет ок. Я лишь сказал, что если одна задача пишет в лог, а другая выводит на экран, то всё будет работать без лишних телодвижений. А если надо, чтобы две задачи писали в один лог, то надо задействовать объекты синхронизации. Это уже не задача printf. Это задача библиотеки логирования.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:43 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3559
Откуда: Китай, Пекин
Цитата:
я отладки проще запустить программу-терминал

ржу чёта...

примерно также защищали поклонники свой xml..
а когда всё "это" из hello world... вышло в реальный мир любители смотреть километровые партянки xml разбежались...

я уже не говорю о том, что вместо того чтобы слать отладочную инфу с наименьшим вмешательством в саму программу, рессурсы микроконтроллера расходуются на преобразование в текст !!!!

ну не дичь ли?
Цитата:
что чем проще, тем лучше.

представь себе ты не одинок...
что мешает написать простенький протокол.
первый байт тип пересылаемого, а далее сами данные?
это настолько элементарно!

на приёмной стороне это разобрать - два пальца обасфальт.

_________________
unirail.org


Последний раз редактировалось cheblin 04 фев 2020, 15:57, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 15:57 
Старожил
Аватара пользователя

Зарегистрирован: 20 май 2013, 22:29
Сообщения: 377
cheblin, то, о чём ты рассуждаешь - это вообще не вопрос реализации printf. Различия между бинарными или текстовыми протоколами меня сейчас не особо волнуют.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 16:01 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3559
Откуда: Китай, Пекин
Цитата:
вместо того чтобы слать отладочную инфу с наименьшим вмешательством в саму программу, рессурсы микроконтроллера расходуются на преобразование в текст !!!!


или этот printf для работы c GPS? тогда да...умолкаю

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 16:50 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1268
ArtDen писал(а):
Не поддерживает тип float и int64_t. Возможно в будущем добавлю эти типы, если понадобится.

Добавить то float можно, только сишные функции с переменным числом параметров с ним не работают, будет вызвана функция преобразования в double, потом при выводе придется конвертить обратно в float. В этом плане С++ гораздо продвинутей, там делай что хочешь...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 18:10 
Старожил

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 4198
Откуда: Чобля - долбаный кетайец
Основная проблема всех этих printf-ов - в va_list - переменном списке аргументов. Ну а если работаете с F4, вас не должно сильно волновать - 1800 байт или 2500. У вас там один только шрифт съедает в 5-10 раз больше.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой printf для МК
СообщениеДобавлено: 04 фев 2020, 18:35 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 832
ArtDen писал(а):
В моём случае для STMF4 размер прошивки при добавлении моей реализации printf увеличивается на 1800 байт при уровне оптимизации -O2.

Если печатать double - добавится еще больше.
Лично я так и не смог понять, в чём смысл использования параметров печати printf. Если печатать что-то уникальным способом - то создаётся новый костыль. Но вот использовать этот костыль везде и всегда - это уже перебор.
Мой велосипед.
https://bitbucket.org/AVI-crak/sprint/src/default/
Печать только целых чисел - 372b, а если задействовать все возможности 3744b.
Не умеет печатать перечисления. Точнее - если включить такую возможность, то внезапно создаются все текстовые массивы для всех имеющихся перечислений. Было бы классно чтобы массивы текста создавались только для используемых перечислений, но я походу где-то напортачил.


Вложения:
Temp33.jpg
Temp33.jpg [ 101.61 Кб | Просмотров: 763 ]

_________________
Потоковая OS
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB