PSoC >> PSoC Mixed-Signal Array

Pages: 1
alager
Tester - PRO for PSoC


Reged: Aug 02 2007
Posts: 32
flash routine / linker overwritting code
      #56162 - Thu May 15 2008 04:23 PM

The linker is moving my code around based on this variable:
const BYTE EEPowerUp @ 0x0080;//0x0fc0;

Consequently I can not place my flash variables in "unused" areas of flash because no matter where I put them, other code is placed into the same block. Then when I call flash_writeBlock(), my chip gets corrupted.

The expected behavior is to find a block of flash that is not being used, and then place up to 64 bytes of storage there, and the code stays where it was.

Aaron


Post Extras: Print Post   Remind Me!   Notify Moderator  
alager
Tester - PRO for PSoC


Reged: Aug 02 2007
Posts: 32
Re: flash routine / linker overwritting code [Re: alager]
      #56172 - Thu May 15 2008 04:45 PM

A temporary work around I found is to declare the variable as an array of 64 bytes.
const BYTE EEPowerUp[64] @ 0x0080;//0x0fc0;

However this is a pain because now I, not the computer, have to think about where code is, and how much space it's taking up ect.

Aaron


Post Extras: Print Post   Remind Me!   Notify Moderator  
clydeAdministrator
HI-TECH team member
*****

Reged: Oct 16 2003
Posts: 470
Re: flash routine / linker overwritting code [Re: alager]
      #56182 - Thu May 15 2008 04:51 PM

Aaron, can you explain a little more? I'm not sure what you mean by "based on this variable". The address you've chosen for it is quite low - it's just above the vector table. It's also only one byte in size, so the flash locations around it (i.e. 0x7F and below, and 0x81 and above) are still up for grabs.


If you want to reserve a block of flash so the compiler doesn't use it, you can either use the --ROM option to the compiler or you can place an array on a constant address, e.g.
Code:

const unsigned char _reserved[64] @ 0x7FC0;


would reserve 64 bytes of flash at the given address. There is also a macro in <psoc.h> that will reserve a specified number of blocks at the top of flash:
Code:

#include <psoc.h>
EEPROM_RESERVE_BLOCKS(1)


will reserve 1 block (64 bytes for most PSoC chips) of flash at the very end of the flash memory. The size of a block, and the total size of the flash, are already known by the compiler based on the chip selected.

Clyde


Post Extras: Print Post   Remind Me!   Notify Moderator  
clydeAdministrator
HI-TECH team member
*****

Reged: Oct 16 2003
Posts: 470
Re: flash routine / linker overwritting code [Re: alager]
      #56202 - Thu May 15 2008 04:57 PM

Aaron, why don't you explain exactly what it is you are trying to achieve? The compiler is quite happy to manage the memory for you, so if you don't want to do that, why are you reserving flash bytes in the first place?

Clyde


Post Extras: Print Post   Remind Me!   Notify Moderator  
alager
Tester - PRO for PSoC


Reged: Aug 02 2007
Posts: 32
Re: flash routine / linker overwritting code [Re: clyde]
      #56232 - Thu May 15 2008 06:04 PM

I have to apologize a little on this one. I evidently did use the ROM command in an old project to work around this problem. But I couldn't find anything related in the search of this forum.

I'm just trying to store a value that I can read on power up.
Instead of using the flash read function, I took the advice of the header file and defined a variable directly to the address where my variable will be stored.

I just tried the macro EEPROM_RESERVE_BLOCKS(1), and it behaves similar to my work around. It does work, but the code is relocated to the end of flash (0xba2). I guess this isn't a big deal, but it sure wasn't expected in either case.

Aaron


Post Extras: Print Post   Remind Me!   Notify Moderator  
clydeAdministrator
HI-TECH team member
*****

Reged: Oct 16 2003
Posts: 470
Re: flash routine / linker overwritting code [Re: alager]
      #56282 - Fri May 16 2008 01:09 AM

Aaron,

You said "I'm just trying to store a value that I can read on power up." How and when are you storing the value?


Post Extras: Print Post   Remind Me!   Notify Moderator  
alager
Tester - PRO for PSoC


Reged: Aug 02 2007
Posts: 32
Re: flash routine / linker overwritting code [Re: clyde]
      #56372 - Fri May 16 2008 11:09 AM

Clyde,

Below is the code that I'm trying to run. It's a simple routine to cycle through a few different states each time power is applied. It's called once from main() after the user modules are initialized.

Aaron

Code:

BYTE PowerUp;
const BYTE EEPowerUp @ 0x0fc0;

void ReadSettings(void) {
PowerUp = EEPowerUp;

}

void SaveSettings(void) {
BYTE value;
_flash_temp = 25;
_flash_delay = (((24*100L-80)/13));
value=flash_writeBlock((void *) &PowerUp, BLOCK_ID);
}

void PowerUpState() {
//read and toggle the PowerUp byte to allow normal
//operation or color cycling

ReadSettings();
if (PowerUp == 0) {
//color cycle
PowerUp++;
} else if (PowerUp == 1) {
//just be on
PowerUp++;
}else if (PowerUp == 2) {
//cycle with pause
PowerUp=0;
} else {
PowerUp=0;
}
SaveSettings();
}





Post Extras: Print Post   Remind Me!   Notify Moderator  
clydeAdministrator
HI-TECH team member
*****

Reged: Oct 16 2003
Posts: 470
Re: flash routine / linker overwritting code [Re: alager]
      #56392 - Fri May 16 2008 05:31 PM Attachment (17 downloads)

Aaron,

that is pretty much what I thought. The bottom line is that since the PSoC flash can only be written in blocks of 64 bytes (or 128 for some new chips) you have to reserve at least one whole block if you want to use it as EEPROM.

If you want to hide the details of this you can use the eeprom_read and eeprom_write functions, e.g. here is a little test program I wrote for these functions:

Code:

#include <psoc.h>
#include "lcd.h"
#include <string.h>
#include <stdio.h>

#define OFFSET 0x30
#define VALIDVAL 0xAA23
EEPROM_RESERVE_BLOCKS(2); // reserve 2 blocks of FLASH for EEPROM emulation
struct
{
int var1;
long var2;
char var3[10];
int valid;
int seq;
} evars;

void
main(void)
{
lcd_init();
lcd_puts("start");
lcd_goto(0x0);
if(!eeprom_read(OFFSET, &evars, sizeof evars)) {
lcd_puts("read fail");
for(;;);
}
if(evars.valid != VALIDVAL) {
printf("invalid %X", evars.valid);
memset(&evars, 0, sizeof evars);
evars.var1 = 0x1234;
strcpy(evars.var3, "hello wor");
evars.var2 = 0xABCDEF99;
} else {
lcd_goto(0);
printf("Read %X", evars.var1);
}
lcd_goto(0x40)
evars.seq++;
evars.valid = VALIDVAL;
if(!eeprom_write(OFFSET, &evars, sizeof evars)) {
lcd_puts("write failed");
for(;;);
}
printf("FlASH seq %X", evars.seq);
}



This is writing a whole structure to the eeprom, and also using an offset into the eeprom (this is just for test purposes).

When this board is powered on, it displays a number on the LCD that is one more than the last time it was powered up. Note the use of a magic number to detect the first time it was powered up after flashing.

I've attached a zip file with a complete project using this code.

You could use the same approach for your application.

Clyde


Post Extras: Print Post   Remind Me!   Notify Moderator  
alager
Tester - PRO for PSoC


Reged: Aug 02 2007
Posts: 32
Re: flash routine / linker overwritting code [Re: clyde]
      #56592 - Mon May 19 2008 11:53 AM

Thanks Clyde!

The macro: EEPROM_RESERVE_BLOCKS(1); Does the trick. As you state, it reserves the block, so that no code is placed in that block, and therefore not over written.

I guess what threw me off in the beginning, was that when I declared the constant variable at a specific address, the linker would move the code around so that there was code always in the same block as my constant variable.
I presume this is happening so that LJMP can be avoided within the compiler generated code.

Aaron


Post Extras: Print Post   Remind Me!   Notify Moderator  
Pages: 1



Extra information
0 registered and 0 anonymous users are browsing this forum.

Moderator:  ndouglas, Dan Henry, jtemples, jeff, garth, Andrew L, Ryan, mikerj 

Print Topic

Forum Permissions
      You cannot start new topics
      You cannot reply to topics
      HTML is enabled
      UBBCode is enabled

Rating:
Topic views: 837

Rate this topic

Jump to

Contact Us | Privacy statement HI-TECH Software

Powered by UBB.threads™ 6.5.5