## Accessing external EEPROM from boot section

21 posts / 0 new
Author
Message

hi guys,

I'm currently working on self programming(fota) of Xmega256A3BU

my binary file is sitting on the external eeprom attached to my board

(normally i used it to store my monitoring data there and i have full access to it from my application code.)

now from boot code as i'm trying to read the data from external eeprom, my boot loader stops working...

code is executed perfectly and as i flash the code to boot section it wont work....

and as soon as i remove the line of code for reading from ext. eeprom it again start working properly.

i'm able to access internal epprom perfectly

Is it possible to read content from external memory/eeprom from bootsection ?????

Isn't there a subroutine or interrupt routine to access the external EEPROM in the application area?
Be careful with interrupts. The interrupt routine for the bootloader must be in the boot area.

What interface does the external EEPROM use ? Parallel ? I2C ?

If I2C, there are a couple of existing Arduino bootloaders you could analyse for inspiration:

https://github.com/mihaigalos/mi...

https://www.rotwang.co.uk/projec...

Mehul9 wrote:
Is it possible to read content from external memory/eeprom from bootsection ?????
Yes

• XMEGA128A1
• XMEGA256A3
• XMEGA256D3

AT45DB041E Datasheet (512KB DataFlash)

"Dare to be naïve." - Buckminster Fuller

void spi_flash_write(uint8_t value)
{
SPIC_DATA = value;
while(!(SPIC.STATUS & 0x80));
}

guys my code is stucking in loop on while(!(SPIC.STATUS & 0x80));

what can be the problem

Is it configured as slave not master? In a slave you can write to the data register all you like but it won't trigger a transfer so you never get the IF flag to say the transfer has completed.

sometimes code is passing through this logic and sometimes it is stucked

sometimes it stucked at waiting for nwm

or it goes till end perfectly....

so i am confused y code is not behaving same every time.

The next bit in STATUS is WRCOL (Write Collision); a guess is "somehow" DATA is written early.

Confirm MODE is correct for that SPI flash integrated circuit.

"Dare to be naïve." - Buckminster Fuller

The code is working fine from the application section.

when i'm trying to read binary from boot section then this problem is seen

Mehul9 wrote:
when i'm trying to read binary from boot section then this problem is seen
Is all the code involved positioned "high" in the BLS? Remember that during SPM the whole app section reads back as 0xFF so you can't rely on any code down at lower addresses while SPM is being performed.

thanks you all..

the problem has been solved , actually some of prot pin are not initialized.

now my happy path is done...

ftp server to external flash and

then using bootloader from external flash to app section..

all is working fine..

now i want to do the verification of bin file sitting in external flash before moving to app section

and also after it...

how can i do it, is there any ready atmel function available?

Usually if you want to "verify" a block of binary you would perform a checksum of some sort - maybe CRC16 or CRC32 ?

how exactly ??

i found out this inbuilt function which generate 32crc for app in crc drivers file.

/**
* \brief Perform a CRC-32 calculation on the entire flash memory, on only
* the application section, on only the boot section, or on a selectable range
* of the flash memory.
*
* This function setups the type of CRC to perform and configures the memory
* range to perform the CRC on, and starts the CRC via the NVM module.
* When the calculation is done, the function disables the CRC module and
* returns the checksum.
* For CRC on the boot or application section, start address and length are not
* needed.
*
* \note In the flash range mode, an even number of bytes is read. If the user
* selects a range with an odd number of bytes, an extra byte will be read, and
* the checksum will not correspond to the selected range.
*
* \param crc_type      what kind of CRC to do perform on the NVM module: \ref
*                      CRC_FLASH_RANGE, \ref CRC_BOOT or \ref CRC_APP
* \param flash_addr    address of first byte in flash to perform CRC on
* \param length        number of bytes to perform CRC on
*
* \return checksum    CRC-32 checksum
*/
{
if ((length == 0) && (crc_type == CRC_FLASH_RANGE)) {
return 0;
}

Assert((crc_type == CRC_FLASH_RANGE) || (crc_type == CRC_BOOT) ||
(crc_type == CRC_APP));

// Initialize CRC for flash
crc_reset();
/* Set CRC32 enable bit to ensure correct reading of the resulting
* checksum */
crc_32_enable();
crc_set_source(CRC_SOURCE_FLASH_gc);

if (crc_type == CRC_FLASH_RANGE) {
} else {
nvm_issue_command(crc_type);
}

// Disable CRC and return checksum
return crc_checksum_complete();
}


so i am calling the function as

crc_flash_checksum(CRC_APP);

it will return me crc32

but after that what should i do?

and also how to check the bin file sitting in external flash.

The way CRCing would usually be used is that at build time, when you create the binary image to be delivered to the AVR then at that moment you have something run a CRC over the data (I have used srec_cat for this in the past). It "adds" a 16/32 bit checksum to the data. You now send the data over the delivery link so what arrives at the AVR is all the actual code and the additional 2/4 bytes of CRC. Now you have the AVR code run the same CRC algorithm over the data (but not including the last 2/4 bvtes) and see what value it gets. If the entire data is there and undamaged in any way then the AVR should calculate the same CRC as was generated back during the build. If they match you can go ahead and use the code. If they don't match you need to indicate the fault to the user and go back into bootloading mode waiting for an intact image to be delivered.

The CRC checking can actually go beyond this - don't just perform the check of data integrity just as the code is delivered but perform the same check at every power on. So as the bootloader first takes control at power on it CRCs the entire application and compares the result to the CRC that was delivered with the code image. If at any time in the future the code in the AVR is corrupted in some way then this power on CRC check will fail so the bootloader can go into the "indicate error/wait for new image delivery" phase again.

I have such support in this bootloader:

as it explains on that page you use a command such as:

srec_cat $(MSBuildProjectDirectory)\$(Configuration)\\$(Output File Name).hex -intel -fill 0xFF 0x0000 0x37FE --l-e-crc16 0x37FE -o AVRAP001.bin -binary

during the code build. The "--l-e-crc16" command there says "calculate a little endian CRC16 on this data and store it to 0x37FE/37FF". Then in the code:

the very same CRC algorithm that srec_cat uses is reimplemented in AVR code

thanks clawson, but i'm still confused.

not getting the clear idea on your explanation...

btw o found a code,is it useful:

// Calculate checksum for the application section
checksum1 = crc_flash_checksum(CRC_APP, 0, 0);

// Recalculate checksum for the application section using flash range CRC
checksum2 = crc_flash_checksum(CRC_FLASH_RANGE, APP_SECTION_START,
APP_SECTION_END-APP_SECTION_START+1);
if (checksum1 == checksum2) {
//"App section CRC   OK",
}

actually it seems sense less, as it is calculating the crc for app section both the time ..btw it is going to be same...

btw if possible can you explain your logic in simple words...

Last Edited: Fri. Sep 4, 2020 - 09:59 AM

Mehul9 wrote:
btw if possible can you explain your logic in simple words...
To be honest, if you don't understand it from what I wrote in #15 then don't bother. It's only really "belts and braces" anyway.

thanks clawson.

i got the flow that at every power on i should check for app code corruption.

even i want to design my flow in same way:

1. start

2. check if app section is corrupted / if my fota flag is set.

- yes then copy the image from ecternal flash to app section

3. no then,

-if my device booted for first time, then move the code from app section to external flash for backup.

but im confused regaring implemetation

actually i have a line of ques..

i create a hex using as7 and then using some avr gcc command i convert it to .bin file..

so finally i'm using the bin file.

*) does this binfile have any crc by default? or we have to add it as per the command you have shown?

*) are we doing crc on whole application section or block of memory in app section at time?

*)for eg. if my app section(256kb) the code is sitting from 0x00000 to 0x185FD, then how will it knows the end of code ?

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

now i'm more clear on the crc concept.

have posted some ques on the above thread.

Mehul9 wrote:
have posted some ques on the above thread.
Umm, no, you haven't ;-)