diff --git a/src/CLR/Core/Random.cpp b/src/CLR/Core/Random.cpp index 7d947c9116..bb1dd1ec2a 100644 --- a/src/CLR/Core/Random.cpp +++ b/src/CLR/Core/Random.cpp @@ -8,38 +8,18 @@ __nfweak void CLR_RT_Random::Initialize() { CLR_INT64 st = HAL_Time_CurrentTime(); - CLR_INT32* ptr = (CLR_INT32*)&st; - m_next = ptr[ 0 ] ^ ptr[ 1 ]; + srand((unsigned int)st); } __nfweak void CLR_RT_Random::Initialize( int seed ) { - m_next = seed; + srand(seed); } -__nfweak int CLR_RT_Random::Next() +__nfweak uint32_t CLR_RT_Random::Next() { - // - // Portable Random Number Generator: page 278-279 "Numerical Recipes in C". - // - static const int IA = 16807; - static const int IM = 2147483647; - static const int IQ = 127773; - static const int IR = 2836; - static const int MASK = 123459876; - - int v = m_next; - int k; - - v = v ^ MASK; - k = v / IQ; - v = IA * (v - k * IQ) - IR * k; if(v < 0) v += IM; - v = v ^ MASK; - - m_next = v; - - return v; + return rand(); } #if !defined(NANOCLR_EMULATED_FLOATINGPOINT) @@ -47,7 +27,7 @@ __nfweak int CLR_RT_Random::Next() __nfweak double CLR_RT_Random::NextDouble() { // Next() will return value between 0 - 0x7FFFFFFF (inclusive) - return ((double)Next()) / ((double)0x7FFFFFFF); + return ((double)rand()) / ((double)0x7FFFFFFF); } #else @@ -55,39 +35,17 @@ __nfweak CLR_INT64 CLR_RT_Random::NextDouble() { // Next() will return value between 0 - 0x7FFFFFFF (inclusive) - return ((CLR_INT64 )Next() ) / ((CLR_INT64)0x7FFFFFFF >> CLR_RT_HeapBlock::HB_DoubleShift); + return ((CLR_INT64 )rand() ) / ((CLR_INT64)0x7FFFFFFF >> CLR_RT_HeapBlock::HB_DoubleShift); } #endif __nfweak void CLR_RT_Random::NextBytes( unsigned char* buffer, unsigned int count ) { - unsigned int i = count / 3; + unsigned int i; - while(i-- != 0) + for(i = 0; i < count; i++) { - int rand = Next(); - - // We take only the bottom 3 bytes, because the top bit is always 0 - buffer[ 0 ] = (unsigned char)rand; rand >>= 8; - buffer[ 1 ] = (unsigned char)rand; rand >>= 8; - buffer[ 2 ] = (unsigned char)rand; - - buffer += 3; - } - - i = count % 3; - - // fill the remaining bytes - if(i > 0) - { - int rand = Next(); - - while(i-- != 0) - { - buffer[ 0 ] = (unsigned char)rand; rand >>= 8; - - buffer++; - } + buffer[i] = (unsigned char)rand(); } } diff --git a/src/CLR/Include/nanoCLR_Runtime.h b/src/CLR/Include/nanoCLR_Runtime.h index 5d7795745e..dd57d48699 100644 --- a/src/CLR/Include/nanoCLR_Runtime.h +++ b/src/CLR/Include/nanoCLR_Runtime.h @@ -374,14 +374,11 @@ struct CLR_RT_Memory struct CLR_RT_Random { -private: - int m_next; - public: void Initialize(); void Initialize( int seed ); - int Next(); + uint32_t Next(); #if !defined(NANOCLR_EMULATED_FLOATINGPOINT) double NextDouble(); diff --git a/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt b/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt index 0d54bc4eaf..a0e3aa9724 100644 --- a/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt +++ b/targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt @@ -41,6 +41,16 @@ if(USE_NETWORKING_OPTION) list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Network.cpp") endif() +# append random implementation for all series, except F0 +if( ${TARGET_SERIES} STREQUAL "STM32L0xx" OR + ${TARGET_SERIES} STREQUAL "STM32F4xx" OR + ${TARGET_SERIES} STREQUAL "STM32F7xx" OR + ${TARGET_SERIES} STREQUAL "STM32H7xx") + + list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetRandom.cpp") + +endif() + # parse nanoFramework API options ParseApiOptions() diff --git a/targets/CMSIS-OS/ChibiOS/nanoCLR/targetRandom.cpp b/targets/CMSIS-OS/ChibiOS/nanoCLR/targetRandom.cpp new file mode 100644 index 0000000000..808eb4e87b --- /dev/null +++ b/targets/CMSIS-OS/ChibiOS/nanoCLR/targetRandom.cpp @@ -0,0 +1,37 @@ +// +// Copyright (c) 2018 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// +#include "Core.h" +#include + +void CLR_RT_Random::Initialize() +{ + rngStart(); +} + +void CLR_RT_Random::Initialize( int seed ) +{ + rngStart(); +} + +uint32_t CLR_RT_Random::Next() +{ + return rngGenerateRandomNumber(); +} + +double CLR_RT_Random::NextDouble() +{ + // the hardware generator returns a value between 0 - 0xFFFFFFFF + return ((double)rngGenerateRandomNumber()) / ((double)0xFFFFFFFF); +} + +void CLR_RT_Random::NextBytes(unsigned char* buffer, unsigned int count) +{ + unsigned int i; + + for(i = 0; i < count; i++) + { + buffer[i] = (unsigned char)rngGenerateRandomNumber(); + } +}