CF_V1: Flash PageErase --> MCU crash at certain address

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CF_V1: Flash PageErase --> MCU crash at certain address

Jump to solution
793 Views
alias5000
Contributor I

Hey there,

I'm developing on ColdFire V1 (MCF51QE128) using CodeWarrior v10.1. All flash routines are taken from AN3942.

BurstProg and PageErase are working in general, but:

 

When I want to Erase several pages in one function, the microcontroller crashed (debug session is terminated, connection lost; micro controller does wierd things). This happens in this function, when i>= 12:

Spoiler
void deleteAllRecordings()
{
    unsigned int i;
    flashSettings.currentDataLoc = 0;
    saveSettings(); //does some PageErase and Burstprog at 0x14000 - 0x143FF
    DisableInterrupts;
    for(i=0; i < (FLASH_MAX_ADDRESS-FLASH_DATA_BASE)/1024; i++)
    {
         Page_Erase((unsigned int *) FLASH_DATA_BASE + i*1024);
    }   
    EnableInterrupts;
}

 Where:

  • FLASH_MAX_ADDRESS = 0x20000
  • FLASH_DATA_BASE = 0x14400

So, this function crashes, when address is 0x17400 or higher (I tested it with i=12 or i=13, by skipping i=12).

 

Please help me finding the source of this problem.

 

Thanks in advance!

alias5000

Labels (1)
0 Kudos
1 Solution
521 Views
kef
Specialist I

Oh, it's pointer arithmetic related bug:

 

when you incement some pointer by N, it is incremented by the size of pointer data times N. So if int* ptr points to 0x14400, and in case sizeof(int)==4, ptr+1 will point to 0x14404. What happens in your code is that you first typecast base to int*, then add to that 1024*4*i, so you are erasing 0x14400, then 0x14400+1024*1*4, 0x14400+1024*2*4, 0x14400+1024*3*4 etc. Try calculating integer address first, and then typecasting it to pointer type:

 

       Page_Erase((unsigned int *) (FLASH_DATA_BASE + i*1024));
 

View solution in original post

0 Kudos
4 Replies
522 Views
kef
Specialist I

Oh, it's pointer arithmetic related bug:

 

when you incement some pointer by N, it is incremented by the size of pointer data times N. So if int* ptr points to 0x14400, and in case sizeof(int)==4, ptr+1 will point to 0x14404. What happens in your code is that you first typecast base to int*, then add to that 1024*4*i, so you are erasing 0x14400, then 0x14400+1024*1*4, 0x14400+1024*2*4, 0x14400+1024*3*4 etc. Try calculating integer address first, and then typecasting it to pointer type:

 

       Page_Erase((unsigned int *) (FLASH_DATA_BASE + i*1024));
 

0 Kudos
521 Views
alias5000
Contributor I

Oh, yes, what a stupid mistake!

 

Thank you very much for this hint :smileyhappy:

0 Kudos
521 Views
kef
Specialist I

Isn't watchdog enabled?

0 Kudos
521 Views
alias5000
Contributor I

Hm, that is a good hint.

Watchdog (COP) is enabled. For testing purposes I diabled it, which didn't change anything in behaviour. But obviously there is a reset happening, because the main routine is re-executed from beginning, when I perform this flash-erase in free run mode (--> no debugging).

 

I copied the output of srs-register to some LEDs and found out, that an illegal Address reset happens. Flash is unprotected (FPS = 7f, FPOPEN = 1). I don't see, why this happens.

0 Kudos