From 16e250604fb4ad34f540ebdd4f35a657c65b044c Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 09:17:50 +0200 Subject: [PATCH 1/8] build system: Add float_math feature This adds the float_math feature to express that math on floating point numbers is supported. All CPUs but native provide this, to reflect that apps using floats on native will randomly fail See https://github.com/RIOT-OS/RIOT/issues/495 Co-authored-by: crasbe --- cpu/arm7_common/Makefile.features | 1 + cpu/atmega_common/Makefile.features | 6 ++++-- cpu/cortexm_common/Makefile.features | 1 + cpu/esp_common/Makefile.features | 1 + cpu/msp430/Makefile.features | 6 +++--- cpu/riscv_common/Makefile.features | 1 + features.yaml | 3 +++ makefiles/features_existing.inc.mk | 1 + makefiles/features_modules.inc.mk | 3 +++ makefiles/pseudomodules.inc.mk | 1 + 10 files changed, 19 insertions(+), 5 deletions(-) diff --git a/cpu/arm7_common/Makefile.features b/cpu/arm7_common/Makefile.features index bb88c29bc811..d9542de557a9 100644 --- a/cpu/arm7_common/Makefile.features +++ b/cpu/arm7_common/Makefile.features @@ -5,6 +5,7 @@ FEATURES_PROVIDED += arch_32bit FEATURES_PROVIDED += arch_arm FEATURES_PROVIDED += arch_arm7 FEATURES_PROVIDED += cpp +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += libstdcpp FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_pm diff --git a/cpu/atmega_common/Makefile.features b/cpu/atmega_common/Makefile.features index 5520c13a2b41..33d7db79e0ab 100644 --- a/cpu/atmega_common/Makefile.features +++ b/cpu/atmega_common/Makefile.features @@ -3,10 +3,10 @@ include $(RIOTCPU)/avr8_common/Makefile.features # common feature are defined in avr8_common/Makefile.features # Only add Additional features -FEATURES_PROVIDED += cpu_core_atmega FEATURES_PROVIDED += atmega_pcint0 +FEATURES_PROVIDED += cpu_core_atmega +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += periph_eeprom -FEATURES_PROVIDED += periph_gpio periph_gpio_irq FEATURES_PROVIDED += periph_gpio_ll FEATURES_PROVIDED += periph_gpio_ll_input_pull_up FEATURES_PROVIDED += periph_gpio_ll_irq @@ -14,6 +14,8 @@ FEATURES_PROVIDED += periph_gpio_ll_irq_edge_triggered_both FEATURES_PROVIDED += periph_gpio_ll_irq_level_triggered_low FEATURES_PROVIDED += periph_gpio_ll_irq_unmask FEATURES_PROVIDED += periph_gpio_ll_switch_dir +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_gpio_irq FEATURES_PROVIDED += periph_pm FEATURES_PROVIDED += periph_rtc_ms FEATURES_PROVIDED += periph_rtt_overflow diff --git a/cpu/cortexm_common/Makefile.features b/cpu/cortexm_common/Makefile.features index 1e6056dcf3c0..b37a80273289 100644 --- a/cpu/cortexm_common/Makefile.features +++ b/cpu/cortexm_common/Makefile.features @@ -6,6 +6,7 @@ FEATURES_PROVIDED += cpp FEATURES_PROVIDED += cpu_check_address FEATURES_PROVIDED += cpu_core_cortexm FEATURES_PROVIDED += dbgpin +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += libstdcpp FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_flashpage_aux diff --git a/cpu/esp_common/Makefile.features b/cpu/esp_common/Makefile.features index 4a203aacda42..13d17ac9a39d 100644 --- a/cpu/esp_common/Makefile.features +++ b/cpu/esp_common/Makefile.features @@ -4,6 +4,7 @@ FEATURES_PROVIDED += arch_32bit FEATURES_PROVIDED += arch_esp FEATURES_PROVIDED += cpp FEATURES_PROVIDED += esp_spiffs +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += libstdcpp FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_cpuid diff --git a/cpu/msp430/Makefile.features b/cpu/msp430/Makefile.features index a272d3665da1..a39d05aac22c 100644 --- a/cpu/msp430/Makefile.features +++ b/cpu/msp430/Makefile.features @@ -17,13 +17,13 @@ FEATURES_PROVIDED += arch_msp430 FEATURES_PROVIDED += bug_newlib_broken_stdio FEATURES_PROVIDED += cpu_$(CPU_FAM) FEATURES_PROVIDED += dbgpin +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_flashpage FEATURES_PROVIDED += periph_flashpage_in_address_space FEATURES_PROVIDED += periph_flashpage_pagewise -FEATURES_PROVIDED += periph_pm -FEATURES_PROVIDED += periph_timer_query_freqs - FEATURES_PROVIDED += periph_gpio_ll FEATURES_PROVIDED += periph_gpio_ll_irq FEATURES_PROVIDED += periph_gpio_ll_switch_dir +FEATURES_PROVIDED += periph_pm +FEATURES_PROVIDED += periph_timer_query_freqs diff --git a/cpu/riscv_common/Makefile.features b/cpu/riscv_common/Makefile.features index f48285ffeee5..954f587a727f 100644 --- a/cpu/riscv_common/Makefile.features +++ b/cpu/riscv_common/Makefile.features @@ -6,6 +6,7 @@ FEATURES_PROVIDED += arch_32bit FEATURES_PROVIDED += arch_riscv FEATURES_PROVIDED += bug_newlib_broken_stdio FEATURES_PROVIDED += cpp +FEATURES_PROVIDED += float_math FEATURES_PROVIDED += libstdcpp FEATURES_PROVIDED += newlib FEATURES_PROVIDED += periph_coretimer diff --git a/features.yaml b/features.yaml index 7113af63e6c5..b22446021c2f 100644 --- a/features.yaml +++ b/features.yaml @@ -468,6 +468,9 @@ groups: a mandatory requirement to build Rust code. - name: emulator_renode help: The platform is compatible with the Renode emulator. + - name: float_math + help: The use of float point math is possible. This requires either a + hardware FPU or a working software FPU. - title: Peripheral Features help: These features indicate presence of peripheral IP block, presence of diff --git a/makefiles/features_existing.inc.mk b/makefiles/features_existing.inc.mk index 6420ccd089cd..bfc975773464 100644 --- a/makefiles/features_existing.inc.mk +++ b/makefiles/features_existing.inc.mk @@ -129,6 +129,7 @@ FEATURES_EXISTING := \ esp_wifi_ap \ esp_wifi_enterprise \ feather_shield \ + float_math \ gecko_sdk_librail_fpu \ gecko_sdk_librail_nonfpu \ highlevel_stdio \ diff --git a/makefiles/features_modules.inc.mk b/makefiles/features_modules.inc.mk index 975cf003c0c2..0e7464a5cf11 100644 --- a/makefiles/features_modules.inc.mk +++ b/makefiles/features_modules.inc.mk @@ -124,6 +124,9 @@ USEMODULE += $(filter vdd_lc_filter_%,$(FEATURES_USED)) # select arduino_pwm pseudomodule if the corresponding feature is used USEMODULE += $(filter arduino_pwm, $(FEATURES_USED)) +# select float_math pseudomodule when corresponding feature is used +USEMODULE += $(filter float_math, $(FEATURES_USED)) + # always register a peripheral driver as a required feature when the corresponding # module is requested PERIPH_IGNORE_MODULES += periph_usbdev_clk periph_gpio_mock periph_gpio_linux periph_spidev_linux diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index cfc84f7fbe4c..e23ec6914c2a 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -79,6 +79,7 @@ PSEUDOMODULES += event_timeout_ztimer PSEUDOMODULES += evtimer_mbox PSEUDOMODULES += fatfs_vfs_format PSEUDOMODULES += fdcan +PSEUDOMODULES += float_math PSEUDOMODULES += fmt_% PSEUDOMODULES += gcoap_forward_proxy PSEUDOMODULES += gcoap_forward_proxy_thread From 1a9a192016d6fb39d464e319a266d309f7766f01 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 09:48:34 +0200 Subject: [PATCH 2/8] drivers: require float_math feature where needed --- drivers/adt7310/Makefile.dep | 1 + drivers/apds99xx/Makefile.dep | 1 + drivers/at30tse75x/Makefile.dep | 4 +++- drivers/bme680/Makefile.dep | 1 + drivers/bmp180/Makefile.dep | 1 + drivers/ccs811/Makefile.dep | 1 + drivers/io1_xplained/Makefile.dep | 4 +++- drivers/isl29125/Makefile.dep | 1 + drivers/kw41zrf/Makefile.dep | 1 + drivers/scd30/Makefile.dep | 1 + drivers/sps30/Makefile.dep | 1 + drivers/sx127x/Makefile.dep | 1 + drivers/sx1280/Makefile.dep | 3 +++ drivers/tmp00x/Makefile.dep | 1 + 14 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/adt7310/Makefile.dep b/drivers/adt7310/Makefile.dep index 6f0dd3d6c3c4..d540c003ae33 100644 --- a/drivers/adt7310/Makefile.dep +++ b/drivers/adt7310/Makefile.dep @@ -1 +1,2 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_spi diff --git a/drivers/apds99xx/Makefile.dep b/drivers/apds99xx/Makefile.dep index eb960043325d..8db6c5c66198 100644 --- a/drivers/apds99xx/Makefile.dep +++ b/drivers/apds99xx/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c ifneq (,$(filter apds99%full,$(USEMODULE))) diff --git a/drivers/at30tse75x/Makefile.dep b/drivers/at30tse75x/Makefile.dep index 7211545eb54c..83327ed035ac 100644 --- a/drivers/at30tse75x/Makefile.dep +++ b/drivers/at30tse75x/Makefile.dep @@ -1,2 +1,4 @@ -USEMODULE += ztimer_usec +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c + +USEMODULE += ztimer_usec diff --git a/drivers/bme680/Makefile.dep b/drivers/bme680/Makefile.dep index 69968ce08a18..28a8f3997575 100644 --- a/drivers/bme680/Makefile.dep +++ b/drivers/bme680/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math USEPKG += driver_bme680 ifneq (,$(filter saul%,$(USEMODULE))) diff --git a/drivers/bmp180/Makefile.dep b/drivers/bmp180/Makefile.dep index 40e4e2276caa..abfbf151c7e5 100644 --- a/drivers/bmp180/Makefile.dep +++ b/drivers/bmp180/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c USEMODULE += ztimer USEMODULE += ztimer_msec diff --git a/drivers/ccs811/Makefile.dep b/drivers/ccs811/Makefile.dep index 0fd0f94c8633..901778928066 100644 --- a/drivers/ccs811/Makefile.dep +++ b/drivers/ccs811/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_gpio FEATURES_REQUIRED += periph_i2c USEMODULE += ztimer diff --git a/drivers/io1_xplained/Makefile.dep b/drivers/io1_xplained/Makefile.dep index 3e4cc2f23b20..585be6672390 100644 --- a/drivers/io1_xplained/Makefile.dep +++ b/drivers/io1_xplained/Makefile.dep @@ -1,4 +1,6 @@ -FEATURES_REQUIRED += periph_gpio +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_adc +FEATURES_REQUIRED += periph_gpio + USEMODULE += at30tse75x USEMODULE += sdcard_spi diff --git a/drivers/isl29125/Makefile.dep b/drivers/isl29125/Makefile.dep index ef9d5eb454ee..0dfb820a1a31 100644 --- a/drivers/isl29125/Makefile.dep +++ b/drivers/isl29125/Makefile.dep @@ -1,2 +1,3 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_gpio_irq FEATURES_REQUIRED += periph_i2c diff --git a/drivers/kw41zrf/Makefile.dep b/drivers/kw41zrf/Makefile.dep index 5e2a52d7c4f9..dc64717600a0 100644 --- a/drivers/kw41zrf/Makefile.dep +++ b/drivers/kw41zrf/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math USEMODULE += ieee802154 USEMODULE += netdev_ieee802154 USEMODULE += netdev_legacy_api diff --git a/drivers/scd30/Makefile.dep b/drivers/scd30/Makefile.dep index c237d318a844..3e124f5f288a 100644 --- a/drivers/scd30/Makefile.dep +++ b/drivers/scd30/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c USEMODULE += checksum USEMODULE += xtimer diff --git a/drivers/sps30/Makefile.dep b/drivers/sps30/Makefile.dep index 46470c82a446..9fa9850586bd 100644 --- a/drivers/sps30/Makefile.dep +++ b/drivers/sps30/Makefile.dep @@ -1,2 +1,3 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c USEMODULE += checksum diff --git a/drivers/sx127x/Makefile.dep b/drivers/sx127x/Makefile.dep index 42eed37846e6..08630abfe594 100644 --- a/drivers/sx127x/Makefile.dep +++ b/drivers/sx127x/Makefile.dep @@ -1,3 +1,4 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_gpio FEATURES_REQUIRED += periph_gpio_irq FEATURES_REQUIRED += periph_spi diff --git a/drivers/sx1280/Makefile.dep b/drivers/sx1280/Makefile.dep index c970b0ea28c6..5baf4992073f 100644 --- a/drivers/sx1280/Makefile.dep +++ b/drivers/sx1280/Makefile.dep @@ -1,3 +1,6 @@ +FEATURES_REQUIRED += float_math + USEPKG += lorabasics + USEMODULE += lorabasics_sx1280_driver USEMODULE += netdev_legacy_api diff --git a/drivers/tmp00x/Makefile.dep b/drivers/tmp00x/Makefile.dep index 9508a8aff76e..2f7740c742e0 100644 --- a/drivers/tmp00x/Makefile.dep +++ b/drivers/tmp00x/Makefile.dep @@ -1,2 +1,3 @@ +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += periph_i2c USEMODULE += xtimer From 4b1259986548ffd8087c08018595165ba9833ebf Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 09:50:47 +0200 Subject: [PATCH 3/8] sys: require float_math feature where needed In some modules some functions are disabled when no floating point arithmetics is available instead of blocking the whole module. The API doc has been extended, so that users know why a function may fail to link. Co-authored-by: crasbe --- sys/Makefile.dep | 8 ++++++++ sys/analog_util/adc_util.c | 3 +++ sys/analog_util/dac_util.c | 3 +++ sys/fmt/fmt.c | 29 ++++++++++++++++------------- sys/include/analog_util.h | 6 ++++++ sys/include/fmt.h | 3 +++ sys/senml/Makefile.dep | 2 ++ 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/sys/Makefile.dep b/sys/Makefile.dep index aad221f7188e..7f6778fe6170 100644 --- a/sys/Makefile.dep +++ b/sys/Makefile.dep @@ -29,6 +29,10 @@ ifneq (,$(filter auto_init_sock_dns,$(USEMODULE))) endif endif +ifneq (,$(filter color,$(USEMODULE))) + FEATURES_REQUIRED += float_math +endif + ifneq (,$(filter congure_%,$(USEMODULE))) USEMODULE += congure endif @@ -259,6 +263,10 @@ ifneq (,$(filter posix_sockets,$(USEMODULE))) USEMODULE += posix_headers endif +ifneq (,$(filter printf_float,$(USEMODULE))) + FEATURES_REQUIRED += float_math +endif + ifneq (,$(filter shell_cmd%,$(USEMODULE))) # each and every command is a submodule of shell_cmds USEMODULE += shell_cmds diff --git a/sys/analog_util/adc_util.c b/sys/analog_util/adc_util.c index 1860716197b2..f0958c9571fc 100644 --- a/sys/analog_util/adc_util.c +++ b/sys/analog_util/adc_util.c @@ -66,7 +66,10 @@ int32_t adc_util_map(int sample, adc_res_t res, int32_t min, int32_t max) return (min + scaled); } +/* only pro adc_util_mapf if float_math is in use */ +#if MODULE_FLOAT_MATH float adc_util_mapf(int sample, adc_res_t res, float min, float max) { return ((((max - min) * sample) / ((int32_t)1L << _adc_res_bits(res))) + min); } +#endif diff --git a/sys/analog_util/dac_util.c b/sys/analog_util/dac_util.c index f55af94df6b0..a6c2b49de647 100644 --- a/sys/analog_util/dac_util.c +++ b/sys/analog_util/dac_util.c @@ -27,7 +27,10 @@ uint16_t dac_util_map(int value, int min, int max) return (uint16_t)(((value - min) * UINT16_MAX) / (max - min)); } +/* only provide dac_util_mapf when floating point arithmetic is available */ +#if MODULE_FLOAT_MATH uint16_t dac_util_mapf(float value, float min, float max) { return (uint16_t)(((value - min) * UINT16_MAX) / (max - min)); } +#endif diff --git a/sys/fmt/fmt.c b/sys/fmt/fmt.c index 199cd9c0f85d..60cd393cf030 100644 --- a/sys/fmt/fmt.c +++ b/sys/fmt/fmt.c @@ -37,19 +37,6 @@ extern ssize_t stdio_write(const void* buffer, size_t len); NONSTRING static const char _hex_chars[16] = "0123456789ABCDEF"; -static const uint32_t _tenmap[] = { - 0, - 10LU, - 100LU, - 1000LU, - 10000LU, - 100000LU, - 1000000LU, - 10000000LU, -}; - -#define TENMAP_SIZE ARRAY_SIZE(_tenmap) - static inline char _to_lower(char c) { return 'a' + (c - 'A'); @@ -377,6 +364,21 @@ size_t fmt_s32_dfp(char *out, int32_t val, int scale) return pos; } + +#if MODULE_FLOAT_MATH +static const uint32_t _tenmap[] = { + 0, + 10LU, + 100LU, + 1000LU, + 10000LU, + 100000LU, + 1000000LU, + 10000000LU, +}; + +# define TENMAP_SIZE ARRAY_SIZE(_tenmap) + /* this is very probably not the most efficient implementation, as it at least * pulls in floating point math. But it works, and it's always nice to have * low hanging fruits when optimizing. (Kaspar) @@ -415,6 +417,7 @@ size_t fmt_float(char *out, float f, unsigned precision) return res; } +#endif size_t fmt_lpad(char *out, size_t in_len, size_t pad_len, char pad_char) { diff --git a/sys/include/analog_util.h b/sys/include/analog_util.h index e359833770a9..f8bfbd49de25 100644 --- a/sys/include/analog_util.h +++ b/sys/include/analog_util.h @@ -47,6 +47,9 @@ int32_t adc_util_map(int sample, adc_res_t res, int32_t min, int32_t max); * @brief Map a sampled ADC value to a given range (using floating point * arithmetic) * + * @warning This function is only available when the features `float_math` + * is used. + * * @see adc_util_map * * @param[in] sample sampled ADC value @@ -75,6 +78,9 @@ uint16_t dac_util_map(int value, int min, int max); /** * @brief Helper function to map a given float value range to a valid DAC value. * + * @warning This function is only available when the features `float_math` + * is used. + * * @see dac_util_map * * @param[in] value value to map to a DAC set value diff --git a/sys/include/fmt.h b/sys/include/fmt.h index 75a36a764861..da7f9ab96ef5 100644 --- a/sys/include/fmt.h +++ b/sys/include/fmt.h @@ -326,6 +326,9 @@ size_t fmt_s32_dfp(char *out, int32_t val, int scale); /** * @brief Format float to string * + * @warning This function is only available when the features `float_math` + * is used. + * * Converts float value @p f to string * * If @p out is NULL, will only return the number of characters that would have diff --git a/sys/senml/Makefile.dep b/sys/senml/Makefile.dep index 175f11280585..c0bbc4b115f1 100644 --- a/sys/senml/Makefile.dep +++ b/sys/senml/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + ifneq (,$(filter senml_saul,$(USEMODULE))) USEMODULE += senml_cbor USEMODULE += senml_phydat From fc3a860e6384930cb8619924bb891b303d16abb5 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 16:30:35 +0200 Subject: [PATCH 4/8] tests: require float_math where needed --- tests/core/thread_float/Makefile | 2 ++ tests/core/thread_stack_alignment/Makefile | 2 ++ tests/net/gnrc_sock_ip/Makefile.ci | 2 +- tests/sys/cpp11_mutex/Makefile | 3 +++ tests/sys/cpp11_thread/Makefile | 3 +++ tests/sys/float/Makefile | 2 ++ tests/sys/fmt_print/Makefile | 3 +++ tests/sys/fmt_print/main.c | 8 +++++++- tests/sys/fmt_print/tests/01-run.py | 2 +- tests/sys/rng/Makefile | 3 +++ tests/unittests/Makefile | 11 +++++------ tests/unittests/tests-analog_util/Makefile.include | 2 ++ tests/unittests/tests-phydat/Makefile.include | 2 ++ tests/unittests/tests-printf_float/Makefile.include | 2 ++ tests/unittests/tests-scanf_float/Makefile.include | 2 ++ tests/unittests/tests-sht1x/Makefile.include | 2 ++ 16 files changed, 42 insertions(+), 9 deletions(-) diff --git a/tests/core/thread_float/Makefile b/tests/core/thread_float/Makefile index 4ef301583e5d..32655e7f8307 100644 --- a/tests/core/thread_float/Makefile +++ b/tests/core/thread_float/Makefile @@ -1,5 +1,7 @@ include ../Makefile.core_common +FEATURES_REQUIRED += float_math + USEMODULE += printf_float USEMODULE += ztimer_usec diff --git a/tests/core/thread_stack_alignment/Makefile b/tests/core/thread_stack_alignment/Makefile index f115224043be..18c12b169149 100644 --- a/tests/core/thread_stack_alignment/Makefile +++ b/tests/core/thread_stack_alignment/Makefile @@ -1,5 +1,7 @@ include ../Makefile.core_common +FEATURES_REQUIRED += float_math + USEMODULE += printf_float # On ESP* a custom sched_task_exit() is used that does not implement diff --git a/tests/net/gnrc_sock_ip/Makefile.ci b/tests/net/gnrc_sock_ip/Makefile.ci index cc9d2e953b14..595b851cdecc 100644 --- a/tests/net/gnrc_sock_ip/Makefile.ci +++ b/tests/net/gnrc_sock_ip/Makefile.ci @@ -7,12 +7,12 @@ BOARD_INSUFFICIENT_MEMORY := \ atmega328p-xplained-mini \ atmega8 \ msb-430 \ + msb-430h \ nucleo-c031c6 \ nucleo-f031k6 \ nucleo-f042k6 \ nucleo-l011k4 \ nucleo-l031k6 \ - msb-430h \ olimex-msp430-h1611 \ samd10-xmini \ stk3200 \ diff --git a/tests/sys/cpp11_mutex/Makefile b/tests/sys/cpp11_mutex/Makefile index aaca5737ec07..6941ff2c3997 100644 --- a/tests/sys/cpp11_mutex/Makefile +++ b/tests/sys/cpp11_mutex/Makefile @@ -1,5 +1,8 @@ include ../Makefile.sys_common +# std::chrono uses floating point math +FEATURES_REQUIRED += float_math + USEMODULE += cpp11-compat USEMODULE += libc_gettimeofday diff --git a/tests/sys/cpp11_thread/Makefile b/tests/sys/cpp11_thread/Makefile index e9ff8c0ba570..372db7b9e2c3 100644 --- a/tests/sys/cpp11_thread/Makefile +++ b/tests/sys/cpp11_thread/Makefile @@ -1,5 +1,8 @@ include ../Makefile.sys_common +# std::chrono uses floating point math +FEATURES_REQUIRED += float_math + USEMODULE += cpp11-compat USEMODULE += ztimer64_usec USEMODULE += timex diff --git a/tests/sys/float/Makefile b/tests/sys/float/Makefile index 474ad5124a4c..8e26a76f0436 100644 --- a/tests/sys/float/Makefile +++ b/tests/sys/float/Makefile @@ -1,3 +1,5 @@ include ../Makefile.sys_common +FEATURES_REQUIRED += float_math + include $(RIOTBASE)/Makefile.include diff --git a/tests/sys/fmt_print/Makefile b/tests/sys/fmt_print/Makefile index 2c90bdedb40e..b0209f0da593 100644 --- a/tests/sys/fmt_print/Makefile +++ b/tests/sys/fmt_print/Makefile @@ -1,5 +1,8 @@ include ../Makefile.sys_common +# Needed for print_float +FEATURES_OPTIONAL += float_math + USEMODULE += fmt include $(RIOTBASE)/Makefile.include diff --git a/tests/sys/fmt_print/main.c b/tests/sys/fmt_print/main.c index d32b93e0d1be..82fb6c684b66 100644 --- a/tests/sys/fmt_print/main.c +++ b/tests/sys/fmt_print/main.c @@ -23,6 +23,7 @@ #include #include "fmt.h" +#include "modules.h" int main(void) { @@ -43,7 +44,12 @@ int main(void) print_str("\n"); print_s64_dec(0x8000000000000000); print_str("\n"); - print_float(1.2345, 5); + if (IS_USED(MODULE_FLOAT_MATH)) { + print_float(1.2345, 5); + } + else { + print_str("print_float() disabled, feature `float_math` not used."); + } print_str("\n"); print_bytes_hex("0123456789", 10); print_str("\n"); diff --git a/tests/sys/fmt_print/tests/01-run.py b/tests/sys/fmt_print/tests/01-run.py index 9be3826fe433..b48ccdd6e662 100755 --- a/tests/sys/fmt_print/tests/01-run.py +++ b/tests/sys/fmt_print/tests/01-run.py @@ -14,7 +14,7 @@ def testfunc(child): child.expect_exact('123456789ABCDEF0') child.expect_exact('18446744073709551615') child.expect_exact('-9223372036854775808') - child.expect_exact('1.23450') + child.expect(r'(1.23450)|(print_float\(\) disabled, feature `float_math` not used.)') child.expect_exact('30313233343536373839') child.expect_exact('Test successful.') diff --git a/tests/sys/rng/Makefile b/tests/sys/rng/Makefile index a0dc82f2bf94..fbe7158277d6 100644 --- a/tests/sys/rng/Makefile +++ b/tests/sys/rng/Makefile @@ -4,6 +4,9 @@ include ../Makefile.sys_common MAIN_THREAD_SIZE = THREAD_STACKSIZE_DEFAULT+THREAD_EXTRA_STACKSIZE_PRINTF+256 CFLAGS += -DTHREAD_STACKSIZE_MAIN=\($(MAIN_THREAD_SIZE)\) +# Using floating point arithmetic, e.g. log2f(), for entropy estimation +FEATURES_REQUIRED += float_math + # override PRNG if desired (see sys/random for alternatives) # USEMODULE += prng_minstd diff --git a/tests/unittests/Makefile b/tests/unittests/Makefile index 3899ed4d92d9..814d32bdef78 100644 --- a/tests/unittests/Makefile +++ b/tests/unittests/Makefile @@ -8,17 +8,16 @@ ifeq (, $(UNIT_TESTS)) # the $(dir) Makefile function leaves a trailing slash after the directory # name, therefore we use patsubst instead. UNIT_TESTS := $(patsubst %/Makefile,%,$(wildcard tests-*/Makefile)) + + # Ignore tests needing floats on native + ifneq (,$(filter native%,$(BOARD))) + UNIT_TESTS := $(filter-out tests-color tests-scanf_float tests-sht1x tests-printf_float,$(UNIT_TESTS)) + endif else UNIT_TESTS := $(filter tests-%, $(MAKECMDGOALS)) endif endif -ifeq (llvm,$(TOOLCHAIN)) - # the floating point exception bug is more likely to trigger when build - # with LLVM, so we just disable LLVM on native as a work around - TEST_ON_CI_BLACKLIST += native32 native64 -endif - DISABLE_MODULE += auto_init auto_init_% # boards using stdio via CDC ACM require auto_init to automatically diff --git a/tests/unittests/tests-analog_util/Makefile.include b/tests/unittests/tests-analog_util/Makefile.include index 96a456176791..a5cd7825de37 100644 --- a/tests/unittests/tests-analog_util/Makefile.include +++ b/tests/unittests/tests-analog_util/Makefile.include @@ -1 +1,3 @@ +FEATURES_OPTIONAL += float_math + USEMODULE += analog_util diff --git a/tests/unittests/tests-phydat/Makefile.include b/tests/unittests/tests-phydat/Makefile.include index 7583f4db7aaa..444e57fa766f 100644 --- a/tests/unittests/tests-phydat/Makefile.include +++ b/tests/unittests/tests-phydat/Makefile.include @@ -1 +1,3 @@ +FEATURES_OPTIONAL += float_math + USEMODULE += phydat diff --git a/tests/unittests/tests-printf_float/Makefile.include b/tests/unittests/tests-printf_float/Makefile.include index 4f383954c9af..f6ab198bf7b5 100644 --- a/tests/unittests/tests-printf_float/Makefile.include +++ b/tests/unittests/tests-printf_float/Makefile.include @@ -1 +1,3 @@ +FEATURES_REQUIRED += float_math + USEMODULE += printf_float diff --git a/tests/unittests/tests-scanf_float/Makefile.include b/tests/unittests/tests-scanf_float/Makefile.include index 2554170ca622..3ee1cbdcf71a 100644 --- a/tests/unittests/tests-scanf_float/Makefile.include +++ b/tests/unittests/tests-scanf_float/Makefile.include @@ -1 +1,3 @@ +FEATURES_REQUIRED += float_math + USEMODULE += scanf_float diff --git a/tests/unittests/tests-sht1x/Makefile.include b/tests/unittests/tests-sht1x/Makefile.include index 4ccfa29f725f..ff565670542d 100644 --- a/tests/unittests/tests-sht1x/Makefile.include +++ b/tests/unittests/tests-sht1x/Makefile.include @@ -1 +1,3 @@ +FEATURES_REQUIRED += float_math + USEMODULE += sht1x From b5d904ec0898ad81600bcac92c7623a3226828a4 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 17:19:35 +0200 Subject: [PATCH 5/8] sys/phydat: avoid use of pow() We just use a simple look-up table for the 10^x exponents that do not overflow the range of int16_t. In addition, we saturate on overflows. --- sys/phydat/phydat_unix.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/sys/phydat/phydat_unix.c b/sys/phydat/phydat_unix.c index aeee0450b671..0212a3d8a51f 100644 --- a/sys/phydat/phydat_unix.c +++ b/sys/phydat/phydat_unix.c @@ -7,8 +7,9 @@ */ #include -#include +#include "macros/math.h" +#include "container.h" #include "phydat.h" /** @@ -18,14 +19,36 @@ static int16_t month_to_yday[] = { 0, 31, -306, -275, -245, -214, -184, -153, -122, -92, -61, -31 }; -static inline int16_t phydat_unscale(int16_t value, int16_t scale) +static int16_t phydat_unscale(int16_t value, int16_t scale) { + static const int16_t tenmap[] = {10, 100, 1000, 10000 }; + + if (value == 0) { + return 0; + } + + /* when out of range anyway, we just saturate to max */ + if (scale > (int16_t)ARRAY_SIZE(tenmap)) { + return INT16_MAX; + } + + /* same, but lower end of the range */ + if (scale < -(int16_t)ARRAY_SIZE(tenmap)) { + return 0; + } + if (scale > 0) { - return value * pow(10, scale); + size_t idx = scale - 1; + if (__builtin_mul_overflow(value, tenmap[idx], &value)) { + /* result would overflow, returning INT16_MAX instead */ + return INT16_MAX; + } + return value; } if (scale < 0) { - return value / pow(10, -scale); + size_t idx = (-scale) - 1; + return DIV_ROUND(value, tenmap[idx]); } return value; From 73f416081cd3de952582cd967768db1f687935ab Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 20:48:54 +0200 Subject: [PATCH 6/8] pkg: require float_math where needed --- pkg/cayenne-lpp/Makefile.dep | 1 + pkg/ccn-lite/Makefile.dep | 2 + pkg/cn-cbor/Makefile.dep | 2 + pkg/emlearn/Makefile.dep | 2 + pkg/flatbuffers/Makefile.dep | 2 + pkg/jerryscript/Makefile.dep | 2 + pkg/libfixmath/Makefile.dep | 2 + pkg/libschc/Makefile.dep | 2 + pkg/lora-serialization/Makefile.dep | 1 + pkg/lvgl/Makefile.dep | 2 + pkg/micropython/Makefile.dep | 2 + pkg/minmea/Makefile.dep | 1 + pkg/mjson/Makefile.dep | 1 + pkg/nanocbor/Makefile.dep | 1 + pkg/nanocbor/Makefile.include | 5 + ...g-Allow-disabling-of-float-arithmitc.patch | 109 ++++++++++++++++++ pkg/qcbor/Makefile.dep | 1 + pkg/tflite-micro/Makefile.dep | 3 +- pkg/tinycbor/Makefile.dep | 2 + pkg/utensor/Makefile.dep | 1 + pkg/wakaama/Makefile.dep | 2 + pkg/wamr/Makefile.dep | 2 + 22 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 pkg/cayenne-lpp/Makefile.dep create mode 100644 pkg/lora-serialization/Makefile.dep create mode 100644 pkg/minmea/Makefile.dep create mode 100644 pkg/mjson/Makefile.dep create mode 100644 pkg/nanocbor/Makefile.dep create mode 100644 pkg/nanocbor/patches/0001-config-Allow-disabling-of-float-arithmitc.patch diff --git a/pkg/cayenne-lpp/Makefile.dep b/pkg/cayenne-lpp/Makefile.dep new file mode 100644 index 000000000000..9cf263a16b95 --- /dev/null +++ b/pkg/cayenne-lpp/Makefile.dep @@ -0,0 +1 @@ +FEATURES_REQUIRED += float_math diff --git a/pkg/ccn-lite/Makefile.dep b/pkg/ccn-lite/Makefile.dep index b653879225eb..c097ee8e82ff 100644 --- a/pkg/ccn-lite/Makefile.dep +++ b/pkg/ccn-lite/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += ccn-lite-utils USEMODULE += gnrc_nettype_ccn USEMODULE += evtimer diff --git a/pkg/cn-cbor/Makefile.dep b/pkg/cn-cbor/Makefile.dep index ff9e6dbea54f..9a7dc49043d6 100644 --- a/pkg/cn-cbor/Makefile.dep +++ b/pkg/cn-cbor/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += posix_headers # CN-CBOR is only supported by 32 bit architectures diff --git a/pkg/emlearn/Makefile.dep b/pkg/emlearn/Makefile.dep index d4a21c581b36..9320da2e4560 100644 --- a/pkg/emlearn/Makefile.dep +++ b/pkg/emlearn/Makefile.dep @@ -1,2 +1,4 @@ +FEATURES_REQUIRED += float_math + # emlearn is not compatible with MSP430 FEATURES_BLACKLIST += arch_msp430 diff --git a/pkg/flatbuffers/Makefile.dep b/pkg/flatbuffers/Makefile.dep index 5648689939d0..aa45ef739810 100644 --- a/pkg/flatbuffers/Makefile.dep +++ b/pkg/flatbuffers/Makefile.dep @@ -1 +1,3 @@ +FEATURES_REQUIRED += float_math + USEMODULE += cpp11-compat diff --git a/pkg/jerryscript/Makefile.dep b/pkg/jerryscript/Makefile.dep index 5c9e84348354..331ca6e95de9 100644 --- a/pkg/jerryscript/Makefile.dep +++ b/pkg/jerryscript/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += jerryscript-port-default USEMODULE += jerryscript-ext diff --git a/pkg/libfixmath/Makefile.dep b/pkg/libfixmath/Makefile.dep index c249341fc07d..7bc47da2dc8e 100644 --- a/pkg/libfixmath/Makefile.dep +++ b/pkg/libfixmath/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + ifneq (,$(filter libfixmath-unittests,$(USEMODULE))) # libfixmath unittests use shift operand incompatible with 8bit # architecture int type. diff --git a/pkg/libschc/Makefile.dep b/pkg/libschc/Makefile.dep index 32df9c536be0..4bdbf474c274 100644 --- a/pkg/libschc/Makefile.dep +++ b/pkg/libschc/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + ifneq (,$(filter libschc_%,$(USEMODULE))) USEPKG += libschc endif diff --git a/pkg/lora-serialization/Makefile.dep b/pkg/lora-serialization/Makefile.dep new file mode 100644 index 000000000000..9cf263a16b95 --- /dev/null +++ b/pkg/lora-serialization/Makefile.dep @@ -0,0 +1 @@ +FEATURES_REQUIRED += float_math diff --git a/pkg/lvgl/Makefile.dep b/pkg/lvgl/Makefile.dep index 7549fcf71e3e..b4914e6c0a93 100644 --- a/pkg/lvgl/Makefile.dep +++ b/pkg/lvgl/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += lvgl USEMODULE += lvgl_core USEMODULE += lvgl_draw diff --git a/pkg/micropython/Makefile.dep b/pkg/micropython/Makefile.dep index 603040cc7767..8fb4e450eb7a 100644 --- a/pkg/micropython/Makefile.dep +++ b/pkg/micropython/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += xtimer USEMODULE += stdin diff --git a/pkg/minmea/Makefile.dep b/pkg/minmea/Makefile.dep new file mode 100644 index 000000000000..9cf263a16b95 --- /dev/null +++ b/pkg/minmea/Makefile.dep @@ -0,0 +1 @@ +FEATURES_REQUIRED += float_math diff --git a/pkg/mjson/Makefile.dep b/pkg/mjson/Makefile.dep new file mode 100644 index 000000000000..9cf263a16b95 --- /dev/null +++ b/pkg/mjson/Makefile.dep @@ -0,0 +1 @@ +FEATURES_REQUIRED += float_math diff --git a/pkg/nanocbor/Makefile.dep b/pkg/nanocbor/Makefile.dep new file mode 100644 index 000000000000..edc409cef25f --- /dev/null +++ b/pkg/nanocbor/Makefile.dep @@ -0,0 +1 @@ +FEATURES_OPTIONAL += float_math diff --git a/pkg/nanocbor/Makefile.include b/pkg/nanocbor/Makefile.include index 2b766f2e7e76..02e1b83ef7b1 100644 --- a/pkg/nanocbor/Makefile.include +++ b/pkg/nanocbor/Makefile.include @@ -1,2 +1,7 @@ INCLUDES += -I$(RIOTPKG)/nanocbor/include INCLUDES += -I$(PKGDIRBASE)/nanocbor/include + +# Disable float functions if no float support is available +ifneq (,$(filter float_math,$(FEATURES_USED))) + CFLAGS += -DNANOCBOR_ENABLE_FLOAT=0 +endif diff --git a/pkg/nanocbor/patches/0001-config-Allow-disabling-of-float-arithmitc.patch b/pkg/nanocbor/patches/0001-config-Allow-disabling-of-float-arithmitc.patch new file mode 100644 index 000000000000..be5c55279fa1 --- /dev/null +++ b/pkg/nanocbor/patches/0001-config-Allow-disabling-of-float-arithmitc.patch @@ -0,0 +1,109 @@ +From e29136bb10b7d763d633341e213112759c6893a0 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Wed, 17 Sep 2025 21:36:01 +0200 +Subject: [PATCH] config: Allow disabling of float arithmitc + +This can be useful for toolchains that cannot compile with any float +arithmetic included. Otherwise with -ffunction-sections the linker would +garbage collect unused float support anyway. +--- + examples/pretty-printer/main.c | 4 ++++ + include/nanocbor/config.h | 7 +++++++ + src/decoder.c | 2 ++ + src/encoder.c | 3 +++ + 4 files changed, 16 insertions(+) + +diff --git a/examples/pretty-printer/main.c b/examples/pretty-printer/main.c +index 9508ecf..1811f0a 100644 +--- a/examples/pretty-printer/main.c ++++ b/examples/pretty-printer/main.c +@@ -144,6 +144,7 @@ static int _print_enter_array(nanocbor_value_t *value, unsigned indent) + return -1; + } + ++#if NANOCBOR_ENABLE_FLOAT + static int _print_float(nanocbor_value_t *value) + { + bool test = false; +@@ -173,6 +174,7 @@ static int _print_float(nanocbor_value_t *value) + } + return 0; + } ++#endif /* NANOCBOR_ENABLE_FLOAT */ + + /* NOLINTNEXTLINE(misc-no-recursion, readability-function-cognitive-complexity) */ + static int _parse_type(nanocbor_value_t *value, unsigned indent) +@@ -228,9 +230,11 @@ static int _parse_type(nanocbor_value_t *value, unsigned indent) + case NANOCBOR_TYPE_MAP: { + res = _print_enter_map(value, indent); + } break; ++#if NANOCBOR_ENABLE_FLOAT + case NANOCBOR_TYPE_FLOAT: { + res = _print_float(value); + } break; ++#endif /* NANOCBOR_ENABLE_FLOAT */ + case NANOCBOR_TYPE_TAG: { + uint32_t tag = 0; + int res = nanocbor_get_tag(value, &tag); +diff --git a/include/nanocbor/config.h b/include/nanocbor/config.h +index a9e5463..bf4e135 100644 +--- a/include/nanocbor/config.h ++++ b/include/nanocbor/config.h +@@ -79,6 +79,13 @@ extern "C" { + #endif + #endif + ++/** ++ * @brief enable/disable support for float/double values ++ */ ++#ifndef NANOCBOR_ENABLE_FLOAT ++#define NANOCBOR_ENABLE_FLOAT 1 ++#endif ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/decoder.c b/src/decoder.c +index 5820659..4a59e01 100644 +--- a/src/decoder.c ++++ b/src/decoder.c +@@ -368,6 +368,7 @@ int nanocbor_get_simple(nanocbor_value_t *cvalue, uint8_t *value) + return res; + } + ++#if NANOCBOR_ENABLE_FLOAT + /* float bit mask related defines */ + #define FLOAT_EXP_OFFSET (127U) + #define FLOAT_SIZE (32U) +@@ -475,6 +476,7 @@ int nanocbor_get_double(nanocbor_value_t *cvalue, double *value) + } + return _decode_double(cvalue, value); + } ++#endif /* NANOCBOR_ENABLE_FLOAT */ + + static int _enter_container(const nanocbor_value_t *it, + nanocbor_value_t *container, uint8_t type) +diff --git a/src/encoder.c b/src/encoder.c +index ec0a4f6..c548fbd 100644 +--- a/src/encoder.c ++++ b/src/encoder.c +@@ -230,6 +230,8 @@ int nanocbor_fmt_null(nanocbor_encoder_t *enc) + return _fmt_single(enc, NANOCBOR_MASK_FLOAT | NANOCBOR_SIMPLE_NULL); + } + ++#if NANOCBOR_TYPE_FLOAT ++ + /* Double bit mask related defines */ + #define DOUBLE_EXP_OFFSET (1023U) + #define DOUBLE_SIZE (64U) +@@ -393,6 +395,7 @@ int nanocbor_fmt_double(nanocbor_encoder_t *enc, double num) + return res; + #endif + } ++#endif /* NANOCBOR_TYPE_FLOAT */ + + int nanocbor_fmt_decimal_frac(nanocbor_encoder_t *enc, int32_t e, int32_t m) + { +-- +2.43.0 + diff --git a/pkg/qcbor/Makefile.dep b/pkg/qcbor/Makefile.dep index ddb8a6ad1db1..f238087e3661 100644 --- a/pkg/qcbor/Makefile.dep +++ b/pkg/qcbor/Makefile.dep @@ -1 +1,2 @@ FEATURES_REQUIRED_ANY += arch_32bit|arch_64bit +FEATURES_REQUIRED += float_math diff --git a/pkg/tflite-micro/Makefile.dep b/pkg/tflite-micro/Makefile.dep index b4cab0836b20..79af7fac6721 100644 --- a/pkg/tflite-micro/Makefile.dep +++ b/pkg/tflite-micro/Makefile.dep @@ -1,9 +1,10 @@ -USEMODULE += cpp11-compat +FEATURES_REQUIRED += float_math USEPKG += flatbuffers USEPKG += gemmlowp USEPKG += ruy +USEMODULE += cpp11-compat USEMODULE += tflite-c USEMODULE += tflite-core-api USEMODULE += tflite-core-c diff --git a/pkg/tinycbor/Makefile.dep b/pkg/tinycbor/Makefile.dep index b33f081360c3..d5f4c586d168 100644 --- a/pkg/tinycbor/Makefile.dep +++ b/pkg/tinycbor/Makefile.dep @@ -1,2 +1,4 @@ # tinycbor is only supported by 32 bit architectures FEATURES_REQUIRED_ANY += arch_32bit|arch_64bit + +FEATURES_REQUIRED += float_math diff --git a/pkg/utensor/Makefile.dep b/pkg/utensor/Makefile.dep index 18bd75d2dc7f..b87f04291dd4 100644 --- a/pkg/utensor/Makefile.dep +++ b/pkg/utensor/Makefile.dep @@ -1,4 +1,5 @@ FEATURES_REQUIRED += cpp +FEATURES_REQUIRED += float_math FEATURES_REQUIRED += libstdcpp USEMODULE += utensor-ops diff --git a/pkg/wakaama/Makefile.dep b/pkg/wakaama/Makefile.dep index ec713ee9e956..7d79a3fe1bb3 100644 --- a/pkg/wakaama/Makefile.dep +++ b/pkg/wakaama/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += wakaama_core wakaama_core_coap wakaama_core_coap13 wakaama_data wakaama_client # include contrib code (platform adaption and client implementation) diff --git a/pkg/wamr/Makefile.dep b/pkg/wamr/Makefile.dep index 230e43d89203..def70ab8a129 100644 --- a/pkg/wamr/Makefile.dep +++ b/pkg/wamr/Makefile.dep @@ -1,3 +1,5 @@ +FEATURES_REQUIRED += float_math + USEMODULE += sema USEMODULE += ztimer64_msec USEMODULE += ztimer_usec From f2efe72f5edd38374e3f331af9060a99edde3875 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Thu, 18 Sep 2025 14:57:17 +0200 Subject: [PATCH 7/8] examples: require float_math where needed --- examples/lang_support/official/riot_and_cpp/Makefile | 2 ++ examples/networking/misc/spectrum-scanner/Makefile | 3 +++ 2 files changed, 5 insertions(+) diff --git a/examples/lang_support/official/riot_and_cpp/Makefile b/examples/lang_support/official/riot_and_cpp/Makefile index 639a862c453e..3a14492b46d1 100644 --- a/examples/lang_support/official/riot_and_cpp/Makefile +++ b/examples/lang_support/official/riot_and_cpp/Makefile @@ -27,6 +27,8 @@ DEVELHELP ?= 1 # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 +USEMODULE += printf_float + # Features required FEATURES_REQUIRED += cpp # basic C++ support FEATURES_REQUIRED += libstdcpp # libstdc++ support (for #include ) diff --git a/examples/networking/misc/spectrum-scanner/Makefile b/examples/networking/misc/spectrum-scanner/Makefile index 96dfc8080b44..bae9b0d08ff6 100644 --- a/examples/networking/misc/spectrum-scanner/Makefile +++ b/examples/networking/misc/spectrum-scanner/Makefile @@ -7,6 +7,9 @@ BOARD ?= samr21-xpro # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../../../.. +# Needed for print_float() +FEATURES_REQUIRED += float_math + # Define modules that are used USEMODULE += gnrc USEMODULE += netdev_default From 56be5ab33fa845a0a93e881a005b4816a534d7af Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 17 Sep 2025 16:27:02 +0200 Subject: [PATCH 8/8] cpu/native: fix FPU/SSE register related context switching issues When the `float_math` feature is not in used, this adds CFLAGS to instruct the compiler to not make use of FPU/SSE registers, fixing issues (random crashes, floating point exceptions, stack corruptions, incorrect computations) due to incorrect back and restore of those registers on context switching. If `float_math` is used, the buggy behavior as before is produced. But since `float_math` is not actually provided by the native CPU, one would have to compile `CONTINUE_ON_EXPECTED_ERRORS=1` to actually get into that situation. Co-authored-by: Mihai Renea --- cpu/native/Makefile.include | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cpu/native/Makefile.include b/cpu/native/Makefile.include index d5f7d1766dd4..786fd4ab672d 100644 --- a/cpu/native/Makefile.include +++ b/cpu/native/Makefile.include @@ -37,3 +37,22 @@ ifeq ($(USE_LIBUCONTEXT),1) CFLAGS += $(pkg-config libucontext --cflags) -DUSE_LIBUCONTEXT=1 LINKFLAGS += $(shell pkg-config libucontext --libs) endif + +ifeq (x86_64,$(OS_ARCH)) + # Disable use of FPU/SSE registers if FPU is not used. This prevents radom + # stack corruptions and floating point exceptions to not occur during + # context switching. + ifeq (,$(filter float_math,$(FEATURES_USED))) + # FPU/SSE registers are not reliably saved and restored in glibc's ucontext + # implementation (see https://github.com/RIOT-OS/RIOT/issues/495) and not at + # all in libucontext's (but there at least this is documented). So we force + # the compiler to only use registers known to be properly backed up and + # restored during context switching + CFLAGS += -mgeneral-regs-only + + # Since we disabled the use of non-general registers (such as FPU registers), + # we need to use a soft FPU + CFLAGS += -msoft-float + LINKFLAGS += -msoft-float + endif +endif