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.

F28335 Strange Flash booting issue will not boot after power reset

Hello,

I have a project I have created in C++ using for the 28335 processor.  I have it set up to boot out of flash and move critical time sensitive functions to RAM at runtime.  I have used many of the TI guides to help me along the way, but I am having a problem I cannot wrap my head around.

Currently, if the application is running using CCS and JTAG, it flashes, boots, and runs with no issues.  I can press the reset button on CCS and it will come back from that as well.  I can disconnect the target, reconnect the target and it picks up running with no issues as well.

However, if I disconnect the target and then power cycle the board, when I reconnect to it I see that it is stuck in an infinite loop.  

I am stuck in boot.asm in the PINIT section.  Under normal (other) conditions, I see that as I go through the pinit code, it pops off an address from the pinit table and runs the constructor.  It then goes back and pops another address off and runs that constructor.  Finally, you get 0 from the table, and you break out of the loop and go to main.

After a power-cycle, I see the same sequence of events, however after it pops off the second address and runs that constructor, the subsequent pop goes back to the first item on the list!  I am not sure what is causing this or why.

Now for the really freaky part - I moved the math libraries into RAM to speed them along in the execution.  When I put them in RAM, I see the behavior I outlined above.  If I leave the math library in FLASH, everything works - power cycle and all!  I don't know what the location of the math libs have to do with any of the constructor stuff, but it is full repeatable and controllable.

I guess I would like to understand why this behavior is happening and also how to fix it.  I need that math lib in RAM during runtime, and I also need to be able to power-cycle the processor and have it come back booting from flash.  Here is the code from boot.asm that is causing the infinite loop:

****************************************************************************
* IF pinit IS NOT -1, PROCESS CONSTRUCTOR ROUTINES *
****************************************************************************
DO_PINIT:

****************************************************************************
* CLEAR THE EALLOW BIT AFTER THE CINIT TABLE IS COPIED. *
****************************************************************************
EDIS

MOV AL,#pinit
MOV AH,#hi16(pinit)
ADDB ACC,#1
B DONE_INIT,EQ ; if pinit < 0 (-1) no pinit table

****************************************************************************
* PROCESS PINIT SECTION. TABLE CONSISTS OF CONSTRUCTOR ROUTINE ADDRESSES *
* THAT POINT TO C++ INITIALIZATION FUNCTIONS. THESE ROUTINES MUST EXECUTE *
* BEFORE MAIN IS CALLED *
****************************************************************************
MOVL XAR7,#pinit ; set up pointer to initialization table
B START_PINIT, UNC ; jump to start processing

LOOP_PINIT:
ADDB XAR7,#1 ; point to next table entry
PUSH XAR7 ; save off table entry address
MOVL XAR7,ACC ; load constructor routine address
LCR *XAR7 ; execute routine
POP XAR7 ; reload table entry address

START_PINIT:
PREAD AL,*XAR7 ; unpack constructor routine address
ADDB XAR7,#1
PREAD AH,*XAR7
TEST ACC ; test for table end condition (zero)
B LOOP_PINIT,NEQ ; process table entry if not zero


****************************************************************************
* COPY CONSTANTS TO DATA MEMORY, IF NECESSARY *
****************************************************************************

Is there something that I should be doing to initialize the RAM after the power cycle perhaps?  This all seems pretty early in the process, so I am not sure what could be messing that pinit list up?

Any help/pointers would be greatly appreciated!!

-Jeff
  • Jeff,

    how do you move the math tables to RAM? do you do this at run time in your code in flash, before accessing any tables or are they statically linked to RAM?

    Jeff Choate said:

    Now for the really freaky part - I moved the math libraries into RAM to speed them along in the execution.  When I put them in RAM, I see the behavior I outlined above.  If I leave the math library in FLASH, everything works - power cycle and all!  I don't know what the location of the math libs have to do with any of the constructor stuff, but it is full repeatable and controllable.

     

    Best Regards

    Santosh

  • Hi Santosh,

    I have tried several approaches.  First I tried doing it simply with a linker command using the libraries like this:

    .rts  { -lrts2800_fpu32_fast_supplement.lib (.text) }  >> RAML0,   PAGE = 0

    If I have that line in the linker command file, I get the weird behavior.  If I comment that line out, everything works fine (but the math takes too long to complete and screws me up computationally - thus I need it in there).

    Next, I figured I would get rid of the libraries to give myself more control and I took the assembly sources and put them right into my project directly to get around the linking issues and just assigned them to RAM directly like this:

          .page
    .global _sin
    .ref _FPUsinTable
    .ref _FPUcosTable

    .sect ".mathfuncs"

    _sin: ; R0H = Radian (on entry)
    MOVIZ R1H,#0x42A2 ; R1H = 512/(2*pi) = 512/6.28318531 = 81.4873309
    MOVXI R1H,#0xF983
    MPYF32 R0H, R0H, R1H ; R0H = Radian * 512/(2*pi)
    
    
    Then I just drop the section where I want it in the linker.  if I assign ".mathfuncs" to RAM, I get the weird behavior.  If I assign the section to FLASH - you guessed it - no problems!
    Finally, I tried to do something like ramfuncs where I load it into flash, but then copy it into RAM at runtime - just like I would do with the RAMFUNCS using memcpy.  But that didn't work 
    at all - it wouldn't even boot after I tried that, so I abandoned the approach- I figured I don't need any more problems!
    
    
    Does any of this make sense?  Can you see something I am messing up?
    
    
    I hope this provides the insight you were asking for?
    
    
    -Jeff
  • Jeff,

    please refer to the app note http://www.ti.com/general/docs/lit/getliterature.tsp?literatureNumber=spraan5&fileType=pdf

    looks like you are running in to issues when placing the PINIT/CINIT sections properly for stan-alone functionality. When you load your code through CCS, the CCS will be loading all the tables/run-time needed data that is linked to RAM properly (=intializing RAM properly) and when your code is executing from flash all the needed data is already initialized now (because of CCS load process). But when you are running the device in stand-alone mode no one is initializing the needed RAM for your code.

    The app note talks about how to deal with such cases. You can also look at your map file (linker generated) to see where your CINIT/PINIT/SWITCH/YOUR_DEFINED_SECTIONS sections are located. To exactly help you solving the problem you will have to narrow it down to the section that is causing the problem (look for sections linked to RAM).

    try avoiding any initialized gloal variables, see if you can avoid switch/case statements in code (atleast until you can solve this) - load all functions to flash, but if you want then to run from RAM then link them to RAM and have your code copy the code from appropriate flash locations to appropriate RAM locations (like the RAMFUNCS).

    Let us know if you have any questions after looking at the app note or if you find more details.

     

    Best Regards

    Santosh

     

  • The answer to this problem was that the functions had to be loaded first before doing anything else.  In order to do this, I used the copy_sections routine provided by DSP28xxx_SectionCopy_nonBIOS.asm.  Then in the DSP2833x_CodeStartBranch.asm loading routine, I branch to the copy sections routine instead of the start.  I modified the startup code to look like this:

    ***********************************************************************
    * Function: wd_disable
    *
    * Description: Disables the watchdog timer
    ***********************************************************************
    .if WD_DISABLE == 1

    .text
    wd_disable:
    ;LCR _initPrep
    MOVL XAR0, #_initListNext ; Get the address of initListNext
    MOVL XAR1, XAR0 ; Put it in XAR1 also
    MOVL *XAR0++,XAR1 ; Make the next ptr point at itself
    MOVL *XAR0++,XAR1
    SETC OBJMODE ;Set OBJMODE for 28x object code
    EALLOW ;Enable EALLOW protected register access
    MOVZ DP, #7029h>>6 ;Set data page for WDCR register
    MOV @7029h, #0068h ;Set WDDIS bit in WDCR to disable WD
    EDIS ;Disable EALLOW protected register access
    ; LB _c_int00 ;Branch to start of boot.asm in RTS library
    LB copy_sections ;Branch to copy_sections

    .endif

    ;end wd_disable

    and then at the end of copy_sections, I simply call to  _c_int00 there.  This causes everything to be moved into RAM at boot time, and resolved my problem.  I hope this helps someone else!

    -Jeff

  • Is there any explanation for this behavior? Why did the functions have to be copied before doing anything else? Were you calling the functions in RAM *before* the point where you copy them into RAM at runtime? I would assume one can copy relevant code sections into RAM at any point and jump there ..

  • Hello Jeff,

    I am having a similar problem. Hope you can help.

    The difference is that I am programming through Matlab Simulink with CCS toolchain. So actually I only have blocks and I dont write any C++ code in CCS. Matlab creates it itself.

    I had been using the f28335 since for sometime and there was no such problem.

    Now when i program through emulator, it works fine. But when i power off/on again, it is stuck somewhere. But while it is stuck, I connect through emulator to CCS and RUN code again, it starts working again. Also if I press the reset button on the board, it starts working. But on Power on/off, it doesn't.

    Here is my .cmd file made in CCS.

    MEMORY
    {
    PAGE 0:
        BEGINRAM:	 origin=0x0, length=0x2
        RAMM0:	 origin=0x2, length=0x3fe
        OTP:	 origin=0x380400, length=0x400
        FLASH:	 origin=0x300000, length=0x3fff6
        BEGINFLASH:	 origin=0x33fff6, length=0x2
        CSM_PWL:	 origin=0x3f7ff8, length=0x8
        IQTABLES:	 origin=0x3fe000, length=0xb50
        IQTABLES2:	 origin=0x3feb50, length=0x8c
        FPUTABLES:	 origin=0x3febdc, length=0x6a0
        ROM:	 origin=0x3ff27c, length=0xd44
        RESET:	 origin=0x3fffc0, length=0x2
        VECTORS:	 origin=0x3fffc2, length=0x3e
        RAML4L7:	 origin=0xe000, length=0x2000
        ADC_CAL:	 origin=0x380080, length=0x9
        ZONE7P:	 origin=0x200000, length=0x10000
    PAGE 1:
        RAML0L3:	 origin=0x8000, length=0x6000
        RAMM1:	 origin=0x400, length=0x400
        ZONE7D:	 origin=0x210000, length=0x10000
    }
    SECTIONS
    {
        .vectors:	 load = 0x000000000
        .text:	 > FLASH, PAGE = 0
        .switch:	 > FLASH, PAGE = 0
        .bss:	 > RAML0L3, PAGE = 1
        .ebss:	 > RAML0L3, PAGE = 1
        .far:	 > RAML0L3, PAGE = 1
        .cinit:	 > FLASH, PAGE = 0
        .pinit:	 > FLASH, PAGE = 0
        .const:	 > FLASH, PAGE = 0
        .econst:	 > FLASH, PAGE = 0
        .reset:	 > RESET, PAGE = 0, TYPE = DSECT
        .data:	 > RAML0L3, PAGE = 1
        .cio:	 > RAML0L3, PAGE = 1
        .sysmem:	 > RAML0L3, PAGE = 1
        .esysmem:	 > RAML0L3, PAGE = 1
        .stack:	 > RAMM1, PAGE = 1
        .rtdx_text:	 > FLASH, PAGE = 0
        .rtdx_data:	 > RAML0L3, PAGE = 1
        IQmath:	 > FLASH, PAGE = 0
        codestart:	 > BEGINFLASH, PAGE = 0
        csmpasswds:	 > CSM_PWL, PAGE = 0
        csm_rsvd:	 > RAMM0, PAGE = 0
        ramfuncs:	 LOAD = FLASH,
    		RUN = RAMM0,
    		LOAD_START(_RamfuncsLoadStart),
    		LOAD_END(_RamfuncsLoadEnd),
    		RUN_START(_RamfuncsRunStart),
    		PAGE = 0
        .adc_cal:	 > ADC_CAL, PAGE = 0 , TYPE = NOLOAD
        IQmathTables:	 > IQTABLES, PAGE = 0 , TYPE = NOLOAD
        IQmathTables2:	 > IQTABLES2, PAGE = 0 , TYPE = NOLOAD
        FPUmathTables:	 > FPUTABLES, PAGE = 0 , TYPE = NOLOAD
    }
    -l "C:\MATLAB\R2012b\toolbox\idelink\extensions\ticcs\c2000\c2833xPeripherals.cmd"
    

    and my CodeStartBranch.asm code is:

    ***********************************************************************
    
    WD_DISABLE	.set	1		;set to 1 to disable WD, else set to 0
    
        .ref _c_int00
        .global code_start
    
    ***********************************************************************
    * Function: codestart section
    *
    * Description: Branch to code starting point
    ***********************************************************************
    
        .sect "codestart"
    
    code_start:
        .if WD_DISABLE == 1
            LB wd_disable       ;Branch to watchdog disable code
        .else
            LB _c_int00         ;Branch to start of boot.asm in RTS library
        .endif
    
    ;end codestart section
    
    
    ***********************************************************************
    * Function: wd_disable
    *
    * Description: Disables the watchdog timer
    ***********************************************************************
        .if WD_DISABLE == 1
    
        .text
    wd_disable:
        SETC OBJMODE        ;Set OBJMODE for 28x object code
        EALLOW              ;Enable EALLOW protected register access
        MOVZ DP, #7029h>>6  ;Set data page for WDCR register
        MOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WD
        EDIS                ;Disable EALLOW protected register access
        LB _c_int00         ;Branch to start of boot.asm in RTS library
    	
        .endif
    
    ;end wd_disable
    
    
    
    	.end
    	
    ;//===========================================================================
    ;// End of file.
    ;//===========================================================================
    

    Hope you can help..

    Regards,

    Adil