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

First of all, thank you very much. I think nobody was going to answer in at least a week or more, but you have been really quick. Thank you again.

I have read yor explanation, and I am going to start modifiying the st application for the PC. I have a lot of work to do, and no much time.

The first try I made with the app for the uPsd, was to make the iap program were a simple function inside my main program. It was perfectly defined in a bank of main flash, the idea was to be able to modify the rest of the program and remain this bank with the iap function the same. To access to the iap I had a menu too, and when you finished the programming, you must restart the machine. But this didn´t work, the software in the pc didn´t work properly and I thounght it was because I had made something wrong in the program for uPsd, so I started with your advices in the forum. I think I will go on with the one having the iap in the boot, and all stuff you wrote here. I will tried to make a pc application to work ok, and thank you again, sometimes you feel really alone in front of some problems.

Happy new year!

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

Icebell,

I think the problem you're running into is that you have to think carefully about the ''rules'' for how your program will start up normally, and how it will get into IAP mode for reprogramming. The general method is this: Have some way of knowing that your ''main application'' is programmed correctly (like some status bits). When you start up, check these bits. If they indicate that the application is there, just jump to that section of the program. If not, stay in the IAP code and wait to be programmed.

Also, somewhere within the normal application, you need to have some way to be put into IAP mode. What I do is accept a serial command. When I receive that, I write a long string into SRAM and then perform a watchdog reset. This string then becomes ANOTHER item that the startup code looks for to decide what to do. So, in pseudo-code, the startup routing looks like this:

if ( (application_present) && !(IAP_string_present) ) {

run_application();

} else {

run_IAP();

}

Hope that helps.

-Phaze426

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

Sorry, but I think maybe is not a good idea to put these questions here, I think I need help in a more general way, so I am going to try to solve some questions first in the forum, and then come back here to go on with the IAP. Anywhere, thank you very much for your help.

Icebell

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

Hello again and thank you very much for your help, you are my only hope to solve this stuff, and you are solving my questions really quick.

My problem now is that I have realised that I have huge holes of understanding about uPSD and it is not posible for me to work in such a level as you explain me things. I would like to mend this and try to understand everything I’m doing because I realised too there is not an immediate and magic solution for the IAP question.

Sorry if it is not the right place to talk about this, or if my questions and too simple for you, I don’t know another place to tell this, but if you let me know, I will be really happy to go there and let you with your things.

First of all I haven´t still completely undestood the memory of the uPSD and how to design a map, and what means code or data, and all the stuff about it.

Phisically, the uPSD (3254 is the one I use) has two blocks of flash memory, one of 256Kbytes (main) and another one of 32kbytes(boot or secondary, I understand is the same to say boot or to say secondary, am I right?). It has too a block of RAM memory of 32kbytes (I am not talking about SFR, but I don´t forget it). From now, when I say ‘block of memory’ I mean a phisical part of the memory.

Each of these memories can be treated like data or code, I am not very sure if RAM memory can be used as code. The difference between these two ways to treat the memory blocks is that the parts defined as code wil be the parts executed, the data just will be data.

We can address 64Kbytes of memory, but with the banking we can make it much bigger.

A memory block can be defined as code at the beginning and later make it to be data, and data can become code too.

A memory block can be defined in several places, it means that accesing to some of these addresses will reach to the same phisical part of the memory, we can define it too, in an address like code code but in the other one we can define it like data.

In every moment two blocks of memory cannot be defined with the same address (and the same bank, when I talk about address I suposse the bank is a part of it) and the same behaviour, I mean, both data or both code, am I right?

This is just the beginning, but having a really clear idea about this, will make me to understand better all the following stuff.

Thank you very much for your time and your attention

Icebell

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

Icebell,

I don't think you need to feel that worried about posting your questions about memory mapping and memory segments here. When you have a truly clear understanding of these concepts, IAP becomes much simpler, so this message is as good a place as any to discuss them. I don't have much time, but I'll try to get started with a description of how memory mapping for 8051 devices in general and the uPSD32XX in particular works. If I have to continue it later, I'll do so. :)

There are two basic categories of memory systems in microprocessors and microcontrollers. The first is called ''Von Neumann'' architecture. In this model, there is no distinction within the processor between ''data memory'' and ''code memory.'' There might be different kinds of physical memory connected, but as far as the processor is concerned, it's up to you to decide where the data is, and where the opcodes are. The second type (and the type used in the 8051) is called a ''Harvard'' architecture. In this type of processor, a distinction is made between data memory and code/program memory. The processor even has different physical lines that access these. On the 8051, the RD/WR signals are used to access the external ''data'' memory, while the PSEN (Program-Storage ENable) line is used to access the ''code / program'' memory. Note an important distinction here - there are TWO control lines for data memory, but only ONE for program memory. This is because, when the 8051 was first conceived, there was no way to WRITE to program memory. The PSEN line then, is what the processor uses when it needs to read the next instruction.

As you mentioned, we have 64kB of address space. This is because the 8051 has 16 address lines for a total of 65536 possible address locations. But since there are SEPARATE control lines for both program and data memory, we find that we can have 64kB of code memory AND 64kB of data memory connected to the same processor.

As technology progressed, we eventually got to a state where we have the ability to WRITE to the memories that contained the program code. Unfortunately, the 8051 didn't provide any instructions for writing to program memory (because it didn't even have a WR control line for it). The only way to make this happen was to use some external logic circuitry to temporarily connect the RD/WR lines to the memory and then use data memory instructions to operate on them. The problem, of course, it that the processor STILL needs to be able to fetch program code while this is happening, so PSEN would have to temporarily be routed to ANOTHER chip that held the program used to reprogram the main code.

What we have in the uPSD is the culmination of all these items rolled right into the chip. The smaller ''boot flash'' is intended to store the IAP code. This is where the processor will get its instructions when it's reprogramming the ''main'' program. As the name implies, the larger ''main'' flash is intended to hold the main program. Finally, the RAM is intended to be used as data memory. The one confusing point is that if you REALLY WANT TO, you could just as easily use the logic circuit to route the PSEN line to the RAM and run from there. The processor doesn't know any different. As long as it gets instructions to execute when it strobes the PSEN line, the type of memory connected makes no difference.

The VM register within the uPSD is what allows us to control ''on-the-fly'' where the control signals are routed. We are basically telling it ''ok, now route the PSEN line to the ''boot'' flash instead of the main flash'' and then ''route the RD/WR lines to the main flash.'' We do this because then we CAN use the processor to execute write commands on the flash and reprogram it.

I have to stop at the moment, but I'll come back and talk a bit about memory-mapping as far as address locations and chip-selects. For now, just see if you can digest what I've said. If anything is unclear, post questions back here and I'll see if I can clear them up.

Best Regards,

Phaze426

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

Thanks, thanks and thanks!

I have been working with the uPSD3254 for two years, yes, in spite of my big ignorance, sometimes it is not difficult to make things work , and writting code is not a complicated task, in fact my application is almost finished, the only thing I need is the iap. For this two years I have dreamt every night about somebody to tell me the words you have, thank you!!!!

Sorry if I am being a bit exaggerated, but I am thrilled because of that clear and valuable information.

I have understood everything perfectly, it is not difficult in the way you express it, I am reading more and have more doubts, but many of them have disappeared with your explanations.

I will try to write them soon, I will wait to your next message, because I am sure, you will solve most of them.

Thank you very much

Icebell

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

An urgent question. I am trying to understand everything but I cannot see what R0 throgh R7 registers are, and where they are, and if they are part of every page/bank or if they are in the internal RAM. This registers are mentioned in a lot of places and I have to suppose, to imagine, but I am not sure of anything.

Thank you again for your time and for your words.

Icebell

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

Icebell,

The R0-R7 registers are the 8051's ''general purpose'' registers. These are located within internal ram. In fact, there are multiple ''banks'' of these R0-R7 registers that can be switched between. If you're writing code in C, just know that these are the registers that are used for function parameter passing and all the nitty-gritty operations that are being generated from your C++ code. If you're worried about paging, they cannot accidentally be ''paged out.''

-Phaze426

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

Icebell,

I'll take a few more minutes and continue with my run-down now. :)

From the last message, you now know that memory on the 8051 is organized into program/code (which has only a READ control line), and data memory (which has both read and write control lines). You know that its 16-bit address bus lets you access up to 64kB of each. You also know that the logic circuits included in the uPSD allow us to ''re-route'' the PSEN/RD/WR signals to WHEREVER we want via the VM register.

Now would be a good time to ask how to get at the rest of the uPSD's flash memory. The uPSD3254 that you're using for example, has 288kB of Flash in addition to its 32kB of SRAM. How could we address the rest of this memory if our address bus can only handle 64kB? Well, imagine that we wanted to add an extra bit to the address bus, so that it was a 17-bit address and could handle 128kB of memory. All we would have to do was find an empty port pin on the chip and just use that! If we called that logic signal something like ''extrabit,'' then in logic gates on the board, we could have one 64kB flash chips select be: (PSEN && !extrabit) and another 64kB chips be (PSEN && extrabit). This way, when ''extrabit'' is high, one chip would be accessed via PSEN, and when ''extrabit'' was low, the other chip would be accessed by PSEN. Thus, we've effectively doubled our memory capacity. BUT THIS COMES AT A HIGH COST! The 8051 internally still only thinks that it can access 64kB, so there's no way to have it ''automatically'' handle that extra bit of address space for us. We have to use instructions to make sure we've chosen the proper chip before trying to call a function or it will run the wrong code. What's worse, we have to think about what happens during interrupts. If an interrupt occurs, the processor doesn't know how to set ''extrabit'' to the correct value so it can jump to our interrupt code. It could again begin executing the wrong code.

So, how do we solve this? There are two ways to handle the problem with interrupts. The first would be to make sure that ALL of our interrupt routines are programmed at the same addresses in BOTH of our flash chips. That way, no matter WHAT extrabit is set to, the processor will find and execute the right code. This is easy, but a bit wasteful since we're programming the same thing in multiple places.

Another method would be to try to use ''extrabit'' in such a way that certain addresses in code memory (like where the interrupt routines are) were ALWAYS accessing the same chip, and only OTHER addresses changed based on its value. This is the notion of a ''common'' page. Imagine this example: Instead of have TWO 64kB flash chips connected to our system, we have THREE 32kB flash chips. We could wire up the 8051's bus like this:

Flash1's Enable = (PSEN && !A15)

Flash2's Enable = (PSEN && A15 && !extrabit)

Flash3's Enable = (PSEN && A15 && extrabit)

So, think about that scenario for a second. If A15 is ''off,'' then the address being read is in the lower 32kB. This will leave Flash1 selected. If A15 is ''on,'' then it's in the upper 32kB and EITHER Flash2 or Flash3 will be selected based on the value of ''extrabit.'' So.. this layout would give us 2 ''pages'' of memory with the lower 32kB ''common'' to both pages and a total of 96kB of Flash. Not as much flash as the first method, but now we don't have to duplicate our code for interrupt routines.

Hopefully I've explained all that clearly enough that I can extend it now. Imagine that just one extra ''bit'' of address space wasn't enough for your application, but you needed two or maybe three more to address all your memory. You can see that with the method above, it's just a matter of using some more logic on the chip select for each one to decide which one is picked based on the address bus and the value of your extra bits. ST has provided all of this for us! The extra ''bits'' of address bus they give us are called the ''page'' register and all they are there to do is help us select which section of flash to access at any moment. What's even better, they've given us an AMAZINGLY COMPLETE array of logic inside the chip. This is their ''address decoder PLD.'' It is what let's you say ''map main flash from this address to this address'' etc. To clarify, if I were to translate the above memory map into what the PSDSoft program expects, it would look like this:

FS0: 0x0000-0x7FFF, PAGE==0 | PAGE==1

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

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

I would then setup PSDSoft to program all my interrupt code into FS0 and my main application code into FS1 and FS2.

The nice thing about working in a C compiler is that the compiler vendor knows this is something you're going to need, so although the ''chip'' can't automatically handle the page register, the compiler can usually generate code automatically. If you enable ''banking / paging'' support, then when you make a function call like do_something(), it will first jump to a routine that figures out which ''page'' do_something() is in and set the page register to the right value.

I'll stop there for now. The next email in my long-winded series will try to explain how all of this relates to IAP and how to get that accomplished. Again, try to digest all this and tell me what doesn't make sense.

Best Regards,

Phaze426

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

I am learning a lot of things with your lessons, thank you, I have finally understood what the common code is, and I have found out that when you compile your code, every of the myprogram.h00, …, myprogram.h007 are 64kbytes of code, and it depens on the memory map, that if you put them in one bank that is defined from 0x8000 to 0xFFFF, then it will work the especific bank code, but if you put any of these files in a bank that is defined in 0x000 to 0x7FFF, it will work the common part, is that right? Sorry if I am not explaining very well, I am bit busy and writing good english takes time to me.

I had my project like, common part in secondary flash and the main flash for the 8 banks, now I suppose I have to make one of that banks for common and free the secondary memory for the iap. I am going to do it now, but if it is not right, please, let me know.

Thank you again, you are being a real help.

Icebell