We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
By boot code consists of two projects. Both are written in C using small memory model. One I call fixed boot which is contained in FLASH memory. The other I call flex boot and it is downloaded from a PC to internal RAM if a software update is required. Flex boot contains FLASH erase and programming algorithms for several devices. Fixed boot calls functions in flex boot via a function table located at a fixed address. My fixed boot project reserves memory 0xC000 - 0xD7FF for flex boot. For this scheme to work correctly I beleive that I need to insure that both projects setup the following items the same way: 1. The system stack 2. The main registers 3. The users stack 4. DPP registers The first three I can handle but I am unsure how to handle the DPP registers. I posed this question to Keil support and they suggested to initialize them in the startup.a66 file. I am confused at how this would work and so far have not been successful in getting an explaination from them. The compiler uses the DPP registers to calculate addresses. If I change the contents of these registers in the startup code, won't the compiled code calculate the wrong address??? Would someone please explain this too me. Also I would appriciate any comments on things I might be missing or need to be careful of in the fixed/flex boot scheme I described. Thanks in advance, Walt
You need to beware of several things; The NEAR DATA and NEAR CONST memory classes of the projects should be at different addresses (L166 Locate settings). The linker puts near stuff in these areas starting at the bottom of the address range so if they are the same address range, the two will be in conflict. In the flex boot the const class will actually be in RAM anyways, though the project will think it's ROM. Depending on what devices you are programming, you may find that function calls during code critical periods will corrupt the programming. This problem forced me to write our boot section in assembly so I could control all calls (C166 uses functions to perform some casts and other things.) This also goes for interrupts. In the ST10F167, many things can cause a failure while the Flash is open for programming. Reading and writing some internal locations and some code locations seem to cause problems. The failure may be obvious or a weakly programmed bit which toggles when in use. I ended up using the first sector in an external flash for the boot sector (AM29F100 - 800). The boot sector initializes everything, identifies the CPU and external flash and maps the memory by sector. The external flash is mapped behind the internal flash so after the last byte of the internal flash there is a byte of external. The external then runs to the top of it's addressing, then the boot sector mirror, then all the external sectors which were 'hidden' by the internal. Since the CPU may have 128K of flash (F167) or 256k (F268) and the external can have 128k - 1M the map can be quite varied. The boot section then performs a CRC check on the program and compares the result to the CRC stored in the highest available address. If there are any failures, the server is notified of a bad program. The boot sector then waits for a hex download, erases and programs the various types of memory by address. Finally it calculates the CRC and stores it at the highest external flash address. It then performs a software reboot. If the program is good, the internal flash is mapped to the 0 segment and a software reset starts the application. The handy part about this system is the boot sector does not allow it's own sector to be reprogrammed. A bootstrap reset is required to do this. This system has been used with no failures in the field. Best luck
Thanks Jon and Scott for you replies. A special thanks to Scott for such a detailed reply. Forgive my ignorance, I am fairly new to the C167 and still on the steep part of the learning curve. This is how the compiler has configured the DPP registers for my two projects. Fixed boot: DPP0 = 0 DPP1 = 0 DPP2 = 3 DPP3 = 3 Flex boot: DPP0 = 0 DPP1 = 3 DPP2 = 3 DPP3 = 3 This is where my code is located for my two projects Fixed boot:
START STOP TYPE GRP COMB CLASS SECTION NAME 000000H 000003H --- --- --- * INTVECTOR TABLE * 000004H 000061H XDATA --- GLOB --- ?C_INITSEC 000062H 000077H CONST --- PRIV --- ?C_CLRMEMSEC 000078H 00081EH DATA 2 PUBL NCONST ?NC?UTILITY 00081FH 0008A3H DATA 2 PUBL NCONST ?NC?MAIN 0008A4H 000916H DATA 2 PUBL NCONST ?NC?APPLOAD 000918H 000957H DATA 2 PUBL NCONST ?NC??PRNFMT 000958H 000A83H CODE --- PRIV ICODE ?C_STARTUP_CODE 000A84H 0012C1H CODE 1 PUBL NCODE ?PR?UTILITY 0012C2H 001A01H CODE 1 PUBL NCODE ?PR?APPLOAD 001A02H 002027H CODE 1 PUBL NCODE ?PR?CAN1 002028H 002377H CODE 1 PUBL NCODE ?C_LIB_CODE 002378H 002597H CODE 1 PUBL NCODE ?PR?PRELOAD 002598H 00278BH CODE 1 PUBL NCODE ?PR?MAIN 00278CH 00286DH CODE 1 PUBL NCODE ?PR?FLASH 00286EH 002921H CODE 1 PUBL NCODE ?PR?ASC0 002922H 0029B3H CODE 1 PUBL NCODE ?PR?ATOL 0029B4H 002A27H CODE 1 PUBL NCODE ?PR?GETS 002A28H 002A9BH CODE 1 PUBL NCODE ?PR?ATOI 002A9CH 002ACDH CODE 1 PRIV NCODE ?PR?PUTCHAR 002ACEH 002AFBH CODE 1 PUBL NCODE ?PR?GETCHAR 002AFCH 002B21H CODE 1 PUBL NCODE ?PR?RTC 002B22H 002B3BH CODE 1 PUBL NCODE ?PR?ISSPACE 002B3CH 002B4FH CODE 1 PUBL NCODE ?PR?ISDIGIT 002B50H 002B61H CODE 1 PUBL NCODE ?PR?MEMSET 002B62H 002B6FH CODE 1 PRIV NCODE ?PR?MEMCPY 002B70H 002B7DH CODE 1 PUBL NCODE ?PR?STRLEN 002B7EH 002B89H CODE 1 PUBL NCODE ?PR?GETKEY 00C000H 00D7FFH --- --- --- * RESERVED MEMORY * 00E000H 00E7FFH DATA 3 PUBL NDATA ?C_USERSTACK 00F200H 00F237H DATA 3 PUBL NDATA0 ?ND0?MAIN 00F238H 00F239H DATA 3 PUBL NDATA0 ?ND0?PRELOAD 00F23AH 00F23DH DATA 3 PUBL NDATA0 ?ND0?UTILITY 00F23EH 00F240H DATA 3 PUBL NDATA0 ?ND0?APPLOAD 00F241H 00F241H DATA 3 PUBL NDATA0 ?ND0?GETCHAR 00FB80H 00FBFFH --- --- --- * SYSTEM STACK * 00FC00H 00FC1FH DATA --- --- *REG* ?C_MAINREGISTERS
START STOP TYPE GRP COMB CLASS SECTION NAME 00C000H 00C003H --- --- --- * INTVECTOR TABLE * 00C010H 00C033H DATA 3 PUBL NCONST ?NC?FUNCTAB 00C034H 00C157H CODE --- PRIV ICODE ?C_STARTUP_CODE 00C158H 00C3B3H CODE 1 PUBL NCODE ?PR?RAMTRON 00C3B4H 00C5E5H CODE 1 PUBL NCODE ?PR?FLASH 00C5E6H 00C6CFH CODE 1 PUBL NCODE ?PR?MAIN 00C6D0H 00C781H CODE 1 PUBL NCODE ?PR?SSC 00C782H 00C7B1H HDATA --- PUBL HCONST ?HC?FLASH 00D000H 00D001H XDATA --- GLOB --- ?C_INITSEC 00E000H 00E7FFH DATA 2 PUBL NDATA ?C_USERSTACK 00FB80H 00FBFFH --- --- --- * SYSTEM STACK * 00FC00H 00FC1FH DATA --- --- *REG* ?C_MAINREGISTERS
Walt, Your memory map looks fine. You may want to kill all optimization on the compile so the compiler doesn't make assumptions about register usage. If memory serves me, function calls weren't the only cause of failures. Some SFR accesses and stack usage may also have played a part. However, these only come into play on the ST10F167, not the ST10F168/269 or SAB167CS-32FM which have builtin algorithms which take and hold control while performing the programming. Since the ST10F167 is no longer available it is probably of no concern. Best luck
Hi Scott What do you think about the difference in DPP1 (0 in fixed boot and 3 in flex boot)? Will turning off optimization as you suggested help this problem (if it is a problem)? I understand why the compiler assigns those values but I'm not sure how I can guarentee that everything will work properly if they do not match. Do I need to set DPP to 3 whenever I enter a flex boot function and set it back to 0 before I leave it or is there a cleaner solution? Please help, -Walt
Refer to the C166 manual. The DPPs are used as follows: DPP0 - Used to access far, huge, and xhuge objects DPP1 - Used for NCONST objects. DPP2 - Used for NDATA objects. DPP3 - Used for SDATA and SYSTEM objects. This must be left at 3 so that stack and SFR accesses work. DPP1 is the only DPP that is different. It is used to point to constant items. Or, it is used to access variables declared with the const declarator. So, here's my suggestion. 1. Don't use const variables in one program or the other. 2. In the linker options, check the memory area specs and make sure that NCONST occupies the same memory space in each application. That should get things working. Jon
Jon is right, the DPP1 will make it so the flex functions won't be able to access it's NCONST members (looks like a 36 byte function lookup table and the entry vector). I assume the system works like this; Fixed boot running. Downloads and stores flex boot (hex file with addressing). Calls entry vector at 0xC000. Entry runs 'CInit' code (Setting DPPs to flex's settings.) Entry vectors to flex's main(). Main finishes flex's initialization and somehow returns (either the function table is fixed at 0xC010 or it's address is returned). Fixed does it's thing using the function table entries. A problem only occurs if flex accesses these constants. If not, just eliminate the DPP1 change in 'start167.a66'. If flex must access them, you can try one of the following (from simplest to most difficult); 1) Get rid of the nconst class in flex. Make all constants huge. Remove the nconst class from the L166-Locate tables (may require not using default settings). May not be allowed. Modify 'Start167.a66' so DPP1 is not changed. Check the map file for no nconsts. 2) Save, modify and restore the DPP0-2 registers at each flex call. Make certain there are no references to nconst or ndata outside the area. 3) Make a single function (pointed to by the 0xC000 vector which expects a command in R8 (1st argument) plus a void pointer to other, command dependent, data (R9). Put a small assembly function at _RESET in 'start167.a66' which stores and changes the state and then switches using the argument (eg. 0 = initialize, 1 = erase address...). This would probably get rid of all consts and protect you at the same time. These are the problems which caused me to decide assembly was easier to code and less apt to cause problems in the future. In assembly you just need DPP3 = 0x0003 for SFR addressing, everything else can be extended addressing. Best luck
Jon and Scott: Ah yes, I am now seeing the light. Thank you both for your help. I am going to try to eliminate the nconst class in flex-boot as Scott suggested. -Walt