Runtime FLASH erase issue (9S08DZ60A)

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Runtime FLASH erase issue (9S08DZ60A)

ソリューションへジャンプ
3,682件の閲覧回数
belskyc
Contributor III

Hello,

I'm working on an application using the MC9S08DZ60ACLH where I'd like to store the "factory configuration" into a block of FLASH to be used later for a "restore to factory defaults" reset service routine.  I currently have successful EEPROM erase/write routines, so my first impression was to adapt these to a FLASH erase/write routine.  I've investigated the forums on FLASH erasing/writing and have started by implementing the common CopyToRAM() function in order to execute the FLASH erase/write from RAM.  This CopyToRAM() executes fine.  The problem is after executing the Erase_FLASH() function during runtime from RAM, my controller UUT gets 'lost', resets a few times (assuming due to the COP) and then finally locks up.  A curious symptom is that if I step through the Erase_FLASH() function using the CodeWarrior Real-Time Debugger, then the UUT will NOT lock up and a 256-byte block of FLASH will successfully erase, but if I simply start the firmware from the beginning running real-time the UUT operates OK until it executes the Erase_FLASH after which it resests then locks up.  I've attached my implementation.  A couple questions:

 

1)  Has anyone seen this symptom before?

2)  After examining my code, can anyone see where I'm going wrong?

3)  Does anybody know where I can find exactly the addresses of the FLASH blocks?  Perhaps I'm erasing a block containing code (even though I believe I have my PRM file setup correctly and the MAP file seems to verify this).

4)  The DZ60A data sheet says the FLASH block size is 768 bytes, why would the Real-Time Debugger Memory window only show a 256-byte block erased?  I'm wondering if this is real or if the Real-Time Debugger is giving me bogus data. 

 

Thanks very much for your input.

~

 

Copy_of_IFC_DZ60.prm

Copy_of_RAM_Funcs.c

Copy_of_Main.c

Message Edited by belskyc on 2009-07-28 04:25 PM
Message Edited by t.dowe on 2009-09-04 02:06 PM
ラベル(1)
0 件の賞賛
返信
1 解決策
1,608件の閲覧回数
bigmac
Specialist III

Hello, and welcome to the forum.

 

I can see a couple of issues with your sector erase code.

 

Firstly, you have globally disabled interrupts near the start of the function, and have then incorrectly re-enabled interrups after the command is launched.  Interrupts should not be re-enabled until after the FCCF flag is set (or an error exit occurs).  The flash cannot be read during the execution of the command, so the interrupts vectors are inaccessible.  It is possible that a hardware interrupt, perhaps a timer interrupt, could occur during the 20 millisecond sector erase period.

 

Are you using the derivative header file associated with the CW installation?  If so, you seem to be using the bit identification macros, rather than the bit mask macros required by your expressions. For example,

FSTAT |= FSTAT_FCBEF;      should be corrected to the following

FSTAT = FSTAT_FCBEF_MASK; // Launch command

 

Similarly, for the error flag tests. 

while(!(FSTAT & FSTAT_FCCF_MASK)) { }

 

Personally, I would not bother with a separate test of the FCBEF flag, since the FCCF flag indicates the completion of the command.  In fact, for more compact code, I would probably derive a composite mask for the FCCF flag and the two error flags, and then exit the wait loop when any one of the three flags became set.

 

Note that not all your code needs to reside in RAM, only the code between the launching of the command and the exit from the wait loop.

 

For the DZ60 device you also have another alternative to running the code from RAM.  It should be possible to store and run the code in EEPROM flash, which is separate from the main flash array.

 

Regards,

Mac

元の投稿で解決策を見る

0 件の賞賛
返信
5 返答(返信)
1,609件の閲覧回数
bigmac
Specialist III

Hello, and welcome to the forum.

 

I can see a couple of issues with your sector erase code.

 

Firstly, you have globally disabled interrupts near the start of the function, and have then incorrectly re-enabled interrups after the command is launched.  Interrupts should not be re-enabled until after the FCCF flag is set (or an error exit occurs).  The flash cannot be read during the execution of the command, so the interrupts vectors are inaccessible.  It is possible that a hardware interrupt, perhaps a timer interrupt, could occur during the 20 millisecond sector erase period.

 

Are you using the derivative header file associated with the CW installation?  If so, you seem to be using the bit identification macros, rather than the bit mask macros required by your expressions. For example,

FSTAT |= FSTAT_FCBEF;      should be corrected to the following

FSTAT = FSTAT_FCBEF_MASK; // Launch command

 

Similarly, for the error flag tests. 

while(!(FSTAT & FSTAT_FCCF_MASK)) { }

 

Personally, I would not bother with a separate test of the FCBEF flag, since the FCCF flag indicates the completion of the command.  In fact, for more compact code, I would probably derive a composite mask for the FCCF flag and the two error flags, and then exit the wait loop when any one of the three flags became set.

 

Note that not all your code needs to reside in RAM, only the code between the launching of the command and the exit from the wait loop.

 

For the DZ60 device you also have another alternative to running the code from RAM.  It should be possible to store and run the code in EEPROM flash, which is separate from the main flash array.

 

Regards,

Mac

0 件の賞賛
返信
1,608件の閲覧回数
belskyc
Contributor III

Hi Mac,

Thanks for the advice, you hit it right on.  That's awesome.  The issue was Enabling Interrupts before the FCCF bit check was complete.  Thus, I'm able to erase & write to the FLASH sector now.  I learned something new today. 

 

I do have one more question, though.  Are you familiar with the CodeWarrior Real-Time Debugger, in particular the "Memory" window?  I'm able to successfully erase & write to the FLASH segment now, but the "Memory" window in the Real-Time Debugger doesn't seem to update correctly.  In short, I added a for-loop in my code for debugging to read back out of the FLASH segment to verify the data was correctly written into FLASH.  This passed ok, but the "Memory" window in the Real-Time debugger shows the first 160 bytes of the FLASH segment as value 0xFF (thereafter the window displays the correct data), whereas when I read the values from these same addresses (by using the for-loop) the correct data is there.  Any ideas on this? 

 

Thanks again for the great insight,

~Belskyc

Message Edited by belskyc on 2009-07-30 04:03 PM
0 件の賞賛
返信
1,608件の閲覧回数
BenFan
Contributor III

Any updates in MEMORY window issue?

We have a problem with calculation of CRC over configuration parameters stored in flash (linear part) memory but are unable to debug the problem as the memory window is showing us old/wrong values. That’s the same with DATA window and when viewing single "variables" based in flash memory.

Any hints??

thnx

0 件の賞賛
返信
1,608件の閲覧回数
kef
Specialist I

BenFan,

 

I think you should modify Debugging Memory Map:

https://community.freescale.com/message/33624#33624

0 件の賞賛
返信
1,608件の閲覧回数
belskyc
Contributor III

Hello, I also forgot to add the FLASH/EEPROM configuration that I use for this application:

 

FCDIV = 0x13;  // FLASH & EEPROM clock = 200kHz [BusClk / (DIV + 1) = 4MHz / (19+1) = 200kHz].
   // = 0b00010011
   // B7 - Divisor Loaded Status Flag (DIVLD - Read Only)
   // B6 - Prescale (Divide) Flash & EEPROM Clock by 8 (PRDIV8 - Write Once)
   // B5:B0 - Divisor for Flash & EEPROM Clock Divider (DIV - Write Once)

 

Thus, my clock time appears to be valid at 200kHz (please remember that my EEPROM erase/write routines operate correctly). 

 

Ok, thanks again, and I still look forward to any insight you may have.

~

0 件の賞賛
返信