cancel
Showing results for 
Search instead for 
Did you mean: 

Need some help creating an IAP app

jmullaney
Associate II
Posted on December 26, 2008 at 23:44

Need some help creating an IAP app

#iap #bootloader #upsd3253
108 REPLIES 108
jdaniel
Associate II
Posted on May 17, 2011 at 12:04

mulls14,

Wow... that is alot of questions. As far as two weeks goes, imagine how I felt when there wasn't anyone on here who seemed to have tried what I was doing. I'll try to take this point by point:

1. You basically have to TELL the linker where to put the statusbytes, because otherwise every code change could move them around and you wouldn't be able to find them (there'd certainly be other FFFF's in there somewhere). If you put the following in your Keil project (under project->options for target XXX, BL51 locate tab) in the ''Code'' line on the dialog, it will locate if for you:

?CO?STATUSBITS(0xXXXX)

where ''statusbits'' is whatever you named the C file with the definition and 0xXXXX is where in code space you want it placed (oh yeah, the ?C0? part tells it you want to locate the ''constant'' segment from this module.)

2. The reasoning is complicated, but goes like this. 8051's don't know anything about pages. They just know about code memory fetches and data memory fetches. What ST has done is provide some internal logic to allow you to activate different chip selects on different chips based on the contents of the VM register. When the 8051 is running a program, it just keeps fetching opcodes from code memory. So... imagine that both startup files are exactly the same and the uPSD is initially running out of secondary flash. When you change the VM register, the next thing the 8051 is going to do is try to grab the next bit of code and it will use whatever code address would have been next in the secondary flash file (because it's just incrementing the PC). If the code WASN'T identical and located at the same spot when you redirect the chip select to main flash, it might try loading in the middle of an opcode or some other random place. Basically, the idea is to get some KNOWN CODE at that exact location in main flash so that it can continue fetching and will never be the wiser. Since you still have to finish your startup and variable initialization, etc. anyway, the easiest way to do this is to make the startup code identical and locate them both to the same place. I hope that makes it clearer.

3. It has a bit to do with the way I initialize the uPSD. In my project, at reset, the uPSD has secondary flash in code space only from 0 - 7FFF and main flash in DATA space only from 8000-FFFF. So, if I just changed the page, then it would try to load from main flash, but that wouldn't be allowed because of the VM register (still in data space). So... first, I make the VM change. This leaves secondary flash in code space in the lower 32kB, but now shifts main flash to CODE space in the upper 32kB. I have to still leave it able to execute from secondary flash, because it's running out of the lower 32kB and if I took that away, it again wouldn't be able to fetch opcodes. Next, I change the page. This swaps in main flash for BOTH the lower 32kB and upper 32kB. But remember, the code at the location of the program counter in main flash is IDENTICAL to what was in the secondary flash, so the 8051 core is still fat dumb and happy. The final VM change is just there for safety really, but it tells the uPSD to only execute code now from main flash (since I'll only want to run from secondary flash again if I try to switch over to do IAP).

4. Doesn't really matter. I use different pages depending on whether it's production code or code for use on my emulator. Since the uPSD resets to page 0, however, it's probably a good idea for you to use that for secondary flash and then some other page for your first page of main flash.

5. Yes... that's the reasoning. Refer to the previous long-winded description for why.

6. Just like above, you put another directive in the ''code'' line under the BL51 locate tab in options. This time the directive would be:

?C_C51STARTUP(0xXXXX)

again, 0xXXXX is just some address you happen to like that's convenient. and C_C51STARTUP is the name Keil's startup.a51 file gives to that segment. You could change it if you like.

7. My app is larger than 32kB as well. What is do is map fs0 into the LOWER 32kB of code space and fs1 into the UPPER 32kB of code space for a total of 64kB of code space. I haven't configured actual code banking since it's not needed for me. If all you want to do is store some code tables or something in the other flash pages, then you can probably handle that manually. Otherwise, you'll have to do some dancing to get the linker to understand how your code pages are laid out. You'd have to chart a course on that one yourself, but once you get the gist of how the above is working, I think it'll click for you.

8. A good key sequency (albeit a long one) would be a string like: ''This could not occur by random chance''. The basic idea is that you need some string long enough that the odds of it happening because of random contents of memory at startup are essentially zero. Also, you'll notice in my checkloop that I destroy it as I check it so that if there's a reset, it's not still hanging around in there. I use this all to tell the processor to run IAP. As in, imagine something happens in the application that makes me want to run IAP to reprogram the application. I write a page value to a specified location in memory (the one that's checked by startup.a51). Next, I write this key sequence in memory. Then I let the watchdog reset the processor. Since it didn't power down, the contents of ram are preserved. At startup, I see that the page value points to the bootloader, but keep in mind that there's still a 1/255 chance that this byte is just random junk from a powerup. So... if THAT matches, I check this long key sequence and if it's all there, I say the only reason it would be is if the application is asking me to run the bootloader and so I stay in secondary flash and get ready for reprogramming. Is that clearer?

Well... hope that helps. I agree the lack of practical IAP stuff is frustrating, but that seems to be the case for every processor manufacturer, not just ST. Typically I guess they figure the people working on this have very specific stuff that their hardware has to do, so they have to hash out the details on their own.

yf800930
Associate II
Posted on May 17, 2011 at 12:04

Thanks a lot, I will try it later! Wish U && I success

[ This message was edited by: moon on 31-12-2004 10:13 ]

jmullaney
Associate II
Posted on May 17, 2011 at 12:04

Im going skiing in VT this weekend, and I will be able to get alot of reading done on the way to the mountain. But in the mean time I was hoping that you could give a quick look at this attempt at implementing your bootloader routine. The Startu32.A51 should be attached. Don't laugh.

-Do you see a problem locating the bootloader routine before the standard memory clearing operations? Any other page layout concerns?

-Do the page & vm register definitions look familiar?

-Do the vm register RD and PSEN definitions look familiar?

-Don't know what 'pageval' is refering to. Why not use #PAGEREG?

-What mem should 'checkcode' be located in? I assumed SRAM, up in XDATA at around XDATASTART + 1K ~ 2400H.

-Am I correct to say that for starters, my BOOTLOADER_PAGE and APPLICATION_PAGE can both be set to page 0? The IAP app is located in CSBOOT0-3 and the Main app in FS0.

Thanks Again!

jmullaney
Associate II
Posted on May 17, 2011 at 12:04

Duh!

Have a happy New Year !!! :-]

jdaniel
Associate II
Posted on May 17, 2011 at 12:04

mulls14,

Hope you had fun skiing. I think you may have attached the wrong STARTUP.A51 file. All I see in there is some prescaler loading and such, but nothing really having to do with IAP, so I'm not going to be able to answer most of your questions.

The ''pageval'' value I use is just a single byte that gets set to zero when I want to run the bootloader. If it's not zero, I don't even have to bother checking the check code on startup, so it just speeds things up a bit. Probably not all that necessary.

Checkcode should be in ram, but you can put it wherever you like. It's not crucial that it be in xdata, but since checking it isn't time-sensitive, that's the most likely place for it.

The question about APPLICATION_PAGE and BOOTLOADER_PAGE makes me think I've lost you. If they were the same page, then there would only be one application. Unless, what you mean is you're going to have secondary flash OVERLAY the main flash in the lower 32kB and then just remove access to it by changing the VM register. That should work without requiring a page change, and you could probably eliminate and/or modify some of the code.

[ This message was edited by: phaze426 on 06-01-2005 14:41 ]

jmullaney
Associate II
Posted on May 17, 2011 at 12:04

Oops, Here it is....

And here are the original questions edited in response to your last message...

-Do you see a problem locating the bootloader routine before the standard memory clearing operations?

-Any other page layout concerns?

-Do the page & vm register definitions look familiar?

-Do the vm register RD and PSEN definitions look familiar?

-I understand 'pageval' now, just a short-cut. I did a quick comment mod to the file to indicate the general concept.

Original Question...

-Am I correct to say that for starters, my BOOTLOADER_PAGE and APPLICATION_PAGE can both be set to page 0? The IAP app is located in CSBOOT0-3 and the Main app in FS0.

Yeah, I was refering to the overlay of main & secondary flash both in page 0. How does this differ from your mapping?

Crap, now I AM confused.

Wait, is the following mapping what you were expecting?...

-One bootloader app resides in secondary mem, and a duplicate resides in main fs0. This way, VM can be toggled without screwing up the PCounter.

-The main app (with identical startup.a51 & C_C51startup etc.) resides lets say in main fs1 (page 1) which is the resoning behind

different pages for boot & main apps.

Well, If that is the case, then I could certainly use that mapping instead. But, I don't get how your app which is >32k, doesn't require banking(paging).

Here is a little sketch pad:

Can you possible DRAW this IAP map you are refering to. Every application note I read refers to a different mapping, and I am now stupid from reading them all.

Main Flash

Page0 Page1 Page2 Page3...

0xFFFF ----------------------------------------------->

| | | |

| | | |

| | | |

| | | |

| | | |

| | | |

0x8000 ----------------------------------------------->

Secondary

0x7FFF ------------

| |

-----------

| |

-----------

| | [Reserved Entirely for BootLoader]

-----------

| |

0x0000 -----------

Once again,

Thanks buddy

PS: Skiing was crap, too much ice & not enough snowbunnies :p

yf800930
Associate II
Posted on May 17, 2011 at 12:04

my IAP baby is working now. and I think there are some defaults in your startup.a51:

1) if there is something wrong with your APP, what will happen? you must use JTAG again.

2) flash can only write to 0, so how can you get 0xFE?

next monday, i will post my startup.a51 here, wish you all success!

[ This message was edited by: moon on 08-01-2005 06:41 ]

jmullaney
Associate II
Posted on May 17, 2011 at 12:04

Wow, that map diagram looks like crap! here, try this.

jmullaney
Associate II
Posted on May 17, 2011 at 12:04

moon,

Im not sure if I understand the questions, but maybe this will help.

1)If all flash memory is empty (new chip), or if something is wrong with my IAP app located in secondary flash, then yes, I must use JTAG to program the device (ISP). My IAP or (bootload) program interacts with my windows based program using serial commands & data-packets. The bootloader can now be used to first-time-program or re-program primary flash with my main application.

2)Once the bootloader is finished programing the main application into primary flash, it must write a status byte somewhere within the main app's constant code space, which indicates that the main app is valid. So, somewhere in the main application is a 'const unsigned char code statusbyte 0xFF' which resides in constant code space. You can actually see this byte somewhere in the first few lines of the hex file. Simply write 0xFE to this byte's address to replace it.

yf800930
Associate II
Posted on May 17, 2011 at 12:04

MOV DPTR, VMREG

MOV A, 86H

MOVX @DPTR, A

MOV R0, KEY_LENGTH - 1;

CHECKBOOT: ;;;;;;;;;;3009--3000

MOV A, 00H

ADD A, R0

MOV DPL, A

MOV A, 30H

ADDC A, 00H

MOV DPH, A

MOVX A, @DPTR

MOV R1,A

MOV A,R0

MOV R2,A

MOV A,'x'

MOVX @DPTR, A ;擦除标识

;wipe stats

MOV A,R2

XRL A,R1

JNZ RUNBOOT ;如果是冷�?�动,从IAP程�?�?行:code restart, run iap

DJNZ R0,CHECKBOOT

RUNAPP: ;�?�级完�?,watchdog�?�?��?��?行APP ;iap finished run app

MOV DPTR, PAGEREG

MOV A, APPLICATION_PAGE

MOVX @DPTR, A

MOV DPTR, VMREG

MOV A, 8CH

MOVX @DPTR, A

JMP DONE

RUNBOOT:

; MOV DPTR, VMREG

; MOV A, 86H

; MOVX @DPTR, A

MOV DPTR, PAGEREG

MOV A, BOOTLOADER_PAGE

MOVX @DPTR, A

MOV DPTR, VMREG

MOV A, 92H

MOVX @DPTR, A

DONE: