Change value of variables in program space

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

Hi,

I cannot find the method to change the value of varaiables that are stored in program space. I wonder if I can do something like this:

#include
...
unsigned char mydata[10] PROGMEM;
...
void ChangeValue()
{
mydata[0] = 0x00;
}

Is that possible at all?

Thanks!

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

:shock:

Quote:
Is that possible at all?
No

Use the EEPROM instead (EEMEM).

You put objects in PROGMEM when you know they are constants.
If you have a mutable object put it in RAM or the EEPROM.

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

"Variables" in program space are constants, not variables.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Theoretically you can reprogram FLASH variable value, but it is not so simple. First of all, the AVR you use mus support bootloader. In bootloader section you can store a new variable value using SPM assembler instruction, the problem is that FLASH has a page structure, so if you want to write something, first you must erase the whole FLASH page. So to write a new value to FLASH variable you have to:
1. Read the whole FLASH page
2. Modify the bytes of interest
3. Erase FLASH page
4. Write new page
Steps 3 and 4 must be done in bootloader section.

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

TFrancuz wrote:
Steps 3 and 4 must be done in bootloader section.

To be more specific: on most AVR's that support the SPM-instruction (on ATmega48 it can be done from the whole flash).

/Martin.

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

I don't know why are you asking for changing the constants stored in the program memory.

If you are storing in bulk and changing in bulk then you can go for changing the value in program memory. For that your code which is going to operate on the flash memory should reside in bootloader section.

Get to know bootloader from the datasheet and avr libc.

If your intention is store something permanently and alter the value in runtime then you can go for EEPROM itself. You have library functions in avr-gcc which takes all your burden.

-Krishna Balan S

-------------------------------------------------------------------------

"Heroes are ordinary people with extraordinary commitment"

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

Thank you all!

For one application, I've exhausted the data space. Unfortunately there is a single big array whose values need to be changed dynamically. Looks like I have to use a different chip or compromise on the size of the array.

Thanks again.

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

By "data space" you mean the SRAM *and* the EEPROM? Otherwise what's wrong with spilling the lesser used variables into EEMEM? as suggested to you above?

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

I am using atmega644a, which has 4k SRAM and 2k EEPROM. The size of the array is larger than 2k. It is true that I can put all other variables to EEPROM and I am currently doing that.

Bo

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

in that case go for an external SPI dataflash

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

Consider going to the ATmega1284P - according to the datasheet, it has 16K of internal SRAM.

Stu

Edit: It's in the same family as the 644P which is a low-power version of the 644A.

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Thanks. The chip could be helpful.

I found if the SRAM is more than ~93% occupied, the program fails. Is that expected?

Bo

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

qiangbo wrote:
Thanks. The chip could be helpful.

I found if the SRAM is more than ~93% occupied, the program fails. Is that expected?

Bo

That doesn't surprise me. The heap grows from the bottom of SRAM, and the stack grows from the top. It sounds like you have a heap-stack collision. You can't use 100% of the SRAM for data. The MCU needs to use some of that SRAM for the stack.

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

Quote:

The heap grows from the bottom of SRAM, and the stack grows from the top.

I guess it depends what you mean by "bottom" and "top" but wither way that does not describe the avr-gcc RAM usage. This picture does:

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

clawson wrote:
Quote:

The heap grows from the bottom of SRAM, and the stack grows from the top.

I guess it depends what you mean by "bottom" and "top" but wither way that does not describe the avr-gcc RAM usage. This picture does:

Ok, now I'm confused. Assuming that we disregard external RAM (which isn't supported on the ATmega644/1284 as far as I know), I would say that RAMEND is the "top" of SRAM, and __data_start is the "bottom". So the heap grows "up" toward RAMEND and the stack grows "down" toward __data_start. If the heap gets too big, it can overwrite the stack, and if the stack gets too big it can overwrite the heap, right? Or if you filled up almost all of the RAM with variables defined in .data, there might not be enough room to accomodate the stack. My comment was based on the picture that you posted, so I'm not clear as to where my reasoning has gone wrong.

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

microcontrollerguy,

I think Clawson just wanted to clarify this a bit more.

and make sure the OP knew that not all controllers do it this way.

There are also controllers that work the other way around stack going up and data going down....

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

My point was that you said "The heap grows from the bottom of SRAM," which is not true. It grows from the end of .bss upwards while the stack grows downwards.

The discussion is moot anyway. There's nothing been said that suggests OP is using malloc(). As such the issue he faces is when the stack grows down and hits the end of .bss, not the heap, it's irrelevant.