Riot: 到处都在使用浮动和双打。

创建于 2019-08-20  ·  5评论  ·  资料来源: RIOT-OS/RIOT

描述

大多数平台没有对单精度浮点的硬件支持,并且没有(除了本机)支持双精度。

grep通过源代码我可以找到 float 和 double 的实例。 这些是一个问题,因为:

  • 如果必须链接软浮动支持,它们会增加代码大小。
  • 软漂浮很慢。
  • 即使硬浮点可用,它通常也不应在中断或内核代码中使用,因为这将涉及保存/恢复 fp 寄存器。

    • 对于驱动程序,很难知道什么在哪个上下文中运行。

  • 用户甚至可能不会怀疑,例如sx127x驱动程序正在使用双打。

据我所知,大多数这些用法都是不合理的。 特别是 double 的 _all_ 使用可以由 float 代替。

重现问题的步骤

获得近似搜索的快速方法是使用这些正则表达式:

$ git grep  "^\([^/]\|\(/[^*/]\)\)*\bdouble\b"  -- "*.[ch]"
$ git grep  "^\([^/]\|\(/[^*/]\)\)*\bfloat\b"  -- "*.[ch]"

他们会捕捉到一些误报,可能会错过一些误报。

实际结果

经过一些手动清理后,结果如下:


双重麻烦

drivers/bmp180/bmp180.c:    return (int16_t)(44330.0 * (1.0 - pow((double)p / pressure_0, 0.1903)));;
drivers/bmp180/bmp180.c:    return (uint32_t)((double)p / pow(1.0 - (altitude / 44330.0), 5.255));;
drivers/sx127x/sx127x_getset.c:    channel = (uint32_t)((double) channel / (double)LORA_FREQUENCY_RESOLUTION_DEFAULT);
drivers/sx127x/sx127x_getset.c:            double bw = 0.0;
drivers/sx127x/sx127x_getset.c:            double rs = bw / (1 << dev->settings.lora.datarate);
drivers/sx127x/sx127x_getset.c:            double ts = 1 / rs;
drivers/sx127x/sx127x_getset.c:            double t_preamble = (dev->settings.lora.preamble_len + 4.25) * ts;
drivers/sx127x/sx127x_getset.c:            double tmp =
drivers/sx127x/sx127x_getset.c:                    / (double) (4 * dev->settings.lora.datarate
drivers/sx127x/sx127x_getset.c:            double n_payload = 8 + ((tmp > 0) ? tmp : 0);
drivers/sx127x/sx127x_getset.c:            double t_payload = n_payload * ts;
drivers/sx127x/sx127x_getset.c:            double t_on_air = t_preamble + t_payload;
drivers/sx127x/sx127x_internal.c:    initial_freq = (double) (((uint32_t) sx127x_reg_read(dev, SX127X_REG_FRFMSB) << 16)
drivers/sx127x/sx127x_internal.c:                             | ((uint32_t) sx127x_reg_read(dev, SX127X_REG_FRFLSB))) * (double)LORA_FREQUENCY_RESOLUTION_DEFAULT;
drivers/tmp006/tmp006.c:    *tamb = (double)rawt / 128.0;
drivers/tmp006/tmp006.c:    double tdie_k = *tamb + 273.15;
drivers/tmp006/tmp006.c:    double sens_v = (double)rawv * TMP006_CCONST_LSB_SIZE;
drivers/tmp006/tmp006.c:    double tdiff = tdie_k - TMP006_CCONST_TREF;
drivers/tmp006/tmp006.c:    double tdiff_pow2 = pow(tdiff, 2);
drivers/tmp006/tmp006.c:    double s = TMP006_CCONST_S0 * (1 + TMP006_CCONST_A1 * tdiff
drivers/tmp006/tmp006.c:    double v_os = TMP006_CCONST_B0 + TMP006_CCONST_B1 * tdiff
drivers/tmp006/tmp006.c:    double f_obj = (sens_v - v_os) + TMP006_CCONST_C2 * pow((sens_v - v_os), 2);
drivers/tmp006/tmp006.c:    double t = pow(pow(tdie_k, 4) + (f_obj / s), 0.25);
sys/crypto/modes/ocb.c:       L_$ = double(L_*)
sys/crypto/modes/ocb.c:       L_0 = double(L_$)
sys/crypto/modes/ocb.c:       L_i = double(L_{i-1}) for every integer i > 0
sys/include/cb_mux.h: * @param[in] head   double pointer to first list entry
sys/include/cb_mux.h: * @param[in] head   double pointer to first list entry
sys/include/net/gnrc/rpl/structs.h:    double link_metric;             /**< metric of the link */
sys/include/random.h:double random_real(void);
sys/include/random.h:double random_real_inclusive(void);
sys/include/random.h:double random_real_exclusive(void);
sys/include/random.h:double random_res53(void);
sys/include/ubjson.h:static inline ssize_t ubjson_get_double(ubjson_cookie_t *__restrict cookie, ssize_t content, double *dest)
sys/include/ubjson.h:        double f;
sys/include/ubjson.h:ssize_t ubjson_write_double(ubjson_cookie_t *__restrict cookie, double value);
sys/net/routing/nhdp/iib_table.c:static const double const_dat = (((double)DAT_CONSTANT) / DAT_MAXIMUM_LOSS);
sys/net/routing/nhdp/iib_table.c:    double sum_total, sum_rcvd, loss;
sys/net/routing/nhdp/iib_table.c:                loss = (((double)ls_elt->hello_interval) * ((double)ls_elt->lost_hellos))
sys/quad_math/fixdfdi.c:quad_t __fixdfdi(double x)
sys/quad_math/fixunsdfdi.c:u_quad_t __fixunsdfdi(double x)
sys/quad_math/fixunssfdi.c:    double x, toppart;
sys/quad_math/fixunssfdi.c:    x -= (double) t.uq;
sys/quad_math/floatdidf.c:double __floatdidf(quad_t x)
sys/quad_math/floatdidf.c:    double d;
sys/quad_math/floatdidf.c:    d = (double) u.ul[H] * (((int) 1 << (INT_BITS - 2)) * 4.0);
sys/quad_math/floatdisf.c:    f = (double) u.ul[H] * (((int) 1 << (INT_BITS - 2)) * 4.0);
sys/quad_math/floatunsdidf.c:double __floatunsdidf(u_quad_t x)
sys/quad_math/floatunsdidf.c:    double d;
sys/quad_math/floatunsdidf.c:    d = (double) u.ul[H] * (((int) 1 << (INT_BITS - 2)) * 4.0);
sys/quad_math/quad.h:quad_t __fixdfdi(double);
sys/quad_math/quad.h:u_quad_t __fixunsdfdi(double);
sys/quad_math/quad.h:double __floatdidf(quad_t);
sys/quad_math/quad.h:double __floatunsdidf(u_quad_t);
sys/random/mersenne.c:double random_real(void)
sys/random/mersenne.c:double random_real_inclusive(void)
sys/random/mersenne.c:double random_real_exclusive(void)
sys/random/mersenne.c:    return ((double) random_uint32() + 0.5) * (1.0 / TWO_POW_32);
sys/random/mersenne.c:double random_res53(void)
sys/random/mersenne.c:    double a = random_uint32() * TWO_POW_26;
sys/random/mersenne.c:    double b = random_uint32() * (1.0 / TWO_POW_6);
sys/random/tinymt32/tinymt32.h:static inline double tinymt32_generate_32double(tinymt32_t *random)
sys/ubjson/ubjson-write.c:ssize_t ubjson_write_double(ubjson_cookie_t *restrict cookie, double value)
sys/ubjson/ubjson-write.c:        double f;
tests/bloom_bytes/main.c:    double false_positive_rate = (double) in / (double) lenA;
tests/float/main.c:    double x = 1234567.0 / 1024.0;
tests/float/main.c:        double z = (x - floor(x));
tests/thread_float/main.c:        printf("T(%" PRIkernel_pid "): %f\n", thread_getpid(), (double)f);
tests/unittests/tests-bloom/tests-bloom.c:    double false_positive_rate = 0;
tests/unittests/tests-bloom/tests-bloom.c:    false_positive_rate = (double) in / (double) lenA;
tests/unittests/tests-printf_float/tests-printf_float.c:static const double in0 = 2016.0349;
tests/unittests/tests-printf_float/tests-printf_float.c:static const double in1 = 123.4567;
tests/unittests/tests-printf_float/tests-printf_float.c:static const double in2 = 0.0;
tests/unittests/tests-sht1x/tests-sht1x.c:    static const double d1_table[] = { -40.1, -39.8, -39.7, -39.6, -39.4 };
tests/unittests/tests-sht1x/tests-sht1x.c:    double d1 = d1_table[dev->vdd];
tests/unittests/tests-sht1x/tests-sht1x.c:    double d2 = (dev->conf & SHT1X_CONF_LOW_RESOLUTION) ? 0.04 : 0.01;
tests/unittests/tests-sht1x/tests-sht1x.c:    double raw = (double)_raw;
tests/unittests/tests-sht1x/tests-sht1x.c:    double temp = d1 + d2 * raw;
tests/unittests/tests-sht1x/tests-sht1x.c:    static const double c1 = -2.0468;
tests/unittests/tests-sht1x/tests-sht1x.c:    static const double t1 = 0.01;
tests/unittests/tests-sht1x/tests-sht1x.c:    double temp = ((double)_temp) / 100.0;
tests/unittests/tests-sht1x/tests-sht1x.c:    double raw = (double)_raw;
tests/unittests/tests-sht1x/tests-sht1x.c:    double c2, c3, t2, hum_linear, hum_real;


概括

cpu/esp32/vendor/esp-idf/include/esp32/esp_mesh.h:    float percentage;           /**< vote percentage threshold for approval of being a root */
cpu/esp32/vendor/esp-idf/include/esp32/esp_mesh.h:esp_err_t esp_mesh_set_vote_percentage(float percentage);
cpu/esp32/vendor/esp-idf/include/esp32/esp_mesh.h:float esp_mesh_get_vote_percentage(void);
cpu/esp8266/vendor/esp/phy_info.c:           (float)info->spur_freq_primary / info->spur_freq_divisor,
cpu/esp8266/vendor/esp/phy_info.c:           (float)info->spur_freq_2_primary / info->spur_freq_2_divisor,
cpu/esp8266/vendor/espressif/c_types.h:typedef float               real32_t;
cpu/esp8266/vendor/espressif/c_types.h:typedef float               real32;
drivers/adt7310/adt7310.c:#define ADT7310_TEMPERATURE_LSB_FLOAT (1.f/((float)((int)1 << ADT7310_VALUE_FRAC_BITS)))
drivers/adt7310/adt7310.c:float adt7310_read_float(const adt7310_t *dev)
drivers/adt7310/adt7310.c:    return (((float) raw) * ADT7310_TEMPERATURE_LSB_FLOAT);
drivers/at30tse75x/at30tse75x.c:static inline float temperature_to_float(uint16_t temp)
drivers/at30tse75x/at30tse75x.c:int at30tse75x_get_temperature(const at30tse75x_t *dev, float *temperature)
drivers/hih6130/hih6130.c:    float *relative_humidity_percent, float *temperature_celsius)
drivers/include/adt7310.h:float adt7310_read_float(const adt7310_t *dev);
drivers/include/at30tse75x.h:int at30tse75x_get_temperature(const at30tse75x_t* dev, float* temperature);
drivers/include/hih6130.h:    float *relative_humidity_percent, float *temperature_celsius);
drivers/include/isl29020.h:    float lux_fac;              /**< factor to calculate actual lux value */
drivers/include/isl29125.h:    float red;              /**< red lux value */
drivers/include/isl29125.h:    float green;            /**< green lux value */
drivers/include/isl29125.h:    float blue;             /**< blue lux value */
drivers/include/tmp006.h:void tmp006_convert(int16_t rawv, int16_t rawt,  float *tamb, float *tobj);
drivers/io1_xplained/io1_xplained_saul.c:static float temperature;
drivers/isl29020/isl29020.c:    dev->lux_fac = (float)((1 << (10 + (2 * DEV_RANGE))) - 1) / 0xffff;
drivers/isl29125/isl29125.c:    float luxfactor = (DEV_RANGE == ISL29125_RANGE_10K) ? 10000.0 / 65535.0 : 375.0 / 65535.0;
drivers/lpsxxx/lpsxxx.c:    float res = TEMP_BASE;      /* reference value -> see datasheet */
drivers/lpsxxx/lpsxxx.c:    res += ((float)val) / TEMP_DIVIDER;
drivers/mpu9150/mpu9150.c:    float fsr;
drivers/mpu9150/mpu9150.c:    float fsr;
drivers/mpu9150/mpu9150.c:    output->x_axis = (int16_t) (((float)output->x_axis) *
drivers/mpu9150/mpu9150.c:    output->y_axis = (int16_t) (((float)output->y_axis) *
drivers/mpu9150/mpu9150.c:    output->z_axis = (int16_t) (((float)output->z_axis) *
drivers/mq3/mq3.c:    float res = mq3_read_raw(dev);
drivers/tmp006/tmp006.c:void tmp006_convert(int16_t rawv, int16_t rawt,  float *tamb, float *tobj)
drivers/tmp006/tmp006.c:    float tamb, tobj;
sys/analog_util/adc_util.c:float adc_util_mapf(int sample, adc_res_t res, float min, float max)
sys/analog_util/dac_util.c:uint16_t dac_util_mapf(float value, float min, float max)
sys/color/color.c:    float rd, gd, bd, delta;
sys/color/color.c:    rd = (float)rgb->r / 255.0f;
sys/color/color.c:    gd = (float)rgb->g / 255.0f;
sys/color/color.c:    bd = (float)rgb->b / 255.0f;
sys/color/color.c:        float rc, gc, bc;
sys/color/color.c:    float aa, bb, cc, f, h;
sys/fmt/fmt.c:size_t fmt_float(char *out, float f, unsigned precision)
sys/fmt/fmt.c:void print_float(float f, unsigned precision)
sys/include/analog_util.h:float adc_util_mapf(int sample, adc_res_t res, float min, float max);
sys/include/analog_util.h:uint16_t dac_util_mapf(float value, float min, float max);
sys/include/color.h:    float h;            /**< hue value        [0.0 - 360.0] */
sys/include/color.h:    float s;            /**< saturation value [0.0 - 1.0] */
sys/include/color.h:    float v;            /**< value            [0.0 - 1.0] */
sys/include/ubjson.h:static inline ssize_t ubjson_get_float(ubjson_cookie_t *__restrict cookie, ssize_t content, float *dest)
sys/include/ubjson.h:        float f;
sys/include/ubjson.h:ssize_t ubjson_write_float(ubjson_cookie_t *__restrict cookie, float value);
sys/quad_math/fixsfdi.c:quad_t __fixsfdi(float x)
sys/quad_math/fixunssfdi.c:u_quad_t __fixunssfdi(float f)
sys/quad_math/floatdisf.c:float __floatdisf(quad_t x)
sys/quad_math/floatdisf.c:    float f;
sys/quad_math/quad.h:quad_t __fixsfdi(float);
sys/quad_math/quad.h:u_quad_t __fixunssfdi(float);
sys/quad_math/quad.h:float __floatdisf(quad_t);
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_temper_conv(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:        float f;
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_temper_conv_open(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:        float f;
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_generate_float(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_generate_float12(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_generate_float01(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_generate_floatOC(tinymt32_t *random)
sys/random/tinymt32/tinymt32.h:static inline float tinymt32_generate_floatOO(tinymt32_t *random)
sys/shell/commands/sc_at30tse75x.c:            float temperature;
sys/ubjson/ubjson-write.c:ssize_t ubjson_write_float(ubjson_cookie_t *restrict cookie, float value)
sys/ubjson/ubjson-write.c:        float f;
tests/driver_adt7310/main.c:    float celsius_float;
tests/driver_adt7310/main.c:    float integral = 0;
tests/driver_adt7310/main.c:    float fractional;
tests/driver_hih6130/main.c:        float hum = 0.f;
tests/driver_hih6130/main.c:        float temp = 0.f;
tests/driver_hih6130/main.c:        float integral = 0.f;
tests/driver_hih6130/main.c:        float fractional;
tests/driver_io1_xplained/main.c:    float temperature;
tests/driver_tmp006/main.c:    float tamb, tobj;
tests/pkg_cmsis-dsp/main.c:    float int_part;
tests/pkg_cmsis-dsp/main.c:    float frac_part = fabsf(modff(variance, &int_part));
tests/rng/test.c:    float entropy = 0.0;
tests/rng/test.c:            float count = (float) buffer[i] / (float) length;
tests/rng/test.h:#define log2f(x) (logf (x) / (float) 0.693147180559945309417)
tests/thread_float/main.c:    float f, init;
tests/thread_float/main.c:    float f, init;
tests/unittests/tests-scanf_float/tests-scanf_float.c:    float x = 0;\
tests/unittests/tests-scanf_float/tests-scanf_float.c:    float x = 0;
tests/unittests/tests-scanf_float/tests-scanf_float.c:    float x = 0;

现在怎么办?

双打应该消失。 我相信这很清楚。

传感器驱动程序中有浮点使用。 这在我看来是错误的。 驱动程序应该有一个层负责从设备检索数据。 该层没有业务进行浮点计算。 在任何情况下,即使在像 mpu9150 这样的传感器的情况下,也不需要浮点数,其中值可以完全使用整数数学来完美表达和操作。

drivers sys bug

所有5条评论

感兴趣的! 我想在这个问题上工作。

谢谢@garrettluu! 期待你的 PR。 一个好的方法是为每个固定/更新的模块打开一个 PR。
并且不要忘记查看我们的贡献者指南

新来的,什么是模块? 例如,整个驱动程序文件夹是一个模块,还是驱动程序文件夹中的每个文件夹都是一个模块? @aabadie

驱动程序文件夹中的每个文件夹都是一个模块吗?

大多数是的。 如果您为每个驱动程序打开一个 PR,将更容易验证没有损坏:每个 PR 只有一个驱动程序要审查/测试。

为 sx127x 驱动程序创建的 PR 草案,但我不确定如何在没有合适板的情况下测试或至少编译我的更改。

此页面是否有帮助?
0 / 5 - 0 等级