Random numbers using SRAM

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello guys,

 

I am trying to generate random numbers using SRAM and its giving constant value across the address. Is there anyway I can get some random values out of it by using some interrupts or something?

microcontroller- Atmega644

using avrdude

 

#define SRAM_START_ADDR 0x010

#define SRAM_END_ADDR 0x110

 

uint8_t Read_SRAM()

{

uint8_t seed = 0xFF;

for (uint8_t * i = (uint8_t *)SRAM_START_ADDR; i < (uint8_t *)SRAM_END_ADDR; i++)

if (*i != seed)

seed ^= (*i);

return seed;

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What makes you think the SRAM will be random?

 

In the Tutorial Forum there is at least one (and I think maybe more?) articles about random sources on AVRs.

 

Basically you need to find some "entropy" and I don't think SRAM contents at power on is going to give you this.

 

If your device has any kind of "user interaction" then timing between one human event and the next is often a good source of entropy. Similarly if the device has any kind of "data connection" to the outside world then timing between events like UARt or Network character arrivals (or using the character content itself) can provide entropy.

 

A light dependent resistor read by ADC could be mildly random (depending on the environment where the device is located).

 

Sometimes a floating ADC input is considered as a possible source of entropy. More often a reverse biased zener is proposed: http://www.reallyreallyrandom.co...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah i was actually trying out different ways to get the entropy. I thought this can be one of the options

 

A light dependent resistor read by ADC could be mildly random (depending on the environment where the device is located).

 

Sometimes a floating ADC input is considered as a possible source of entropy. More often a reverse biased zener is proposed: http://www.reallyreallyrandom.co...

 

any sample code this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
What makes you think the SRAM will be random?

Over the entire population of device's production run, the power-up content of might be "random" - it is certainly not guaranteed to be any particular value.

 

But on one specific chip, I'd think the values you'd read from SRAM at startup would be (largely) repeatable.

 

@avr90900:  so are you actually looking for:

  • something that will be random each time the chip powers-up?
  • something that will be unique from one chip to another?
  • something else ... ??

 

clawson wrote:
you need to find some "entropy"

Indeed.

 

@avr90900:  you already have a thread with loads of suggestions on that: https://www.avrfreaks.net/forum/random-numbers-using-adc

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try a search here - even in the last week someone was asking about the Zener/ADC thing. also, like I said, someone did some fairly detailed work a few years back and posted something in Tutorial. A search suggests it was one of these:

 

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

 

EDIT: actually neither of those is the thing I was thinking of - wonder where it is located? ....

Last Edited: Tue. Jul 6, 2021 - 10:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah i want the numbers to be unique though in one power up.  I thought it can be done with some global interrupts but this way is not working . its giving me constant value thoughtout.

But its giving me different but constant value when i power it on again(this is something i dont want)

 

@avr90900:  you already have a thread with loads of suggestions on that: https://www.avrfreaks.net/forum/random-numbers-using-adc --- yeah i know..but its not working for me

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr90900 wrote:
I thought it can be done with some global interrupts

what made you think that?

 

The RAM content will be whatever it will be - whether you use interrupts or not is irrelevant, surely?

 

If you're writing in C (or C++), you have remembered to disable its RAM initialisation - haven't you ... ?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want a different seed at power up then use srandom()/random() but before each power down store the current value in EEPROM to become the seed at the next power on.

 

Alternatively maybe consider the zener/ADC thing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another way to get "random" ADC values (at least in the low bits) is to connect an ADC input via an RC filter to some active signal on the board, thus feeding the ADC with a signal that is constantly ramping up and down.

 

I've also thought about using the separate watchdog timer.  On power-up, configure it to interrupt at say 16 to 64 ms, and during that interval, run a 16-bit timer at full speed.  Get the 16-bit timer value when the WDT interrupts.  At 8MHz, it will have counted ~128,000 to ~512,000 clocks.  Since the two timers are independent, I would expect the lower values (perhaps the lower byte) of the 16-bit timer to have enough variation to generate a seed.  Then shut off the WDT or configure it for actual watchdog use, as desired.

Last Edited: Tue. Jul 6, 2021 - 02:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to generate random numbers using SRAM and its giving constant value across the address.

 

#define SRAM_START_ADDR 0x010
#define SRAM_END_ADDR 0x110

The only ram you are reading is 0x100-0x10F, the rest is the registers then io. The 16 registers being used are unknown at power on, but by the time you get around to your function they have all probably been used so are now known values, the io registers are in reset state which are known values, and the first 16 bytes of ram being used are also probably initialized to either data or bss, and also known values. Not much random there.

 

 

 

Ram bits on power up are unknown from one mcu to another, and in one mcu many ram bits power up into a repeatable state (they are more strongly inclined to be a particular state), while some bits seem to have little inclination to be one state or the other and therefore appear to be random at power on.

 

Most toolchains do not init ram above the usual data/bss (I think there may be one out there that clears all ram), so using some portion of ram above the data/bss (like use the last 64/128/256/... bytes of ram) one can get at least some amount of random from the bits that cannot decide what they want to be at power on. How much random is unknown and would depend on the number of bits that are unknown at power on and what kind of algorithm you are using over that range of ram to get your initial 'random' value, but most would be happy with just enough so you get away from 'repeatable random' at power on (and power on is probably the only time one could detect this repeatability since you have a frame of reference which you lose soon after).

 

Also note that ram bits tend to remain 'as-is' for some time after power off, so testing ram bits at power on requires some amount of power off time time to truly figure out what the ram is doing at power on.

 

While running, you can also get some of your isr's to simply grab a random value, and also in various code locations, so at runtime the sequence of random you are going through will be less repeatable (even though you will most likely not be able to detect whether it is doing anything of value). With low power modes now available in mcu's (powerdown <1uA), leaving an mcu powered all the time would also mean power up is a rare event and one could easily live with any initial seed value as it really no longer matters much.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you can use a button that gets held down at some point, that can give a nice random value...We used that for some spinning LED roulette wheel programs.  When you released the button, the random value (& outcome) had already been determined.  All the spinning & beeping & slowdown were just for show.  We had one of 32 choices picked at "random" & it seemed to work very well.   Getting a true random is not an easy task...even an ADC can have some very slight bias (then certain seeds or values might very very very slightly dominating). So, if you need random to one part in a trillion, it is no small feat.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr90900 wrote:
any sample code this?

https://forum.arduino.cc/t/using...

App note AVR126 below:

/**
 * \file
 *
 * \brief Using ADC of ATmega88 in polling mode
 *
 * Copyright (C) 2015 Atmel Corporation. All rights reserved.
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */
/*
 * Support and FAQ: visit http://www.atmel.com/design-support/
 */

/**
 * This code is distributed with the application note AVR126
 * This file contains functions that helps to use the ATmega88 ADC
 * in Single Conversion Mode.
 *
 * The driver is not intended for size and/or speed critical code, since
 * most functions are just a few lines of code, and the function call
 * overhead would decrease code performance. The driver is intended for
 * getting started with the ATmega88 ADC module.
 */

#include <avr/io.h>

unsigned int result;
unsigned int compare;

/*! \brief Initializes ADC Peripheral
     Configuration Registers */

void initialize(void)
{
	/* Set PORTB.0  as output */
	DDRB    |= 0b00000001;        			
	/* Initialize PORTB.0 with logic "one" */
	PORTB   |= 0b00000001;   
	/* 
	 * Enable ADC with Clock prescaled by 16
	 * If Clock speed is 8MHz, then ADC clock = 8MHz/16 = 500kHz
	 */
	ADCSRA   = 0b10000100;  
	/* Disable Digital Input on ADC Channel 0 to reduce power consumption */      			
	DIDR0    = 0b00000001;       	
	/*
	 * Disable Left-Adjust and select Internal 1.1V reference
	 * Select ADC Channel 0 as input		
	 */
    ADMUX    = 0b11000000;       			
	
	/* (465 -> 0.5V Equvlaent Counts for 1.1 V ADC Reference) */
	compare  = (unsigned int)465;      		
}

/*! \brief ADC Conversion Routine
 *  in single ended mode */

void convert(void)
{
	/* Start ADC Conversion */
	ADCSRA  |= (1<<ADSC);					
	/* Wait till conversion is complete */
	while((ADCSRA & (1<<ADIF)) != 0x10);	
	
	/* Read the ADC Result */
	result   = ADC;
	/* Clear ADC Conversion Interrupt Flag */                         
	ADCSRA  |= (1 << ADIF);					

	/* Compare the converted result with 0.5 V */
	if(result <= compare)
	/* If less clear PORTB.0 else set PORTB.0*/                 
	PORTB   &= 0b11111110;        			
	else
	PORTB   |= 0b00000001;					
}

/*! \brief Main routine
 *  Calls function "initialize()" to initialize ADC
 *  Calls function "convert()" to convert the ADC indefinitely */

int main(void)
{
	/* Initialize the ADC Module */
	initialize();							

    while(1) {
		/* ADC Conversion Routine */
		convert();
	}
}

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

If you want something you've never had...

...you must be willing to do something you've never done!

Lets go Brandon!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr90900 wrote:
any sample code this?

That's all in your other thread!

 

https://www.avrfreaks.net/forum/random-numbers-using-adc

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Jul 6, 2021 - 05:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I am thinking that this thread should be closed as the overwhelming suggestions are you use teh ADC in one fashion or another.  Just as mentioned in teh other thread.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some time ago, we were discussing random number generation (one of my favorite recurring themes in the forum, another one is division by 10...) and I did a SRAM dump for an ATmega 4809.

You can see the result in graphical form here:  https://www.avrfreaks.net/comment/2712941#comment-2712941

 

So it's very random. However, it's also mostly unchangeable and fixed for each particular chip. I noticed only about 4% of bits seem to be "undecided".

A few more thoughts on this here:  https://www.avrfreaks.net/comment/2712941#comment-2712941

In fact the whole thread has several interesting comments.

Last Edited: Tue. Jul 6, 2021 - 09:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If your app uses a button.... a simple rand generator can be...

Rnd is always changing until button press is detected then value is passed in

 

//Main loop

uint_16 Rnd =0;

while(1)

{

Rnd++;

CheckButton(Rnd);

}