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
jmullaney
Associate II
Posted on May 17, 2011 at 12:04

I cannot quite grasp the IAP fucntionality yet. I'm a newbie working with the DK3200. I am familiar with the general mapping of an IAP program as follows:

Boot to secondary flash which contains the IAP program. The IAP program can perform various validity checks on primary flash sectors to determine good/bad status of main program. The IAP can then modify the VM and page register and ''jump'' to the page of the main program.

Can someone please give some specifics on the VM and page register modifications. :-[

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

IAP can be tricky. Before I even get started, do you plan to use this with an ICE (in-circuit emulator). Neither the one made by Nohau or by Manley support the most efficient means of performing IAP since it involves ''swapping out'' the entire code space. Let me know that and I'll be able to answer your question more effectively.

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

No emulators. simply using the DK3200.

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

Alright... here's the way to do it that I found most accomodating:

1. Create a memory map that has one page with secondary flash mapped in the lower 32kB of code memory and main flash mapped into the upper 32kB (or whatever) of data memory (with your RAM and the like in the lower 32kB of data memory). This map should have another page with main flash mapped into the lower 32kB of code memory and secondary flash not mapped anywhere.

2. Create a project for some compiler (I use Keil) to contain your IAP routines. Make sure to copy and include the STARTUP.A51 code from Keil if that's what you're using. In this project, write the various routines for programming the main flash, etc.

3. Create another project to contain your main application. Find an open block of fixed code memory and define some constants there that are all FF's, like so:

const unsigned int code statusbytes = 0xFFFF;

4. Modify the STARTUP.A51 file for BOTH projects to be IDENTICAL. This assembly code should, at startup, check the status bytes of the main application and if they're equal to some predetermined value (OTHER than FF), run the application. Otherwise, it should just run the IAP routines. The way the code runs the application is by changing the VM register to let it fetch code from EITHER main or secondary flash, THEN swapping to a page which places main flash in the space previously held by secondary flash. A final note is that you have to tell the linker to place this startup code (in Keil, the routine is C_C51STARTUP) at the EXACT same memory address. Just look at the memory map and pick someplace that looks convenient.

Notes:

- When you finish programming the main flash application, you should set the status bytes to whatever value you want to be your ''good'' indicator. For examples, I use 0xFE

- Your startup assembly code also needs to check if you're trying to switch into IAP mode. I do this by writing a long key sequence into RAM from the main application when IAP is initiated and then letting the watchdog reset the processor. I have my startup code check this BEFORE seeing if the application is valid, and if it's there I run the IAP routines. Make sure it's a long enough key sequence that random RAM contents at startup couldn't accidentally prevent you from running the application.

- When you start reprogramming flash, the very FIRST thing you should do is program your status bytes to 0x0000, that way if anything goes wrong, your startup code will know NOT to try and run a corrupted application.

There are some other nifty things you could do. With as much memory as the DK3200 has, it's possible to have multiple application images and have the startup code just run whichever one is valid. This way, you avoid ever having no application to run after a failed download.

Hopefully some of that will help. It took me quite a while to wrap my head around what's involved in doing all this manual paging.

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

Wow! Lots of work ahead of me.

Thanks for taking the time to explain that to me. It has been a real help. I'm sure that I'll have followup Q's eventually, but until then, good day sir.

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

I ask hesitantly as I do not want to bite the hand that feeds me.

Could you possibly attach/paste an example of the startup.a51 routine which provides the following functionality: checks main flash validity, looks for the IAP key pattern in RAM, and jumps to either main or IAP routines?

An example would put me further along the path of comprehension much faster.

I will understand if you choose not to disclose such information.

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

Sure, I can post some code that will give you a basic idea without divulging anything that I shouldn't. Also, the basic methodology I use here is from an app note I found somewhere on either this forum or another ST site. Finally, there will be no mocking my hideously inefficient assembly code. I'm normally a C-only guy.

MOV DPTR, VMREG

MOV A, (VM_REG_RD_MAIN_FLASH OR VM_REG_PSEN_MAIN_FLASH OR VM_REG_PSEN_BOOT_FLASH)

MOVX @DPTR, A

CHECKPAGE: MOV DPTR, pageval

MOVX A, @DPTR

JNZ RUNAPP ;If pageval doesn't point to bootloader, check and run app

MOV DPTR, PAGEREG

MOV A, BOOTLOADER_PAGE

MOVX @DPTR, A

;If we're here, the pageval appears to point to the bootloader. We check the checkcode

;in RAM against the key value to make sure that it's not just a random occurrence on

;startup. If they match, we run the bootloader.

CHECKRAM: MOV R0, KEY_LENGTH - 1 ;R0 = Loop index

CHECKLOOP: MOV DPTR, key

MOV A, R0

MOVC A, @A+DPTR

MOV R1, A ;Store next byte from key in R1

MOV A, LOW(checkcode) ;Add R0 to location of checkcode and load

ADD A, R0 ;into DPTR

MOV DPL, A

MOV A, HIGH(checkcode)

ADDC A, 00H

MOV DPH, A

MOVX A, @DPTR ;Fetch next byte of check code

MOV R2, A

MOV A, 'x'

MOVX @DPTR, A ;Wipe checkcode as we process it so we can get back to app

MOV A, R2

XRL A, R1 ;XOR with key byte in R1

JNZ RUNAPP ;If bytes don't match, check and run application

DJNZ R0, CHECKLOOP ;Otherwise, decrement loopcounter and jump

JMP RUNBOOT ;pageval =0 and key sequence good, so run bootloader

RUNAPP: MOV DPTR, (08000H + APPBITS)

MOVX A, @DPTR

CJNE A, 0FEH, RUNBOOT ;Make sure we don't run an invalid application

MOV DPTR, VMREG

MOV A, (VM_REG_PSEN_MAIN_FLASH OR VM_REG_PSEN_BOOT_FLASH)

MOVX @DPTR, A

MOV DPTR, PAGEREG

MOV A, APPLICATION_PAGE

MOVX @DPTR, A

MOV DPTR, VMREG

MOV A, VM_REG_PSEN_MAIN_FLASH

MOVX @DPTR, A

JMP DONE

RUNBOOT: MOV DPTR, VMREG

MOV A, (VM_REG_PSEN_BOOT_FLASH OR VM_REG_PSEN_MAIN_FLASH)

MOVX @DPTR, A

MOV DPTR, PAGEREG

MOV A, BOOTLOADER_PAGE

MOVX @DPTR, A

MOV DPTR, VMREG

MOV A, (VM_REG_PSEN_BOOT_FLASH OR VM_REG_RD_MAIN_FLASH)

MOVX @DPTR, A

DONE:

Hope some of that helps... let me know if anything's unclear, but I think it's lack of efficiency makes it pretty easy to understand.

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

Thank you. I am also primarily a C-guy, so please don't appologize for knowing more Assembly than me. 😉

I've got a meeting w/ GE this morning so I won't be able to perform any tests until afternoon'ish. But I'm sure your example code will answer many of my questions.

Thanks again!

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

Your example startup.a51 has helped tremendously. I have some questions though that I was hoping that you could answer before I get myself into trouble.

-----------------------------------------------

1:How do I locate the main app's statusbytes (0xFFFF) once defined? Do I simply open the .hex file in a hex viewer and look for it's location?

-----------------------------------------------

Previously, you had written:

Modify the STARTUP.A51 file for BOTH projects to be IDENTICAL.

2:Can you explain your reasoning behind using identical startup.a51's for both programs.

-----------------------------------------------

Previously, you had written:

The way the code runs the application is by changing the VM register to let it fetch code from EITHER main or secondary flash, THEN swapping to a page which places main flash in the space previously held by secondary flash.

3.I can see this in your startup.a51 example. There is a VM change,Page change,and then VM change again. Could you explain each change in a bit more detail?

4.What pages are you using for #APPLICATION_PAGE & #BOOTLOADER_PAGE ?

-----------------------------------------------

Previously, you had written:

A final note is that you have to tell the linker to place this startup code (in Keil, the routine is C_C51STARTUP) at the EXACT same memory address. Just look at the memory map and pick someplace that looks convenient.

5.Is this why the same startup.a51 is used for both app's?; So that address of C_C51STARTUP is the same in both pages?

6.How exaclty do I 'tell' the linker to place startup code at a specific mem address?

-----------------------------------------------

7.My main application will take up more than 32k code space. I am familiar with banking as I have successfully created a bank-switching app which calls routines in all 8 banks. What concerns and/or modifications should I make to allow this multi-page mapping to my main application, without disrupting the IAP architecture?

-----------------------------------------------

8.Could you provide a sample key sequence used to switch to IAP mode from main app? Im not sure that I understand your CHECKLOOP.

-----------------------------------------------

FYI: I too am using Keil.

Wow, thats alot of Q's. I have been reading up on the uPSD for well over 2 weeks now. It really helps having someone with experience who can fill in the blanks for me. Especially with IAP development which has been the hardest to find help on.

Thanks for all of your help