• Система автоматизации с открытым исходным кодом на базе 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
 
Последнее редактирование:
Сверху Снизу