This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Boot code question

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

Parents
  • 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

Reply
  • 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

Children
  • 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

    Flex boot:
    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

    As you can see, fixed boot reserves memory from 0xC000-0xD7FF. Flexed boot is entirely located in this space (except for stack and registers). I believe that means that fixed boot and flex boot do not share the same memory areas so the answer to Jon's question...

    The problem that comes up is what happens if DPP1 of flex-boot is different than DPP1 in fixed-boot. Or, more succintly, will fixed-boot and flex-boot share the same memory areas for NCODE and NDATA?

    If the answer is YES, you can configure BOTH programs with the same memory areas and simply RESERVE the areas in flex-boot that are used by fixed-boot.

    If the answer is NO, you may need to have an interface routine between fixed-boot and flex-boot that changes and restores the DPP registers.


    ...is NO. Is that correct? I would like to avoid manipulating the DPP registers. Any ideas on how I can locate things so that the compiler will assign the DPP registers identically for both project?

    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.

    I am assuming that since I am using two different projects, each containing its own library functions etc. that this should not effect me. Flex-boot will erase and program FLASH while running from RAM. If it makes any function calls they also will be called from RAM. Is that assumption correct or am I missing something.

    Thanks again for your time and help, any comments are much appreciated

    -Walt

  • 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