Re-flashing last sector 0xFE00 in MC9S12DG128

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

Re-flashing last sector 0xFE00 in MC9S12DG128

4,449件の閲覧回数
TaB
Contributor I
I used AN2720 to create a boot loader for flashing my application. Since the boot loader doesn't use interrupts I need to reprogram the ISR Vector table to addresses in the application. My boot loader is in the 0x4000 (3E) block and my application in the 0xC000 (3F) block. My unimplemented ISR is at FF7E for both the boot loader and application. I have placed Application checksums in the 6 bytes below this. I am running CodeWarrior 5.7 with P&E Micro USB Multilink Interface for debugging.

Everything works fine until I try to erase the last sector. First it doesn't erase the sector, then it will only write from 0xFE00 through 0xFEFD. At this point I seem to still be able to see all of the flash. However when I exit and try to return to a new debug session, the security bits have been set and I have to run an unsecure program to regain access. If I only erase the last sector it still affects the security bits, even though in both cases I still see address 0xFF0F = 0xFE when finished.

I've tried just over-writing a word in the vector table, but I get an Access Error. I also tried blocking a write to addresses 0xFF00 through 0xFF1F to ensure that they didn't accidently get programmed, no difference.

To create the simplest flash programmer possible I created a project with a wrapper main.c around the app note files. See attached

Eventually I would like to be able to re-program the boot loader too. I created a version of flash.c & Do_On_Stack.asm that runs completely in RAM. The idea is to download via RS-232 the complete boot loader, verify a checksum, then go to RAM to reprogram it. Since interrupts are disabled I thought that I should be able to reprogram the last sector first then the boot loader. With this version I can program my application just fine, but still can't re-program the last sector, FE00.

BTW: I added FCNFG=0; and PPAGE=0x3F; before trying to erase or reprogram the last sector.

What am I doing wrong?
ラベル(1)
0 件の賞賛
返信
7 返答(返信)

1,901件の閲覧回数
CompilerGuru
NXP Employee
NXP Employee
Well, I'm not answering your question, but AFAIK,
having the bootloader at 0x4000 and the app at 0xC000 cannot be done without the danger of loosing the device in the field if the bootloader would just have erased the reset vector when a power off happens.
So if you want to have a really reliable boot loader, you have to place it into the top area so the vectors are never reprogrammed.
That your loader does only use the reset vector and no other one does not really help :smileysad:. You have to implement some vector redirection with this setup, I guess to avoid that was the reason to place the app at 0xC000.

This may actually avoid the issue you have with the protection too, as then you would no longer reprogram it.

Daniel
0 件の賞賛
返信

1,901件の閲覧回数
TaB
Contributor I
Can someone give my a simple example of the redirection code that will reside in RAM pointed to by the vector table? The only way that I know how to do this is to create it in flash, then copy it to the RAM block.
0 件の賞賛
返信

1,901件の閲覧回数
sjmelnikoff
Contributor III
If you erase flash location 0xFF0F (FSEC), this sets the security bits, which means that next time you reset the processor, you won't be able to write to flash at all without first doing a mass erase. You can't get around this using backdoor key access, as that is also disabled by erasing this location.
 
As mentioned above, the best place to put a bootloader is in the 0xC000 block. You have an interrupt vector table as part of it, with each vector jumping to a secondary table at a fixed location in the application.
 
Incidentally, it's not necssary to run the whole bootloader in RAM. The only part which needs to be executed out of RAM is the code which starts the write to flash, and waits for it to finish. You can do it in 10 bytes, like this:
 
WriteToFlash:
  bset  FSTAT, #CBEIF     ; execute command by writing 1 to CBEIF
  brclr FSTAT, #CCIF,*+0  ; loop while CCIF = 0
  rts                     ; return
 
Steve.
0 件の賞賛
返信

1,901件の閲覧回数
TaB
Contributor I


sjmelnikoff wrote:
If you erase flash location 0xFF0F (FSEC), this sets the security bits, which means that next time you reset the processor, you won't be able to write to flash at all without first doing a mass erase. You can't get around this using backdoor key access, as that is also disabled by erasing this location.
As mentioned above, the best place to put a bootloader is in the 0xC000 block. You have an interrupt vector table as part of it, with each vector jumping to a secondary table at a fixed location in the application.
Incidentally, it's not necssary to run the whole bootloader in RAM. The only part which needs to be executed out of RAM is the code which starts the write to flash, and waits for it to finish. You can do it in 10 bytes, like this:
WriteToFlash:
bset FSTAT, #CBEIF ; execute command by writing 1 to CBEIF
brclr FSTAT, #CCIF,*+0 ; loop while CCIF = 0
rts ; return
Steve.





sjmelnikoff wrote:
If you erase flash location 0xFF0F (FSEC), this sets the security bits, which means that next time you reset the processor, you won't be able to write to flash at all without first doing a mass erase. You can't get around this using backdoor key access, as that is also disabled by erasing this location.
As mentioned above, the best place to put a bootloader is in the 0xC000 block. You have an interrupt vector table as part of it, with each vector jumping to a secondary table at a fixed location in the application.
Incidentally, it's not necssary to run the whole bootloader in RAM. The only part which needs to be executed out of RAM is the code which starts the write to flash, and waits for it to finish. You can do it in 10 bytes, like this:
WriteToFlash:
bset FSTAT, #CBEIF ; execute command by writing 1 to CBEIF
brclr FSTAT, #CCIF,*+0 ; loop while CCIF = 0
rts ; return
Steve.



steve,
That would work except that when I reflash the boot, the erase and write loop must be in RAM. This being the case, for only one reflash version, I reprogram the app this way too, except that I can do it in multiple blocks since I can return from the erase and write loops.
0 件の賞賛
返信

1,901件の閲覧回数
TaB
Contributor I
For my boot loader the only vector I'm using is at 0xFFFE, the reset vector when I power on. However for application software I've go CAN, RS-232, I2C, Real time and other interrupts.

Since erasing is by sector, I don't see the advantage of using 0xC000 for the boot loader. As it currently stands I use 0x5800 through 0x7FFF for the application. I have a limitation of bringing in 0x1600 bytes of code for reprogramming, so I must reprogram in 0x1600 max byte zones.

The boot loader is much less than that, so it can be reprogrammed completely while running the flash programmer from RAM.

What is the reason why I can't erase the vector sector, 0xFE00, or program above 0xFEFC?
0 件の賞賛
返信

1,901件の閲覧回数
Lundin
Senior Contributor IV
Also, you can't run flash-erasing code from 0x4000 and erase 0xC000 since they are part of the same block/bank.

I didn't check the code, but I assume that it is executed from RAM and no access is done to the flash at 0x4000 during the flash programming. Otherwise, strange things will happen.
0 件の賞賛
返信

1,901件の閲覧回数
TaB
Contributor I
Yes they're in the same block, that's why I used the strategy in AN 2720. Currently the application isn't big enough to use the 8000-BFFF pages.

I also noticed that when I'm reprogramming a sector that the memory window in CodeWarrior debugger must not be displaying this sector or it won't work.

What I'm really looking for is a method to reprogram the last sector where the ISR vectors are located. I may have to resort to mapping them to RAM and redirecting them in the application.
0 件の賞賛
返信