From 8f6e5cf31189b8674cdf4de0073e9bfcb0d3435a Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Tue, 4 Aug 2026 15:09:31 +0200 Subject: [PATCH 1/2] Allow setting a seed for random numbers --- src/Primitives/emulated.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 8027cae8..3db2ff1d 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -100,6 +100,12 @@ def_prim(random_int, NoneToOneU32) { return true; } +def_prim(random_set_seed, oneToNoneI32) { + srand(arg0.uint32); + pop_args(1); + return true; +} + // call callback test function (temporary) def_prim(test, oneToNoneU32) { uint32_t fidx = arg0.uint32; @@ -593,6 +599,7 @@ void install_primitives(Interpreter *interpreter) { install_primitive(millis); install_primitive(micros); install_primitive(random_int); + install_primitive(random_set_seed); install_primitive(print_int); install_primitive(print_string); From f1eb89eccad395a6fda9fc69ddfdff1bd150aeec Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Tue, 4 Aug 2026 15:35:43 +0200 Subject: [PATCH 2/2] Use std::minstd_rand instead of rand and srand because of an ESP-IDF and Zephyr conflict Ideally we should not have to do this and it increases the size of the binary slightly but there is no way to avoid the conflict between ESP-IDF and Zephyr otherwise. However, rand and srand do work fine on other boards. Why rand/srand: The entropy API appears to be more useful for cryptographic purposes by using hardware entropy which we don't really need for basic random numbers. We still have some conf options for this but this is mostly becaues the networking stack can also sometimes use entropy. By using rand we can also use srand to set the seed which the entropy API does not support. --- platforms/Zephyr/prj.conf | 1 - src/Primitives/zephyr.cpp | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/platforms/Zephyr/prj.conf b/platforms/Zephyr/prj.conf index 69fb9798..9262530e 100644 --- a/platforms/Zephyr/prj.conf +++ b/platforms/Zephyr/prj.conf @@ -41,7 +41,6 @@ CONFIG_STM32_ENABLE_DEBUG_SLEEP_STOP=y # Display drivers CONFIG_DISPLAY=y -# Needed for random number generation primitives CONFIG_ENTROPY_GENERATOR=y # Needed for getting runtime memory stats diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 1279eaa0..467d42ed 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #if IS_ENABLED(CONFIG_WIFI) @@ -32,6 +31,7 @@ #include #include #include +#include #include "../Memory/mem.h" #include "../Utils/macros.h" @@ -176,8 +176,18 @@ def_prim(noTone, NoneToNoneU32) { #endif +// Ideally, we would use rand and srand here but since ESP-IDF and Zephyr both +// define a function called "random" it causes a linker error. +static std::minstd_rand rng; + def_prim(random_int, NoneToOneU32) { - pushInt32(sys_rand32_get()); + pushInt32(rng()); + return true; +} + +def_prim(random_set_seed, oneToNoneI32) { + rng.seed(arg0.uint32); + pop_args(1); return true; } @@ -654,6 +664,7 @@ void install_primitives(Interpreter *interpreter) { install_primitive(chip_digital_read); install_primitive(millis); install_primitive(random_int); + install_primitive(random_set_seed); install_primitive(print_string); install_primitive(print_int); install_primitive(abort);