Split from: eeprom_write_word & eeprom_write_dword

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

Hi

i am using atmega8 .it have 512 byte of eeprom, i use it without any problem

but if i use out of this range of address "512" in my program, still any thing works with out problems in compile and program , for example "eeprom_update_byte((uint8_t*)2048,cnt);"

2048 is out of range eeprom atmega8 but why no error ? and program work correctly ?

i can read and write eeprom in address 2048 !!!

Last Edited: Thu. Aug 2, 2018 - 04:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The EEAR register wraps (or rather it "masks") So 2048 which is 0x800 & 0x1FF is 0x000. So when you think you are writing to "2048" you are just writing to 0. In fact if you write some known value to "2048" then read from 0 you should find you get the same value.

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

hossein_sbi wrote:
2048 is out of range eeprom atmega8 but why no error ? and program work correctly ?

This is an excellent example of how bad code can actually appear to "work" !

 

Note that this "wrapping" of addresses is very common.

 

 

EDIT

 

More examples of stuff working by accident rather than design - both hardware & software:

 

https://www.avrfreaks.net/commen...

 

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: Wed. Nov 24, 2021 - 10:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank  you for information ,yes  you right, the 2048  is 0 , as i tested.

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

hossein_sbi wrote:

2048 is out of range eeprom atmega8 but why no error ?

Now, why would you expect an error?

 

Is there anything in the rules of C that says you cannot assign a value outside of range?

 

Could a LINT-like tool detect the situation and warn about it?  Surely.  Could it take some action?  How?  What if the programmer intentionally wanted a wraparound?  While perhaps unusual, surely not unheard of in buffer work.

 

What does the datasheet say?  [and what does that imply?]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

To issue a warning splint (or whatever) would need to be told about the [512] dimension. As far as I know nothing suggests to the compiler or any other tool that such an upper bound exists.

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

At least on the Arduino platform (avr-gcc) there is a #define of E2END which provides the uppermost valid EEPROM address (before wrapping).

 

--Mike

 

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

But how could any code analyser know the significance of that until it was actually associated with EEMEM in some way?

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

I was thinking that E2END might be useful to the OP, not necessarily for a code analyser.

 

--Mike

 

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

I suppose one could envisage a modification to the eeprom_*() routines in AVR-LibC themselves where they chaeck the eeprom address parameters for <= E2END and report back some kind of error - but most people don't use absolute addressing anyway. If you simply do:

int eeVAR EEMEM;

eeprom_update_word(&eeVar, 12345);

then the only thing ever really interested in &eeVar is the linker. The modern linker scripts have:

__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 128K;
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
__EEPROM_REGION_LENGTH__ = DEFINED(__EEPROM_REGION_LENGTH__) ? __EEPROM_REGION_LENGTH__ : 64K;
__FUSE_REGION_LENGTH__ = DEFINED(__FUSE_REGION_LENGTH__) ? __FUSE_REGION_LENGTH__ : 1K;
__LOCK_REGION_LENGTH__ = DEFINED(__LOCK_REGION_LENGTH__) ? __LOCK_REGION_LENGTH__ : 1K;
__SIGNATURE_REGION_LENGTH__ = DEFINED(__SIGNATURE_REGION_LENGTH__) ? __SIGNATURE_REGION_LENGTH__ : 1K;
__USER_SIGNATURE_REGION_LENGTH__ = DEFINED(__USER_SIGNATURE_REGION_LENGTH__) ? __USER_SIGNATURE_REGION_LENGTH__ : 1K;
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = __DATA_REGION_LENGTH__
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__

which for most devices, most of the time should police a per device limit so the worst that happens if you let the linker allocate EEMEM var addresses is an "overflow in section .eeprom" if you end up locating too much there.