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

Hello,

I can start the program and it goes to iap or main depending the key_string value!!!!!!! I know I still have a long way to walk but things seem to be working.

Thank you, your help is being fundamental in my success. Thanks specially to phaze426 and mulls14, thank you very much.

icebell

P.S. I am delighted and there is nobody in the office to share the good news.

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

Don´t worry about ''him'' or ''her'', I really don´t mind, it is just I don´t like people believing things that are not true

With your last messagge I have confirmed a lot of ideas I was not sure about, it is dangerous working so insecure, when something does not work everything seems to be the reason.

I have finally understood why in the memory map FS0 must be like this:

FS0: 0x0000-0x7FFF || (0x8000-0xFFFF && PAGE==7)

I just made it but I didn´t know why.

Now I am trying to erase and blanck check, and every option the example software have. Of course, what I want is reprogram but I need to go step by step. In the way my program is I could just reprogram the main app, but I hope to be able to reprogram everything in the uPSD.

I have a question about that functions, erase, read, etc, I have seen in the datasheet, there are some instrunctions the program use to make these operations. Exactly in the datasheet, page 102, you can see these intructions. I dont understand what SA or PA or PD, I mean all of these addresses how are they? The other ones are in hexadecimal code and are big enough to be anywhere in the memory map but this ones seems to be just one byte in the program and I dont understand very well.

I will try to understand till some one mekes me see the true.

Thank you very much.

Icebell

[ This message was edited by: icebell on 23-01-2007 10:10 ]

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

Icebell,

My sincerest apologies for the ''him'' assumption. It's often a safe one when discussing electrical engineering, though clearly not always! Also, I'm glad to hear that you're having some success. I know it can be neat when you finally have that ''eureka'' moment with something as complicated as IAP. Anyhow... I'm sorry it's taken so long, but let me try to get some more of my discussion out there (I really should write a whitepaper on doing this or something).

From the previous posts, I've mentioned how the 8051 has two controls lines to access up to 64kB of external data memory (RD/WR) and one control line to access up to 64kB of external program memory (PSEN). I've also talked about how the VM register in the uPSD can be used to re-route some or all of these three control lines to any portion of memory (RAM, Main Flash, Boot Flash) we like.

We've also talked about what would be required to extend the address bus of the 8051 to allow for more than 64kB of data or program memory. We've then gone on to talk about how the uPSD provides all of this internally via its decode PLD and the PAGE register.

Now let's talk about what needs to happen for IAP to take place. Recall throughout this whole topic that the ONLY thing the 8051 EVER DOES with the PSEN line is strobe it to fetch opcodes to decode and execute. It doesn't know anything about what kind of memory is attached to the bus at that moment and our job is to make sure that it always fetches the next instruction correctly, even if we're messing around with the VM / PAGE registers, etc.

For a first step in IAP, let's decide on a memory map. Your application is pretty large and pretty complicated, but let's try to boil it down to the key requirements:

1. We NEED all 256kB of main flash to store our main program

2. We NEED a common area for ISRs

3. We NEED the main application to be IAP

4. We NEED the IAP code itself to be updatable (I would debate this, but for now I'll assume you're right)

How do we get a memory map that accomplishes this? First, lets start with point 1 and 2. If we decide that FS0 will be our ''common'' area for the main program, we could decide to map it in the lower 32kB of code memory and the other flash segments in the upper 32kB. What that means, for instance, is that page 0 would have FS0 in the lower 32kB and FS1 in the upper. Page 1 would have FS0 in the lower 32kB and FS2 in the upper, etc. Our initial memory map would look like this, then:

FS0: 0x0000-0x7FFF

FS1: 0x8000-0xFFFF && PAGE==0

FS2: 0x8000-0xFFFF && PAGE==1

FS3: 0x8000-0xFFFF && PAGE==2

.

.

FS7: 0x8000-0xFFFF && PAGE==6

So, at this point we could configure our compiler with these settings for banking and we would be able to use all 256kB of main flash for our application. We've also defined a common area so we won't get a crash when ISRs execute. So far, so good. Now let's move on to point 3. How do we do IAP on the main flash?

The trick here is that WE CANNOT EXECUTE FROM THE SAME AREA OF FLASH WE'RE PROGRAMMING. This is because the first step in programming the flash is to ERASE it. If we were executing code in FS0, then attempted to erase FS0 for programming, the system would crash. This leads us to the conclusion that we need to be executing out of SECONDARY flash while we program main flash (it should be a hint that it's called ''boot'' flash - short for bootloader/IAP).

So, now we have to figure out how to set up the memory map for boot flash so that we can execute from there and still have access somewhere in memory to the main flash. This is a bit complicated. The thing that makes this easiest is the table (I think it's on page 110 in the datasheet) that shows us that there is a ''priority'' scheme for the different areas of memory. For instance, if we had the VM register configured to allow PSEN to access BOTH main and boot flash AND we had both of those bits of memory mapped to a single address, the access would happen to the memory with higher priority: the boot flash. This lets us design a map for the boot flash that overlays the main flash without causing any problems. As long as the VM register indicates NOT to access secondary flash with PSEN, it sits there waiting. When we set the VM register to allow access, it overrides and blocks that section of main flash. So, to start, let's just imagine that we overlay the lower 32kB of code space with the boot flash like this:

CSBOOT0: 0x0000-0x1FFF

CSBOOT1: 0x2000-0x3FFF

CSBOOT2: 0x4000-0x5FFF

CSBOOT3: 0x6000-0x7FFF

Now let's think about how our memory map works in total. If we have the VM register set to allow PSEN to access only MAIN flash, then things are as we described before. If we now set it to access BOOT flash, we have CSBOOT0-3 in the lower 32kB and FS1-FS7 in the upper 32kB in each of the pages. This is great! We can now be running out of the lower 32kB in boot flash and erase/reprogram the other main flash banks FS1-FS7. The only thing missing . . . is FS0. Since we've overlayed the lower 32kB where FS0 was, we now don't have any way to access it when we're reprogramming. To solve that, we can just add another page that maps FS0 into the upper 32kB. FS0's select equation now looks like this:

FS0: 0x0000-0x7FFF || (0x8000-0xFFFF && PAGE==7)

So, now we've got a memory map that lets us re-program all of the main flash via a program that's in the boot flash. We still have a bit more work to do on this memory map to get to a point where we can reprogram the boot flash, however.

I'm going to stop here again for now. See if all of this makes sense and I'll try to pick up again before too long.

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

icebell,

I figured out IAP by tinkering with ST's examples. I'm sending you versions of the ST examples that I used to test with. (You've got mail!) They've got pretty good comments so they should be easy to understand. You're on the right path though, keep reviewing code examples, and refer to the manual when you have questions. Good Luck!

Oh yeah, all of these IAP examples are for reprogramming the main program only. You can always use JTAG to reprogram the entire chip, both primary and secondary flash, but IAP is commonly used to reprogram the main program when JTAG is not available. Like when you need to make field-updatees. For instance, my device is programmed via JTAG here in our production department and then shipped to a customer. If the customer needs changes to the program I just email them a new program. My PC program loads the new .obj file (PSDExpress output file), and sends the contents of the .obj file (packet by packet) to the IAP program running on the uPSD, which in turn reprograms main flash. You may not need to perform a blank check, like the JTAG interface does. My proceedure is as follows (PC program interfacing with IAP program): PC sends a command to invalidate the main program (special code stored in RAM). Now even though no changes have been made, any errors or interruption in the reprogramming sequence will not matter because the special code in RAM indicates that the main program is invalid. Next the PC sends commands to erase all main program sectors (simple enough). Then the PC starts sending packets of code from the .obj file, including the start address of where to put the code. The PC program also sends page change commands so that we can program each page of memory, one at a time. Next for good measure the PC program requests memory packets from the IAP program in the same fashion that it sent packets. This is for verification purposes, I want to make sure that the new program in main memory matches the program in the .obj file. Finally, when the program is fully loaded and verified, the PC sends a command to validate the new program we just loaded, and for convenience sends a command to reboot the device so that it immediately restarts into the new main program. This architecture comes from both ST examples and from discussions here in the forum, and has worked flawlessly for me so far.

[ This message was edited by: mulls14 on 23-01-2007 16:02 ]

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

Icebell,

I understand why it's confusing. I personally think that ST could have written that section of the datasheet better, or at least given a better ''key'' to figure out what those abbreviations mean. What I usually understand them to stand for is:

PA = Program Address (This is the actual address in the flash that you're trying to program)

PD = Program Data (This is the actual data that you're trying to write to the flash)

SA = Segment Address (This represents ANY ADDRESS within the segment you're trying to work on. For instance, during the erase flash segment command, if you had FS3 mapped into the upper 32kB and you substituted 0x8000 for SA, it would erase FS3).

As mulls suggested, you can generally use STs example code and understand what the datasheet means by what the code is doing (though it should really be the other way around).

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

Yes mulls14, your examples have helped me a lot, thanks to them I could make my program jump form main app to iap, they were really usefull but all stuff about talking to the flash memory, to erase, to read, everything about that, doesn’t appear in the code you sent me.

The problem I have now is I cannot make the program option works. I am with the st winapp example, I am read everything and I cannot find why the “Error writing data. Probably the target sector was not blank.'' appears all the time.

I have made a copy of my main.h00, main.h01, …, main.h07 and change them for main0.hex, main1.hex, …, main7.hex. I have seen in the winapp it checks if the file to program is *.bin or *.hex, but anything else.

I know there is bugs in the code, but I can finde them, can you please help me with this?

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

Icebell,

Before I continue with my IAP stuff, let me just make a recommendation to you: Don't try to start out with a fully capable bit of IAP for your first tests. That is, don't try using STs windows application and IAP code to actually write down your whole program. Instead, do something like this: Set your serial port up to listen for a code like ''IAP'' and then when it receives it, erase the flash and program what you send over the serial port into memory. Then, you can read out the flash contents with the JTAG programmer and see if your data is getting programmed correctly. That way you can narrow down the possible places things are getting screwed up. This will show you if your flash doesn't get erased properly, etc.

-Phaze426

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

Icebell,

Continuing along with IAP: Up to this point, we've got this much specified for our memory map:

CSBOOT0: (0x0000-0x1FFF)

CSBOOT1: (0x2000-0x3FFF)

CSBOOT2: (0x4000-0x5FFF)

CSBOOT3: (0x6000-0x7FFF)

FS0: (0x0000 - 0x7FFF) || (0x8000 - 0xFFFF && PAGE==7)

FS1: (0x8000 - 0xFFFF) && (PAGE==0)

FS2: (0x8000 - 0xFFFF) && (PAGE==0)

.

.

FS7: (0x8000 - 0xFFFF) && (PAGE==6)

With this, we can use the VM register to run from boot flash (in the lower 32kB) and program each of the other flash banks (when they're mapped into the upper 32kB). One question you might have is why do we need to map the flash sectors into the upper 32kB for programming? It has to do with that priority scheme I talked about in the last message. The memory area with the highest priority is the RAM, so we need to make sure that when we're accessing the flash with the RD/WR lines, it doesn't overlap with the RAM. Otherwise, our writes/reads will go there instead of the flash and the flash won't get programmed. So, we can add this to our chip-select:

RS0: 0x0000-0x7EFF

CSIOP: 0x7F00 - 0x7FFF

Notice that to be able to perform IAP like this, we're sacrificing a small chunk of the XDATA memory by overlaying the CSIOP on top of it. This is the only way we can leave the entire upper 32kB of space clear.

Now we're to the point in this whole memory-mapping study that we need to figure out how we're going to reprogram the boot flash (I would again point out that this can often be avoided altogether by just writing simple, solid bootloader code at the outset). We need to find a way to map the boot code into the upper 32kB. At the same time, we need to execute from SOMEWHERE and map that into the lower 32kB. Let's assume that we're going to put the code for reprogramming the bootloader into FS0. This makes sense since it's going be mapped into the lower 32kB on any page anyway. We could then just change the selects for our boot flash like so:

CSBOOT0: (0x0000-0x1FFF) || (0x8000-0x9FFF && PAGE==8)

CSBOOT1: (0x2000-0x3FFF) || (0xA000-0xBFFF && PAGE==8)

CSBOOT2: (0x4000-0x5FFF) || (0xC000-0xDFFF && PAGE==8)

CSBOOT3: (0x6000-0x7FFF) || (0xE000-0xFFFF && PAGE==8)

Now, we FINALLY have a memory map that can do everything you need. Here are the three general ''states'' that your device could be in at any given time:

''Normal Operation''

VM: Set to route RD/WR to RAM, PSEN to MAIN FLASH

PAGE: 0-6

''Reprogramming Main FLash''

VM: Set to route RD/WR to RAM AND MAIN FLASH, PSEN to BOOT FLASH

PAGE: 0-7 (where page 0 is for programming FS1, 1 for FS2, . . . 7 for FS0)

''Reprogramming Boot Flash''

VM: Set to route RD/WR to RAM AND BOOT FLASH, PSEN TO MAIN FLASH

PAGE: 8

Remember to load the code for reprogramming the boot flash into FS0 since that's what we'll be executing from on page 8.

That about sums up all the necessary things to be done with memory mapping to get IAP to happen. Jumping from one state to the other can be tricky, but here's what I generally do:

I setup the uPSD to boot from the boot flash. Within the boot flash, I have a bit of code that:

1. Checks to see if there is a valid application programmed into main flash.

2. Checks to see if there's a code in RAM telling me to get ready to reprogram the main flash.

If the code is not there, and there's a valid application, then I switch the VM register to run from main flash and continue. Otherwise, I just stay in the boot flash and wait to receive a program. The tricky part is this: When you toggle the VM register, the processor will isntantly begin fetching instructions from the new memory location. If the code that's there doesn't line up EXACTLY RIGHT, your program will crash in some unpredictable way that will change with every compile. What you need to do then, is define a FIXED LOCATION for the startup code and LOCATE THE EXACT SAME CODE TO THE EXACT SAME SPOT IN FS0 AND CSBOOT. That way, it will look to the processor like nothing changed.

You will have some additional considerations to make, however, since you want to be able to reprogram the boot flash. What if you need to change the startup code, for instance? If you reprogram the main flash with something DIFFERENT than what's in your boot code, then this switchover won't happen quite right. My personal recommendation would then be to create a page switching function that you WILL NEVER CHANGE OR MOVE and put it also at a fixed location in both CSBOOT and FS0. That way, it will always be there to handle switching back and forth.

I think I'll stop with my explanation here and just go back to answering questions if things are still unclear. I suspect that you'll just need to spend some time playing with these things until you get it. Good luck!

-Phaze426

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

Phaze makes a good suggestion. It seems like you're trying to design the entire product in one shot. You really need to slow down and work on one portion at a time so that you can debug it, and learn from your mistakes. I realize that you're in a hurry to finish but it will take you longer to complete your product if you don't understand each portion of the chip and IAP implementation along the way. As a reference, I spent many months testing with example programs before I started formalizing the program and chip architecture.

Also, It seems from your messages that you're using the ST examples, and my examples, as 'working' code. None of the examples should be used as-is in your project. The ST Windows app just provides example commands for you to structure your own Win app. You must build YOUR OWN Windows IAP program to interact with your YOUR OWN uPSD IAP program. The two programs must be customized for your project needs.

You may find it easier to use the main.obj file created from PSDExpress instead of the main.h00..07 files created by your compiler. File types: *.hex, *.h00, and *.obj are intel hex files which can be opened with notepad. You will find it very valuable to research intel hex files so that you (and your windows program) can read and understand them. The *.hex files contain one bank of code each while the *.obj file contains all banks - PSDExpress merges all the *.h00 files into one *.obj file.

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

Thank you both for your advices, yes, I am in a hurry and sometimes I try to bite off more than I can chew.

I am going to read carefully your long messagge phaze, as I always do, and follow all your both recommendations. I will tell you about my doubts and problems soon and about my success too, I hope to finish the iap stuff in the future (not so far future, I hope).

Best regards

Icebell