|
Вывод float в arm-none-eabi-gcc для stmf4 |
|
|
|
Oct 20 2016, 15:09
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Добрый день. Я меня возникли некоторые проблемы с выводом в терминал значений с плавающей точкой. Самый обычный sprintf прекрасно работает с целыми числами и отказывается работать с float. Например CODE 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 Кто-либо сталкивался с подобным?
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Oct 20 2016, 17:02
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Цитата(scifi @ Oct 20 2016, 18:26)  В командную строку линкера нужно добавить "-u _printf_float". Первоисточник. На самом деле пробовал с -u _printf_float и с -u _sprintf_float с одинаковым результатом.
Сообщение отредактировал zemlemer - Oct 20 2016, 17:18
|
|
|
|
|
Oct 21 2016, 19:00
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Цитата(scifi @ Oct 20 2016, 20:22)  Я невнимательно посмотрел. Если линкуется целочисленная версия, не будет вот этих странных чисел. Обратите внимание на выравнивание стека по границе 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); - передается правильно.
Сообщение отредактировал IgorKossak - Oct 22 2016, 13:27
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
|
|
|
|
|
Oct 21 2016, 19:25
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Цитата(iiv @ Oct 21 2016, 22:03)  если у вас одинарная точность, sprintf хочет %f или %e или %g, а если двойная, то да, с "l" надо писать. Знаю. Просто va_arg не работает с float, поэтому перед передачей я преобразовывал в double а после - обратно во float.
|
|
|
|
|
Oct 24 2016, 10:53
|
Участник

Группа: Участник
Сообщений: 69
Регистрация: 10-06-08
Пользователь №: 38 190

|
Цитата(demiurg_spb @ Oct 23 2016, 00:21)  Я каждый раз задаюсь вопросом: в чём был смысл такого решения при создании сишной библиотеки? Смыслов несколько. У меня статически выделен массив для передачи строки в терминал, а стандартные работают с динамическим перераспределением памяти. Использовать malloc или realloc нужно когда совсем припрет. Мне не нужны все возможности printf или sprintf (кто-нить использовал \b или \v или ..... ), но все лишнее намертво прилепится к выходному бинарнику.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|