Любая функция вместо sprintf() в C? размер кода слишком велик после компиляции

Я работаю над разработкой встроенной системы (Cortex M3). Для отправки некоторых данных с устройства на последовательный порт (для отображения на экране ПК) я использую некоторые собственные функции, используя метод putchar().

Когда я хочу отправить integer или float, я использую sprintf(), чтобы преобразовать их в строку символов и отправить их на последовательный порт.

Теперь их проблема в том, что я использую Keil uVision IDE, и это ограниченная версия с максимальным размером 32 КБ. Всякий раз, когда я вызываю sprintf() в разных функциях, я не знаю, почему размер кода после компиляции слишком сильно увеличился. Теперь я превысил 32 КБ, и мне интересно, мне нужно изменить некоторые из моих функций и использовать что-то еще вместо sprintf!

Любая подсказка?


person Django    schedule 25.10.2012    source источник
comment
В конце концов, старайтесь избегать float, так как их компоненты библиотеки времени выполнения в большинстве случаев довольно большие и медленные.   -  person glglgl    schedule 25.10.2012
comment
семейство printf очень дорогое, так как для его реализации требуется большой объем кода, особенно с плавающей запятой. Только целое число printf намного меньше, но все же дорого. Вы действительно думаете, что вам нужен printf() в коде встроенного микроконтроллера? Вы можете реализовать свои собственные гораздо более дешевые решения.   -  person old_timer    schedule 26.10.2012
comment
Также посмотрите на доступные библиотеки поставщиков вашего компилятора. Часто будет несколько разновидностей стандартных библиотек C с ограниченной функциональностью. Например, sprintf обрабатывает int и float, но не экспоненциальную запись.   -  person Josh Petitt    schedule 31.01.2013


Ответы (3)


Два возможных предложения (ни одно из которых я не использовал сам - поставщики моих компиляторов обычно предоставляют урезанный printf для встроенного использования):

http://eprintf.sourceforge.net/ — [сентябрь 2017 г.: к сожалению, похоже, но исходный код все еще здесь: https://sourceforge.net/projects/eprintf/files/ ]

http://www.sparetimelabs.com/tinyprintf/index.html — 2 файла , около 1,4 КБ кода. Возможность включить «длинные» (означает больший размер кода). Поддерживает начальные нули и ширину поля. Нет поддержки с плавающей запятой.

person Martin Thompson    schedule 25.10.2012
comment
Поскольку на веб-странице eprintf нет ссылок на фактический код, вот ссылка на проект eprintf sourceforge: sourceforge.net/ проекты/eprintf - person Michael Burr; 26.10.2012
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. – Из обзора - person StoryTeller - Unslander Monica; 27.09.2017
comment
@StoryTeller - обычно я бы согласился, но я не уверен, что краткое изложение содержания поможет, если ссылки исчезнут (как я вижу, одна из них :( - когда я просто предлагаю ссылки на исходный код, а не на верный ответ. - person Martin Thompson; 27.09.2017

Если вы хотите, чтобы он был эффективным, вероятно, лучший способ — написать его самостоятельно или найти какой-нибудь уже написанный код в сети. Однако преобразование int в строку очень простое, каждый программист может написать это менее чем за 30 минут. Преобразование числа с плавающей запятой в строку немного сложнее и зависит от используемого формата с плавающей запятой.

Для удобства приведем простой алгоритм преобразования целых чисел в строку для использования в приложениях микроконтроллера:

void get_dec_str (uint8_t* str, size_t len, uint32_t val)
{
  uint8_t i;
  for(i=1; i<=len; i++)
  {
    str[len-i] = (uint8_t) ((val % 10UL) + '0');
    val/=10;
  }

  str[i-1] = '\0';
}
person Lundin    schedule 25.10.2012
comment
Я не уверен, что это очень быстрая/эффективная функция, если у вашего микро нет аппаратного делителя... (или модуля :). Хотя лучшего варианта в голову не приходит! - person Martin Thompson; 25.10.2012
comment
@MartinThompson Я не уверен, что с этим можно что-то поделать, десятичные дроби основаны на 10, но компьютеры предпочитают 2/4/8/16/32. Кроме того, я бы предпочел оставить оптимизацию компилятору. - person Lundin; 25.10.2012
comment
справедливый комментарий: оставить оптимизацию компилятору - person Martin Thompson; 25.10.2012

Вы можете попробовать itoa() или ftoa() и реализовать их по своему требованию. Я имею в виду, что они преобразуют их в символы только внутри самого определения, используя putchar() для прямой печати.

Это должно сработать, я думаю.

person Omkant    schedule 25.10.2012
comment
В языке Си нет ни функции с именем itoa, ни функции с именем ftoa. - person Lundin; 25.10.2012
comment
@Lundin: можно написать по вашему требованию ... или включить эти файлы ... itoa и ftoa находятся в этих заголовочных файлах ‹stdlib.h› или ‹cstdlib› - person Omkant; 25.10.2012
comment
в C нет itoa() и ftoi() (я не знаю, существует ли он на самом деле в C++) - person Django; 25.10.2012
comment
@Omkant Их нет в стандартной библиотеке, поскольку они не являются частью какого-либо стандарта C или C ++. Вы используете какой-то нестандартный компилятор. - person Lundin; 25.10.2012
comment
@Lundin: как я уже упоминал, вы можете реализовать то же самое ... означает написать собственное определение - person Omkant; 25.10.2012