I am trying to validate the flash during a self test using a CRC check. Most parts are in place, but one issue remains. How do I find the end of the flash (i.e. the amount of flash to be checked)?
I don't understand - don't you know how large the device in question actually is?
If you want to save time by only verifying the used flash region, you will have to ask the linker.
Thank goodness there is a way to access these values from C: infocenter.arm.com/.../armlink_chdcgbjd.htm
Enjoy Marcus
Hi Pontus,
I'm trying to do the same for the internal ROM on an LPC2292. My idea is to run an int- pointer from a start-adress (0x000) to the end of the internal ROM and calculate a crc32 for each int-value. I place the expected value at a certain adress (extern unsigned int const flash_crc32 __attribute__ ((at(CRC_FLASH_POSITION))) = CRC_FLASH;) and skipp this value when calculating. Still, I get a different crc every time I change the expected value ....
I would be interested in your approach how to do that ...
Marco
I found another trick... Put this in main.c (or where suitable)
#pragma arm section rodata = "codeEnd" const int romCrc = 0xFF; // This is the place for ROM CRC
In the Project Wizard->Linker the "Use Memory Layout from Target Dialog" must be unchecked and scatter file must be edited. This is what I added:
*.o (codeEnd, +Last)
... and now the file looks like this:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x00000000 0x00080000 { ; load region size_region ER_IROM1 0x00000000 0x00080000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) *.o (codeEnd, +Last) } RW_IRAM1 0x40000000 0x00010000 { ; RW data .ANY (+RW +ZI) } }
Then, the CRC check can be performed.
int crc; crc=calc_crc(0x0,&romCrc); if(crc != romCrc) { // Do what has to be done }
(Datatypes may not match in my examples)
Next step is to build a peice of software that takes a hexfile generated by Keil and put a correct CRC in that one...
thanks for your information. While working with your example code, I came up with another solution based on my previous approach. Just for the sake of the dicussion:
1) I place the expected crc in the internal flash
#define CHECK_FLASH_CRC_EXPECTED 0x280A5642 #define CHECK_FLASH_CRC_POSITION 0x00001000 unsigned int const flash_crc32 __attribute__ ((at(CHECK_FLASH_CRC_POSITION))) = CHECK_FLASH_CRC_EXPECTED;
2) Then I calculate a crc32 over the whole internal flash, just skipping the position of the expected crc
#define CHECK_FLASH_START 0x00000000 #define CHECK_FLASH_STOPP 0x0003DFFF int check_flash() { unsigned int *adr_flash_start; unsigned int *adr_flash_end; unsigned int *adr_crc_expected; unsigned int crc_calculated; unsigned int crc_expected; crc_calculated = 0; adr_flash_start = (unsigned int*)CHECK_FLASH_START; adr_flash_end = (unsigned int*)CHECK_FLASH_STOPP; adr_crc_expected = (unsigned int*)CHECK_FLASH_CRC_POSITION; crc_expected = *adr_crc_expected; do { if(adr_flash_start != adr_crc_expected) { crc32_check_data(&crc_calculated, (char*)adr_flash_start, 4); } adr_flash_start++; }while(adr_flash_start < adr_flash_end); if(crc_expected == crc_calculated) { return(CHECK_FLASH_OK); } return(CHECK_FLASH_ERROR); }
I had to consider that the actual flash size in the lpc2292 is just 248k, therefore end of flash is 0x0003DFFF.
The disadvantage in my example is, that the crc is calculated over the whole flash whereas yours just uses the actual used memory.
An advantage could be, that you don't have to edit your hexfile, you only have to modify the define CHECK_FLASH_CRC_EXPECTED.
Anyway, thanks for sharing, Marco
-> Still, I get a different crc every time I change the expected value ....
May this be related to Error Correction Code (ECC)? Some NXP LPC2xxx devices use ECC to correct single bit flash errors.
John,
-> May this be related to Error Correction Code (ECC)? Some NXP LPC2xxx devices use ECC to correct single bit flash errors.
The wrong crc was just my fault: Had the expected value somewhere else in my code ....