zemlemer 0 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Добрый день. Я меня возникли некоторые проблемы с выводом в терминал значений с плавающей точкой. Самый обычный sprintf прекрасно работает с целыми числами и отказывается работать с float. Например float flttest = 123.45678; sprintf(TestArray, "-= %lf =-", flttest); Terminal("Test1: STR %s", TestArray); uint16_t integer= 12345; sprintf(TestArray, "*- %d -*", integer); Terminal("Test2: STR %s", TestArray); При этот вывод: 003 INFO: Test1: STR -= 403099659660755.687500 =- 004 INFO: Test2: STR *- 12345 -* Основные ключи компилятора: arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mlittle-endian -mthumb-interwork -ffunction-sections -fdata-sections -Wl,--gc-sections Основные ключи линкера: arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Xlinker -Map="project.map" -L/opt/gcc-arm-none-eabi-5_4/arm-none-eabi/lib/armv7e-m/fpu/ --specs=rdimon.specs -T/Core/STM32F4XX_FLASH.ld Кто-либо сталкивался с подобным? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба В командную строку линкера нужно добавить "-u _printf_float". Первоисточник. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zemlemer 0 20 октября, 2016 Опубликовано 20 октября, 2016 (изменено) · Жалоба В командную строку линкера нужно добавить "-u _printf_float". Первоисточник. На самом деле пробовал с -u _printf_float и с -u _sprintf_float с одинаковым результатом. Изменено 20 октября, 2016 пользователем zemlemer Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Я невнимательно посмотрел. Если линкуется целочисленная версия, не будет вот этих странных чисел. Обратите внимание на выравнивание стека по границе 8 байт. Помню, это приводило к чудесам в плавучке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lagman 1 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба может поможет http://www.openstm32.org/tiki-view_forum_t...s_parentId=2108 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Ещё вариант: https://github.com/emb-lib/io библиотека, оптимизированная для embedded применений. Плавучку печатает без нареканий (только нужно определить макро PRINTF_FLOAT, лучше всего передать в командной строке -DPRINTF_FLOAT). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zemlemer 0 21 октября, 2016 Опубликовано 21 октября, 2016 (изменено) · Жалоба Я невнимательно посмотрел. Если линкуется целочисленная версия, не будет вот этих странных чисел. Обратите внимание на выравнивание стека по границе 8 байт. Помню, это приводило к чудесам в плавучке. Вроде к линковщике секция с правильным ALIGN, или я не правильно понял. ._user_heap_stack : { . = ALIGN(4); PROVIDE ( end = . ); PROVIDE ( _end = . ); PROVIDE ( __end__ = . ); . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); } >RAM Вообще ситуация еще более печальна. Задавая вопрос, я просто упростил сложившуюся ситуацию. На самом деле я пишу небольшую библиотеку для отладочного вывода. Парсер разбора форматной строки - va_arg - корректно работает с целочисленными переменными. Т.е. intarg = va_arg(ap, int32_t); отрабатывает корректно. Как только речи идет о передаче плавучки - doublearg = va_arg(ap, double); - передается мусор. Если передать float через *((int32_t*)&floatarg и передать через va_arg(ap, int32_t); - передается правильно. Изменено 22 октября, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iiv 18 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба float flttest = 123.45678; sprintf(TestArray, "-= %lf =-", flttest); если у вас одинарная точность, sprintf хочет %f или %e или %g, а если двойная, то да, с "l" надо писать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба если у вас одинарная точность, sprintf хочет %f или %e или %g, а если двойная, то да, с "l" надо писать. У sprintf не бывает одинарной точности, "l" игнорируется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zemlemer 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба если у вас одинарная точность, sprintf хочет %f или %e или %g, а если двойная, то да, с "l" надо писать. Знаю. Просто va_arg не работает с float, поэтому перед передачей я преобразовывал в double а после - обратно во float. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Вроде к линковщике секция с правильным ALIGN, или я не правильно понял. ._user_heap_stack : { . = ALIGN(4); Ещё раз: выравнивать по границе 8 байт. Проверяйте на входе в sprintf(). Внутрисхемным отладчиком остановите на входе в функцию и посмотрите на SP. Если не кратно 8 - беда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба перед передачей я преобразовывал в double а после - обратно во float. про "после" подробнее... желательно с кодом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 октября, 2016 Опубликовано 22 октября, 2016 · Жалоба У sprintf не бывает одинарной точности, "l" игнорируется.Я каждый раз задаюсь вопросом: в чём был смысл такого решения при создании сишной библиотеки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zemlemer 0 24 октября, 2016 Опубликовано 24 октября, 2016 · Жалоба Я каждый раз задаюсь вопросом: в чём был смысл такого решения при создании сишной библиотеки? Смыслов несколько. У меня статически выделен массив для передачи строки в терминал, а стандартные работают с динамическим перераспределением памяти. Использовать malloc или realloc нужно когда совсем припрет. Мне не нужны все возможности printf или sprintf (кто-нить использовал \b или \v или ..... ), но все лишнее намертво прилепится к выходному бинарнику. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 октября, 2016 Опубликовано 24 октября, 2016 · Жалоба Я каждый раз задаюсь вопросом: в чём был смысл такого решения при создании сишной библиотеки? Между прочим, если функция имеет переменное число аргументов (как sprintf), аргументы типа float приводятся к типу double перед вызовом функции. Отцы-основатели не подумали о микроконтроллерах. Да их (МК) тогда и не было, наверное :laughing: Мне не нужны все возможности printf или sprintf (кто-нить использовал \b или \v или ..... ), но все лишнее намертво прилепится к выходному бинарнику. Уже проверили выравнивание стека, кратное 8 байт? Просто интересно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться