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

Не работают float, double и библиотека math

sharikov

Active member
Понадобилась арифметика с плавающей точкой и функции из math.
С этим совсем беда: стандартные библиотеки отключены а в rtl_libc все плохо, даже сравнение float не работает:
[inline]undefined reference to `__aeabi_fcmple'[/inline]
и в том же духе по всем фунциям eabi для float и double.

Подключить стандартную библиотеку не вариант - будет конфиликт с rtl_libc, уже по этим граблям ходили.

Может кто посоветует сторонние библиотеки без внешних зависимостей с поддержкой плавающей арифметики и функций math ?
 

pvvx

Активный участник сообщества
Подключить стандартную библиотеку не вариант - будет конфиликт с rtl_libc, уже по этим граблям ходили.
Конфликта не возникает - поправьте входящие в проект файлы в sdkset.mk. Я линковал уже вариант со всякими java интерпретаторами и стандартными либами плавающей точки от GNU GCC...
С #include файлами тоже придется поработать для той части, которая использует float.
 

pvvx

Активный участник сообщества
А смысл?
Она дает всего это (qfplib-m3.h):
Код:
extern float qfp_fadd(float x,float y);
extern float qfp_fsub(float x,float y);
extern float qfp_fmul(float x,float y);
extern float qfp_fdiv(float x,float y);
extern float qfp_fsqrt(float x);
extern float qfp_fexp(float x);
extern float qfp_fln(float x);
extern float qfp_fsin(float x);
extern float qfp_fcos(float x);
extern float qfp_ftan(float x);
extern float qfp_fatan2(float y,float x);
А у нас уже есть в ROM:
Код:
int rtl_dtoi(double d);
int rtl_dtoui(double d);
float rtl_i2f(int val);
int rtl_i2d(int val);
float rtl_ui2f(unsigned int val);
int rtl_ui2d(unsigned int val);
char *rtl_itoa(int value, char *string, int radix);
char *rtl_ltoa(int value, char *string, int radix);
char *rtl_utoa(unsigned int value, char *string, int radix);
char *rtl_ultoa(unsigned int value, char *string, int radix);
int rtl_ftol(float f);
int rtl_ftod(float f);
float rtl_dtof(double d);
float rtl_fadd(float a, float b);
float rtl_fsub(float a, float b);
float rtl_fmul(float a, float b);
float rtl_fdiv(float a, float b);
int rtl_dadd(double a, double b);
int rtl_dsub(double a, double b);
int rtl_dmul(double a, double b);
int rtl_ddiv(double a, double b);
int rtl_dcmpeq(double a, double b);
int rtl_dcmplt(double a, double b);
int rtl_dcmple(double a, double b);
int rtl_dcmpgt(double a, double b);
int rtl_fcmplt(float a, float b);
int rtl_fcmpgt(float a, float b);
float rtl_fabsf(float a);
int rtl_fabs(double a);
float rtl_cos_f32(float a);
float rtl_sin_f32(float a);
Код из ROM работает быстрее (без тактов ожидания) даже оптимизированного, но расположенного в SRAM. Только если его закинуть в TCM RAM, то будет работать без тактов ожидания... Если в SDRAM - соответственно ещё медленнее.

Так-же вставил какие-то c_printf() и c_sprintf() - они работают с float.
Сильно всё не проверял, т.к. пока нет нужды в плавающей точке...
 
Последнее редактирование:

sharikov

Active member
Конфликта не возникает - поправьте входящие в проект файлы в sdkset.mk. Я линковал уже вариант со всякими java интерпретаторами и стандартными либами плавающей точки от GNU GCC...
Поясните как линковать стандартные библиотеки чтобы при этом сохранить работающее из ram_pvvx_libc.c Насколько раздувается код ?
Поправил ram_pvvx_libc_s.c - простая арифметика и сравнения заработали но libm тянет много недостающих __aeabi_* и не линкуется.

Это видел но еще не пробовал.
 

Вложения

pvvx

Активный участник сообщества
Поясните как линковать стандартные библиотеки чтобы при этом сохранить работающее из ram_pvvx_libc.c Насколько раздувается код ?
Ну тут пока не выработано общего решения - написал же - мне пока не требовалось, а никакой помощи со стороны нет. Есть куча разных либ, хоть тот-же microc от ESP8266.
Поправил ram_pvvx_libc_s.c
Это временная затычка, сделанная для моих проектов-примеров. Потому так и названа.
 

sharikov

Active member
Код:
===========================================================
Compile (build)
===========================================================
Link (build)
/opt/gcc-arm-none-eabi-5_4-2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7-m/libc_nano.a(lib_a-sscanf.o): In function `siscanf':
sscanf.c:(.text.sscanf+0x0): multiple definition of `sscanf'
build/obj/project/src/user/ram_pvvx_libc_s.o:/media/Yocto/rtl8710/tp6_rtl//project/src/user/ram_pvvx_libc_s.c:292: first defined here
Если убрать --specs=nano.specs собирается и даже работает, плавучка считает правильно. Но +6Кб. На exp() и pow() 6 кило как-то многовато будет.
 

pvvx

Активный участник сообщества
Если убрать --specs=nano.specs собирается и даже работает, плавучка считает правильно. Но +6Кб. На exp() и pow() 6 кило как-то многовато будет.
Пишите свою либу. Тут на вкус и цвет... В базовом SDK нет printf с float, а так-же не все функции _eabi в ROM (другая версия GCC, очень старая)
Тем более exp() и pow() - составные функции - впишите свои.
Пример :) https://opensource.apple.com/source/Libm/Libm-315/Source/ARM/powf.c
 
Последнее редактирование:

Neov

Member
@sharikov так как с внедрением float double? удалось? как бы ещё легко 64 битную алгебру завести :)
 

pvvx

Активный участник сообщества
Код:
double d = 1.23456789;
    double a = 9.87654321;
    printf("double d = %lf a = %lf, d+a = %lf, d*a = %Lf\n", d, a, d+a, d*a);
лог:
double d = 1.234568 a = 9.876543, d+a = 11.111111, d*a = 12.193263
----
project.mk: USE_GCC_LIB = 1

Далее google: "GCC printf long long"

А так-же желательно вспомнить, что писал про c_printf/c_sprintf
Код:
    double d = 1.23456789;
    double a = 9.87654321;
    c_printf("double d = %lf a = %lf, d+a = %lf, d*a = %Lf\n", d, a, d+a, d*a);
    int64_t xa = 0x1234567890123456LL;
    c_printf("xa = 0x%016llX, xi = %llu\n", xa, xa);
    unsigned char uc = UCHAR_MAX;
    unsigned short us = USHRT_MAX;
    unsigned int ui = UINT_MAX;
    unsigned long ul = ULONG_MAX;
    unsigned long long ull = ULLONG_MAX;
    c_printf("UCHAR_MAX, %u (decimal), %#o (octal), %#x (hex)\n",    uc, uc, uc);
    c_printf("USHRT_MAX, %u (decimal), %#o (octal), %#x (hex)\n",    us, us, us);
    c_printf("UINT_MAX, %u (decimal), %#o (octal), %#x (hex)\n", ui, ui, ui);
    c_printf("ULONG_MAX, %lu (decimal), %#lo (octal), %#lx (hex)\n", ul, ul, ul);
    c_printf("ULLONG_MAX, %llu (decimal), %#llo (octal), %#llx (hex)\n", ull, ull, ull);
Код:
double d = 1.234568 a = 9.876543, d+a = 11.111111, d*a = 12.193263
xa = 0x1234567890123456, xi = 1311768467284833366
UCHAR_MAX, 255 (decimal), 377 (octal), ff (hex)
USHRT_MAX, 65535 (decimal), 177777 (octal), ffff (hex)
UINT_MAX, 4294967295 (decimal), 37777777777 (octal), ffffffff (hex)
ULONG_MAX, 4294967295 (decimal), 37777777777 (octal), ffffffff (hex)
ULLONG_MAX, 18446744073709551615 (decimal), 1777777777777777777777 (octal), ffffffffffffffff (hex)
Код:
    float f = 1.23456789012345678912e16;
    c_printf("float\t\t%lf, %.17le\n", f, f);
    double d = 1.23456789012345678912e16;
    c_printf("double\t\t%lf, %.17le\n", d, d);
    long double ld = 1.23456789012345678912e16;
    c_printf("long double\t%lf, %.17le\n", ld, ld);
Код:
float           12345678407663615.000000, 1.23456784076636150e+16
double          12345678901234567.000000, 1.23456789012345670e+16
long double     12345678901234567.000000, 1.23456789012345670e+16
 
Последнее редактирование:
Сверху Снизу