mc9s12dg256: lrae&lfae-style bootloader help

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

mc9s12dg256: lrae&lfae-style bootloader help

3,881 Views
HenryL
Contributor III
I am implementing a bootloader similar to the app notes for LRAE & LFAE.

I am using Cosmic compiler generating three s19 files
BOOT1.s19 (equivalent to LRAE)
BOOT2.s19 (equivalent to LFAE)
MAIN.s19 (the main app)

BOOT1 resides in ppage $3F starting at address $F800. It looks for an EE variable that stores an address to the MAIN app. If empty or invalid, will then wait to be programmed.

BOOT2 gets programmed into RAM (mapped at $1000 - $4000) via BOOT1.

MAIN is multi paged starting at $5100 and is programmed via BOOT2. I've mapped eeprom to $4000 to $5000, so ppage $3E actually starts at $5000, and a jumptable for interrupts reside at $5000 to $5100, so the MAIN app starts at $5100. After programming, I write $5100 to the EEprom variable that BOOT1 looks for.

All this is done successfully, raw data from s19 files are written to the appropriate locations in flash and eeprom. But I cannot get the MAIN to execute. On bootup to BOOT1, I tell the micro to jump to the location stored in the EE variable like this
    _asm("tfr d,y", GEuintAppAddr);
    _asm("jmp 0,y");

but nothing happens. either wrong address, or MAIN has an error. But I've flashed the micro via BDM using MAIN.s19 directly without problems. Only difference is when flashing directly, I include the interrupt vector in linking. The interrupt vector is already linked in BOOT1 since I've protected that sector of flash. This is what the jumptable is for. Interrupt vector points to a location in the jumptable, which then jumps to the actual function performing interrupt routines.

My other suspicion is that both BOOT1 and MAIN has linked the startup file crtsi.s required by COSMIC, and it gets executed twice in the code (once in BOOT1, and 2nd when BOOT1 jumps to $5100) which somehow interferes.

I know most ppl use codewarrior here, but if anybody can give me some pointers or ideas of where to look, I'd very much appreciate it.
Labels (1)
9 Replies

1,206 Views
HenryL
Contributor III
according to this example in the cosmic user manual:
_asm(“tfr b,ccr”, varcc);
The varcc variable is passed in the d register, as a first argument. The
_asm sequence then transfers the low byte from the b register to the
condition register.

So in my code, GEuintAppAddr gets loaded into d register. Then I transfer d to y. Then I jump to y. This is the method i used when jumping to the start of BOOT2 from BOOT1 which is loaded into RAM. The only difference is I'm passing a variable of type (unsigned char *).

If you have a different or better code, please advise. Thanks.


Message Edited by Henry L on 2008-12-24 11:17 AM
0 Kudos
Reply

1,207 Views
kef
Specialist I
I don't know Cosmic, but how I understand excerpt from manual is this:
 
1)First somewhere above in the code The varcc variable is passed in the d register, as a first argument. 2)And then The _asm sequence then transfers the low byte from the b register to the condition register
 
I'm not sure what that ",varcc" does, but I think it tells compiler that varcc variable is used in the code and that compiler shouldn't optimize varcc out. I can be wrong. If GEuintAppAddr is not an auto variable on the stack, then I would try
 
 
    _asm("  LDY  GEuintAppAddr" ,    GEuintAppAddr);
    _asm("  jmp 0,y");
or
 
    _asm("  LDY  _GEuintAppAddr" ,    GEuintAppAddr);
    _asm("  jmp 0,y");
 

1,207 Views
HenryL
Contributor III
I have confirmed that cosmic's _asm() function works as I originally thought.
The format is _asm(assembly string, arguments) where arguments is values that are loaded into d register, then the aseembly string is executed. The assembly string can even be entirely independant of the d register. The _asm() function simply provides an easy way to load values from C code. _asm() can also be used without arguments, and just assembly string only.

Now that that's out of the way, i'm still having the problem with PPAGE register. I've checked the MISC register, and it is set to 0x0D, which allows flash to be written. I believe this value is correct and nothing else needs to be changed.
0 Kudos
Reply

1,207 Views
kef
Specialist I
OK.
Did you try to concatenate S records and debug complete binary image? I mean debugging complete image with for example BOOT1 and MAIN loaded at the same time? You can remove all S0 and S9 records from first image, S0 from second image, then concatenate both files. Notepad could be used for this. Good luck.
0 Kudos
Reply

1,207 Views
HenryL
Contributor III
I can concatenate the s records. But how do I debug the complete image? Am i looking for something in particular?
0 Kudos
Reply

1,207 Views
kef
Specialist I
I can't write you stepbystep instruction, but at least you have map file with function addresses, all debuggers are able to show disassembled code and you are allowed to put breakpoints at known addresses. Then for example CW debugger allows to load symbols only. So you can load bootloader symbols first and step to your tfr-jmp sequence and see if it jumps to correct address and if not then why. If it jumps ok, then you load symbols for bootloaded app. And so on. If debugger, after load of bootloaded app symbols, resets or jumps somewhere, then try to put breakpoint at known address in your bootloader, maybe again at your tfr-jmp sequence.
Good luck and happy New Year.
0 Kudos
Reply

1,207 Views
HenryL
Contributor III
I finally got it working! thanks for all the help!

now i need to port it for the mc9s12dg128. As far as I know, the only difference is size of RAM, EE, and flash. I think I should be able to flash directly and simply change the mapping of memory. Is there anything I should be aware of before beginning?
0 Kudos
Reply

1,207 Views
HenryL
Contributor III
i'll look into that.

but first, I may have discovered another issue.
To program flash, I have to first erase the sectors before writing new data. I have it set up so that I erase each page entirely before programming page at a time. I erase the data in the paged window, but the same does is not reflected in the physical address when I use the debugger to look at the values.

for example, I erase page $30 by setting PPAGE = 0x30, then use flash sector erase FCMD = 0x40, to erase address at 0x8000 to 0xBF00. (Lower byte is ignored since sector erase only looks at high byte of the address and erases the entire 256 byte sector.)

Using the debugger tool, I can see that location $8000 is indeed cleared to FFFFFF, but the physical address for page $30 at $C0000 has not been cleared. An I doing something wrong?

0 Kudos
Reply

1,207 Views
kef
Specialist I
What's this?

    _asm("tfr d,y", GEuintAppAddr);

Of course it doesn't load GEuintAppAddr to D or Y register.
0 Kudos
Reply