This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UCD3138A: load.asm

Part Number: UCD3138A

Dear TI,

I'm studying the deomo code of  UCD3138A.  I'm confused with  the load.asm file.The assembly instructions as follows:

LDR r0, c_cinit
MOV r7, #1
CMN r0, r7
BEQ _c1_

This means initialize variables, copy the variables in Pflash to RAM to run?  which section in Pflash to copy?

Can you provide some documentation about the startup programs  of UCD3138A?

Best Wishes

LEI

  • The cinit table is generated by the C compiler for auto initialized variables. The format for the table should be described in the comments for load.asm.

    An auto-initialized variable is a static variable with its value defined in the declaration, like this:

    int32 grumble_index = 43;

    If you look at the map file for a project with autoinitialized variables, you should see a cinit area.
  • Dear Mr. Ian Bower;

    Thanks a lot for you reply. I have 3 more question to consult.

    Q1: 

      In load.asm,  the follow assembly statement  means compare  c_cinit  to -1 and perform main code if equal?  Why compare with -1?  Execute initialize variables if not equal ?

    LDR r0, c_cinit
     MOV r7, #1
     CMN r0, r7
     BEQ _c1_

     

    Q2 : I look at  the map file, as the follow map file show the .cinit section and .bss section.

       .cinit     0    000065d0    0000004c    
                      000065d0    00000018     UART_Auto_Baud.obj (.cinit)
                      000065e8    00000018     fault_handler.obj (.cinit)
                      00006600    00000018     standard_interrupt.obj (.cinit)
                      00006618    00000004     --HOLE-- [fill = 0]

     .bss       0    0001901c    000006cc     UNINITIALIZED
                      0001901c    0000020b     main.obj (.bss)
                      00019227    00000001     uart.obj (.bss)
                      00019228    00000100     main.obj (.bss:_xn_bins)
                      00019328    00000080     main.obj (.bss:_program_area)
                      000193a8    00000058     main.obj (.bss:_pmbus_dcdc_config)
                      00019400    00000058     main.obj (.bss:_pmbus_dcdc_config_translated)
                      00019458    0000004c     main.obj (.bss:_filter0_cp_pmbus_regs)
                      000194a4    0000004c     main.obj (.bss:_filter0_pmbus_regs)
                      000194f0    0000004c     main.obj (.bss:_filter0_start_up_pmbus_regs)
                      0001953c    0000004c     main.obj (.bss:_filter1_pmbus_regs)
                      00019588    00000034     main.obj (.bss:_adc_values)
                      000195bc    00000034     main.obj (.bss:_adc_values_avg)
                      000195f0    00000034     main.obj (.bss:_fiq_data)
                      00019624    00000034     main.obj (.bss:_pmbus_buffer)
                      00019658    00000030     main.obj (.bss:_pmbus_dcdc_config_nonpaged)
                      00019688    00000030     main.obj (.bss:_pmbus_dcdc_config_nonpaged_translated)
                      000196b8    00000020     UART_Auto_Baud.obj (.bss)
                      000196d8    00000008     fault_handler.obj (.bss)
                      000196e0    00000008     standard_interrupt.obj (.bss)

     The format of Initialization records in .cinit section :  size in bytes,  pointer to  .bss area , Initialization date.  Map file just give the .obj files.

    So how can I get the detail information in .cinit  like pointer which area in .bss ?  and what is the initialization date?  the size of the date? 

     

    Q3: Why the stacks have different addresses in load.asm and map file? (FIQ_STACK_TOP .equ 0x19e00)   ( 00019f94  _StackFIQ_ )

    In load.asm

    SUP_STACK_TOP   .equ 0x19ffc ;Supervisor mode (SWI stack) starts at top of memory
    FIQ_STACK_TOP .equ 0x19e00 ;allocate 256 bytes to supervisor stack, then do FIQ stack
    IRQ_STACK_TOP .equ 0x19d00 ;allocate 256 bytes to fiq stack, then start irq stack
    USER_STACK_TOP .equ 0x19b00 ;

    In map file

    00019fec  _StackABORT_                           
    00019f94  _StackFIQ_                             
    00019fe8  _StackIRQ_                             
    00019ffc  _StackSUPER_                           
    00019ff0  _StackUND_                             
    00019f24  _StackUSER_ 

     

    Best Wishes

    LEI

     

     

     

  • Your first question should be answered in the comments in load.asm.

    ;*------------------------------------------------------

    ;* PERFORM AUTO-INITIALIZATION. IF CINIT IS -1, THEN

    ;* THERE IS NONE.

    ;*------------------------------------------------------

    So if there is no CINIT table, then the c compiler will set the value of the _cinit to -1.

    The size and location of cinit is given in the .map file:

                       location        size

    .cinit     0    000065d0    0000004c    
                      000065d0    00000018     UART_Auto_Baud.obj (.cinit)
                      000065e8    00000018     fault_handler.obj (.cinit)
                      00006600    00000018     standard_interrupt.obj (.cinit)
                      00006618    00000004     --HOLE-- [fill = 0]

    To see the actual data in the file, I would suggest looking at the .xo file.  The .x0 file is a pretty straightforward object file format.  There is a Wikipedia page on it, if you need help with that. 

    I've never needed to look at the .cinit file.  I've never heard of any issues with it. 

    The stack locations are totally defined by the load.asm file.  The values in the .cmd file are ignored.  The one important thing in the .cmd file is to end the RAM section at an address below the lowest address you expect the stack to go to.  That way the linker will give you a warning if your variables expand into the space used for the stack.  Otherwise, you don't have to work about the stack values in the .cmd file. 

  • Dear Mr. Ian Bower;

    Many thanks for your kind and clear reply.  I read the CMD file today ,and still wondering about the following two points.

    Q1:the section in cmd file shows:

    .text : {} > (PFLASH align(16))
    .const : {} > (PFLASH align(16)) 
    .cinit : {} > (PFLASH align(16))

    .CONFIG : {} > (DFLASH align(32))
    .CONFIG_B : {} > (DFLASH align(32))
    .PASSW : {} > (DFLASH align(32))

    The .test  section is aligned on a 16-byte boundary within the PFLASH range.  Why  .test  section shoud aligned on a 16-byte boundary , not 32-byte boundary or else?

    The .CONFIG  section is aligned on a 32-byte boundary within the DFLASH range. Why  .CONFIG  section shoud aligned on a 32-byte boundary ? 

    Q2:  About  UNIOIN Statement in cmd file:

    UNION : run = RAM_FOR_PROGRAM_AREA

    {

    .ram_for_program_area
    .zero_out_integrity_word : load = PFLASH,start(_zero_out_integrity_word_start) {zero_out_integrity_word.obj }
    }

     Unioning sections causes the linker to allocate them to the same run address.

    Sections from .zero_out_integrity_word and .ram_for_program_area  are allocated at the same address in  RAM_FOR_PROGRAM_AREA(0x00019000).

    I don‘t under the section of .ram_for_program_area come from?   In the map I find .ram_for_program_area  located  at 0x00019000 same with the run address.

    Just load the .zero_out_integrity_word to RAM_FOR_PROGRAM_AREA(0x00019000),  Why use union statement? 

    #pragma DATA_SECTION(program_area, ".ram_for_program_area")

    Uint32 program_area[32];

    Best Wishes

    LEI



  • I don't know why the first three are aligned on 16 byte boundaries.  I think we just leave it that way out of fear that if we change it, it may break. 

    Perhaps someone can add information for me on that one.

    The CONFIG constants are aligned that way because the DFLASH has 32 byte pages, and we want the CONFIG to start on a new page, so we can erase pages and only erase the CONFIG structure, nothing else.

    The union is used so that we only have one RAM area, and we write each program to it only when we need it.  We don't want to tie up more RAM than necessary.

    The union is set up so that all the programs executed in RAM are compiled as if they are executing from the RAM address, but are stored in program flash.

    That's what the union is designed for. 

    The programs that get copied into RAM all involve things that can't be done in program flash, like erasing or writing to program flash.  While the erase or write is going on, the program flash will return FFs, so it can't be executed from during that time.  So the program to do it has to be executing somewhere else. 

  • Dear Mr. Ian Bower;

    Thank you very much for your kind and clear reply.  I am clearly about that now.

    Today I have one more question:  In load.asm file

    LDR r13, c_sup_stack_top ; initialize supervisor stack pointer
    LDR r4,c_mfbalr1_half0 ;point r4 at program flash base address register
    MOV r0,#0x62 ;make block size 32K, address 0, read only
    STRH r0,[r4]; store it there
    LDR r0,c_mfbalr2_half0_load ;set up data flash for write only
    STRH r0,[r4,#8] ;put it into mfbalr2

    c_mfbalr1_half0 .long 0xFFFFFE0E ;low 16 bits of memory fine bank address low
    c_mfbalr2_half0_load .long 0x8822 ;data flash base address 8800, block size 2K, read only

    These assemblers mean write 0x62 to address 0xFFFFFE0E,Here's  the Technical Reference Manual description:

    "MFBALR1 – The BLOCK_SIZE field is loaded with a 6. This means that the Program Flash is at 0x10000, and is 32KB long. RONLY bit . If set, this means “read only”.

    Address FFFFFE0C – Memory Fine Base Address Low Register 1"

    Q1:  According to the manual , the address of MFBALR1 is  FFFFFE0C not  0xFFFFFE0E, Why write 0x62 to address 0xFFFFFE0E not FFFFFE0C in asm file?

     

     These assemblers then write 0x8822 to address 0xFFFFFE16

    The manual said:  "MFBALR2 – BLOCK_SIZE = 2, ADDRESS = 0x22 – Data flash = 2KB at 0x18800

    Address FFFFFE14 – Memory Fine Base Address Low Register 2"

    Q2:  Why write date 0x8822 to address 0xFFFFFE16 not FFFFFE14 (MFBALR2) in asm file?

    According to the MFBALR2 definition in manual "ADDRESS[15:10]  AW [9]  BLOCK_SIZE[7:4]  RONLY [1]  PRIV[0]"

    Q3: I think  you should write  0x2222 (not  0x8822 ) to register  MFBALR2 which means data flash base address 18800, block size 2K, read only?  Why write 0x8822 ?

     

     

    Best wishes

    LEI

     

     

     

     

     

     

     

     

     

  • You're really going over this with a fine toothed comb, aren't you.

    On the address question, note that the instruction is a STRH, store half, not an STR. So we're only storing the lower half of the register, 16 bits, not 32. So we use the address of the lower half of the 32 bit register, which is actually only a 16 bit register anyway.

    As far as the 8822 vs 2222, you're wrong, 8822 is the right value.
  • Hi,
    can you, please, tell me which code is referred to as "UCD3138A demo" here?
    Best regards,
    Adam
  • Dear Mr. Ian Bower;

    Thank you for your prompt  reply and detailed explanation. Thanks again.

    Have a nice weekend!

    Best Wishes

    LEI

  •  Dear Mr. Lan

    I am still confused about .cinit section

    .cinit definition:Tables for explicitly initialized global and static variables.

     .cinit     0    000065d0    0000004c     
                      000065d0    00000018     UART_Auto_Baud.obj (.cinit)
                      000065e8    00000018     fault_handler.obj (.cinit)
                      00006600    00000018     standard_interrupt.obj (.cinit)
                      00006618    00000004     --HOLE-- [fill = 0]

     .bss       0    0001901c    000006cc     UNINITIALIZED
                      0001901c    0000020b     main.obj (.bss)
                      00019227    00000001     uart.obj (.bss)
                      00019228    00000100     main.obj (.bss:_xn_bins)
                      00019328    00000080     main.obj (.bss:_program_area)
                      000193a8    00000058     main.obj (.bss:_pmbus_dcdc_config)
                      00019400    00000058     main.obj (.bss:_pmbus_dcdc_config_translated)
                      00019458    0000004c     main.obj (.bss:_filter0_cp_pmbus_regs)
                      000194a4    0000004c     main.obj (.bss:_filter0_pmbus_regs)
                      000194f0    0000004c     main.obj (.bss:_filter0_start_up_pmbus_regs)
                      0001953c    0000004c     main.obj (.bss:_filter1_pmbus_regs)
                      00019588    00000034     main.obj (.bss:_adc_values)
                      000195bc    00000034     main.obj (.bss:_adc_values_avg)
                      000195f0    00000034     main.obj (.bss:_fiq_data)
                      00019624    00000034     main.obj (.bss:_pmbus_buffer)
                      00019658    00000030     main.obj (.bss:_pmbus_dcdc_config_nonpaged)
                      00019688    00000030     main.obj (.bss:_pmbus_dcdc_config_nonpaged_translated)
                      000196b8    00000020     UART_Auto_Baud.obj (.bss)
                      000196d8    00000008     fault_handler.obj (.bss)
                      000196e0    00000008     standard_interrupt.obj (.bss)

    The auto-initialized variable in .cinit  section are variables in UART_Auto_Baud.obj  ,fault_handler.obj and standard_interrupt.obj .

    There are many global and static variables in many .C file, Why auto-initialized variable are choosen from the above three C files? Do they have any special purpose?

    Do we have to copy this auto-initialized variable  to RAM?  why?

    Best Wishes

    LEI