This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Random number generator not so random

Hello DevZone,

SDK 15.0.0, sd132

I'm working on the random number generator peripheral in the nRF52832 and used the peripheral example in my SDK.

When I upload the example code to my devkit I can clearly see that every time the microcontroller boots the numbers differ from each other.

When I want to implement that feature in my project, using the same lines of code and files and settings (I believe) it always seems to give me the same number.

Even across multiple devkits. 

So can anyone tell me what I'm doing wrong here?

Kind regards

Parents Reply Children
  • I haven't used this peripheral but I prefer writing home-brew rather than the abstracted libraries in most cases as you can tell what's going on. Some things come to mind, the obvious one is the library probably uses interrupts and you are not. Second is the RND is probably used by SoftDevice (I guess) for the encrypted connection so maybe the nrf library is calling it and you have a problem there.

    If you're doing this on boot before softdevice init and without need to refresh the numbers I'd be happy with your approach, with a loop for however many you need.

  • Well thanks for your help at least, I've figured out that the softdevice indeed uses this peripheral and makes it unusable for me. I think I'll do all my random number generation prior to starting the softdevice

  • That's what I'd do. You can probably call the softdevice to try and share the generation but doing it before init is cleaner imo. It comes down to whether you need new numbers later on.

  • Yea you're probably right, I've found this that works with the softdevice.
    The only thing I dislike about this is waiting for the softdevice to generate a number, but its something I have to deal with.

    for(uint8_t i = 0; i < 6; i++)
    {
        while(len == 0)
        {
            APP_ERROR_CHECK(sd_rand_application_bytes_available_get(&len));
        }
        APP_ERROR_CHECK(sd_rand_application_vector_get(&p_buff[i], len));
        len = 0;
    }

  • I know this is an old question, but I see no updates to similar questions so I thought I'd point it out. There are two bugs in this snippet.

    1) uReady cannot be used in the while loop. It won't work correctly. You must check the NRF_RNG->EVENTS_VALRDY in the loop itself. uReady won't be magically updated inside the loop, just set to whatever value NRF_RNG->EVENTS_VALRDY was set to prior to running the loop. This must be fixed before bug #2.

    2) NRF_RNG->EVENTS_VALRDY needs to be set to 0 by you prior to entering the loop. Chances are, if other tasks are using it or have used it, you'll find the value is 1 all the time and the task will return the same random number every time.

    This isn't a bug in NRF_RNG, it's the code itself. You mentioned you copied it from some example. If it was actually the same line for line, then the example is incorrect also. You will find after fixing this that NRF_RNG will work for you regardless of whether a Softdevice is using it or not.

    The advantage of NRF_RNG is that it is a random number based on hardware, rather than a software psuedorandom number. This is important for secure code implementations.

    (Additionally, the claimed working code above is incorrect as well--it has the same uReady issue and will only work if some other module is resetting the EVENTS_VALRDY independently and you happened to sync up with it in a race condition) 

    Hope this helps.

Related