Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work on random number generator #643

Merged
merged 1 commit into from
Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 9 additions & 51 deletions src/CLR/Core/Random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,86 +8,44 @@
__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)

__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

__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();
}
}
5 changes: 1 addition & 4 deletions src/CLR/Include/nanoCLR_Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
10 changes: 10 additions & 0 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
37 changes: 37 additions & 0 deletions targets/CMSIS-OS/ChibiOS/nanoCLR/targetRandom.cpp
Original file line number Diff line number Diff line change
@@ -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 <hal.h>

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();
}
}