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.

Jump to BIOS App from custom bootloader.

Other Parts Discussed in Thread: TMS320F28335, SYSBIOS

I am trying to create a skeleton for a custom bootloader on the TMS320F28335. The bootloader is a non-bios application and resides in sector A of the flash device. We have a BIOS application loaded in flash sectors B-H. I have enforced the locations in flash with the linker command script. According to the map file for the BIOS application the _c_int00 for it resides at 0x00320d9d and as such my very minimal bootloader ...

void main(void)
{
    asm(" LB 0x00320d9d");
}

is set to jump to that address. From what I understand this and disabling the watchdog is all my minimal bootload should have to do to jump to another application. When I jump to a NON-BIOS app from the bootloader everything seems to run as expected. When I jump to the BIOS app from the bootload I end up in ITRAP.

What must I do extra to be able to properly jump to a BIOS app? What does BIOS expect me to configure that I am not?

  • After further experimentation the error with jumping to BIOS only occurs when I place .ebss for the BIOS app in external RAM. I am configuring external RAM inside my bootloader now as I have been doing with BIOS 'user reset function'.

    I have to run our application from external RAM due to size constraints.

  • Steve,

    Are you saying the problem is now resolved?

    Alan

  • No. Just narrowed it down to a cause: BIOS .ebss in external RAM when booting from custom bootloader.

    I still need help figuring out why this is a problem when the bootloader is doing the same pre-_c_int00 initialization of the XINTF bus that I had BIOS configured to when I was directly booting to my BIOS application. Calling the function below in the bootloader prior to jumping to _c_int00 for the BIOS app should be the same as having BIOS call the function before calling it's own _c_int00.

    void initExternMem(void)
    {
        ///////////////////////////////////////////////////////////////////////////
        // setup xternal ram interface
        ///////////////////////////////////////////////////////////////////////////

        volatile struct SYS_CTRL_REGS*  SysCtrlRegs;
        volatile struct GPIO_CTRL_REGS* GpioCtrlRegs;
        volatile struct XINTF_REGS*     XintfRegs;

        SysCtrlRegs  = (volatile struct SYS_CTRL_REGS*) 0x007010;
        GpioCtrlRegs = (volatile struct GPIO_CTRL_REGS*)0x006F80;
        XintfRegs    = (volatile struct XINTF_REGS*)    0x0B20;

        EALLOW;
        // Make sure the XINTF clock is enabled
        SysCtrlRegs->PCLKCR3.bit.XINTFENCLK = 1;
        SysCtrlRegs->PCLKCR3.bit.GPIOINENCLK = 1;    // GPIO input clock

        // Configure the GPIO for XINTF with a 16-bit data bus
         GpioCtrlRegs->GPCMUX1.bit.GPIO64 = 3;  // XD15
         GpioCtrlRegs->GPCMUX1.bit.GPIO65 = 3;  // XD14
         GpioCtrlRegs->GPCMUX1.bit.GPIO66 = 3;  // XD13
         GpioCtrlRegs->GPCMUX1.bit.GPIO67 = 3;  // XD12
         GpioCtrlRegs->GPCMUX1.bit.GPIO68 = 3;  // XD11
         GpioCtrlRegs->GPCMUX1.bit.GPIO69 = 3;  // XD10
         GpioCtrlRegs->GPCMUX1.bit.GPIO70 = 3;  // XD19
         GpioCtrlRegs->GPCMUX1.bit.GPIO71 = 3;  // XD8
         GpioCtrlRegs->GPCMUX1.bit.GPIO72 = 3;  // XD7
         GpioCtrlRegs->GPCMUX1.bit.GPIO73 = 3;  // XD6
         GpioCtrlRegs->GPCMUX1.bit.GPIO74 = 3;  // XD5
         GpioCtrlRegs->GPCMUX1.bit.GPIO75 = 3;  // XD4
         GpioCtrlRegs->GPCMUX1.bit.GPIO76 = 3;  // XD3
         GpioCtrlRegs->GPCMUX1.bit.GPIO77 = 3;  // XD2
         GpioCtrlRegs->GPCMUX1.bit.GPIO78 = 3;  // XD1
         GpioCtrlRegs->GPCMUX1.bit.GPIO79 = 3;  // XD0

         GpioCtrlRegs->GPBMUX1.bit.GPIO40 = 3;  // XA0/XWE1n
         GpioCtrlRegs->GPBMUX1.bit.GPIO41 = 3;  // XA1
         GpioCtrlRegs->GPBMUX1.bit.GPIO42 = 3;  // XA2
         GpioCtrlRegs->GPBMUX1.bit.GPIO43 = 3;  // XA3
         GpioCtrlRegs->GPBMUX1.bit.GPIO44 = 3;  // XA4
         GpioCtrlRegs->GPBMUX1.bit.GPIO45 = 3;  // XA5
         GpioCtrlRegs->GPBMUX1.bit.GPIO46 = 3;  // XA6
         GpioCtrlRegs->GPBMUX1.bit.GPIO47 = 3;  // XA7
         GpioCtrlRegs->GPCMUX2.bit.GPIO80 = 3;  // XA8
         GpioCtrlRegs->GPCMUX2.bit.GPIO81 = 3;  // XA9
         GpioCtrlRegs->GPCMUX2.bit.GPIO82 = 3;  // XA10
         GpioCtrlRegs->GPCMUX2.bit.GPIO83 = 3;  // XA11
         GpioCtrlRegs->GPCMUX2.bit.GPIO84 = 3;  // XA12
         GpioCtrlRegs->GPCMUX2.bit.GPIO85 = 3;  // XA13
         GpioCtrlRegs->GPCMUX2.bit.GPIO86 = 3;  // XA14
         GpioCtrlRegs->GPCMUX2.bit.GPIO87 = 3;  // XA15
         GpioCtrlRegs->GPBMUX1.bit.GPIO39 = 3;  // XA16
         GpioCtrlRegs->GPAMUX2.bit.GPIO31 = 3;  // XA17
         GpioCtrlRegs->GPAMUX2.bit.GPIO30 = 3;  // XA18
         GpioCtrlRegs->GPAMUX2.bit.GPIO29 = 3;  // XA19
         GpioCtrlRegs->GPBMUX1.bit.GPIO38 = 3;  // XWE0

         GpioCtrlRegs->GPBMUX1.bit.GPIO37 = 3;  // XZCS7
         GpioCtrlRegs->GPAMUX2.bit.GPIO28 = 3;  // XZCS6
        // All Zones---------------------------------
        // Timing for all zones based on XTIMCLK = SYSCLKOUT
        XintfRegs->XINTCNF2.bit.XTIMCLK = 1;
        //Buffer up to 3 writes
        XintfRegs->XINTCNF2.bit.WRBUFF = 0;
        //XCLKOUT is enabled
        XintfRegs->XINTCNF2.bit.CLKOFF = 0;
        //XCLKOUT = XTIMCLK
        XintfRegs->XINTCNF2.bit.CLKMODE = 1;

        // Zone 6------------------------------------
        // When using ready, ACTIVE must be 1 or greater
        // Lead must always be 1 or greater
        // Zone write timing
        XintfRegs->XTIMING6.bit.XWRLEAD = 1;
        XintfRegs->XTIMING6.bit.XWRACTIVE = 1; // Drives = 1
        XintfRegs->XTIMING6.bit.XWRTRAIL = 1;
        // Zone read timing
        XintfRegs->XTIMING6.bit.XRDLEAD = 1;
        XintfRegs->XTIMING6.bit.XRDACTIVE = 1; // Drives = 2
        XintfRegs->XTIMING6.bit.XRDTRAIL = 1;

        // don't double all Zone read/write lead/active/trail timing
        XintfRegs->XTIMING6.bit.X2TIMING = 0;

        // Zone will not sample XREADY signal
        XintfRegs->XTIMING6.bit.USEREADY = 0;
        XintfRegs->XTIMING6.bit.READYMODE = 0;

        // 1,1 = x16 data bus
        // 0,1 = x32 data bus
        // other values are reserved
        XintfRegs->XTIMING6.bit.XSIZE = 3;

        EDIS;

       //Force a pipeline flush to ensure that the write to
       //the last register configured occurs before returning.
       asm(" RPT #7 || NOP");
    }

  • IE:

    Startup.resetFxn = "&initExternMem"; in my BIOS config file.

    vs:

    typedef void (*fptr)(void);

    void main(void)
    {
        fptr init = APP_START_ADDR;

        initExternMem();

        (*init)();
    }

    in my bootloader.

  • Can you step through your boot loader's invocation of 'initExternMem()' to confirm that external memory is indeed getting initialized correctly and that accesses to this memory region are successful?

    Does your map file show any .const or .cinit data placed in .ebss?

    Alan

  • Yes. I can step through initExternMem in the bootloader and manually read/write to external ram content in my bootloader.

        volatile char* x = (char*)0x100000;
        *x = 'a';
        char y = *x;

    y is in fact = 'a'

    Here is what the map file is saying it puts in .ebss.

    .ebss.1    1    00100000    0000056e     UNINITIALIZED
                      00100000    00000440     task_p28FP.o28FP (.ebss)
                      00100440    00000108     rts2800_fpu32.lib : trgdrv.obj (.ebss)
                      00100548    00000018     DSP2833x_CpuTimers.obj (.ebss)
                      00100560    00000004     rts2800_fpu32.lib : _lock.obj (.ebss)
                      00100564    00000004                       : exit.obj (.ebss)
                      00100568    00000003     sysbios.lib : BIOS.obj (.ebss)
                      0010056b    00000001     task.obj (.ebss)
                      0010056c    00000002     rts2800_fpu32.lib : sinit.obj (.ebss)

    .ebss.2    1    00100580    00000200     UNINITIALIZED
                      00100580    00000100     rts2800_fpu32.lib : atexit.obj (.ebss)
                      00100680    00000100     task_p28FP.o28FP (.ebss:taskStackSection)

  • Here is one fix that made my toy bios app work.

    00100680    00000100     task_p28FP.o28FP (.ebss:taskStackSection)

    taskStacks cannot be in external ram. I placed the stacks for the toy app back in internal RAM.

    Let me check with my real app and make sure this is not happening, though I am pretty sure I am placing the stacks in internal ram there.


  • Still crashing in my real APP.  Content of .ebss is....

    .ebss.1    1    00100000    00014634     UNINITIALIZED
                      00100000    00006040     DBMActual.obj (.ebss)
                      00106040    00004400     DBM2GFacade.obj (.ebss)
                      0010a440    00004000     DBMHardLimits.obj (.ebss)
                      0010e440    00004000     DBMUserLimits.obj (.ebss)
                      00112440    00001100     DBM2GFacadeScalings.obj (.ebss)
                      00113540    00000e03     task_p28FP.o28FP (.ebss)
                      00114343    00000001     rts2800_fpu32.lib : fopen.obj (.ebss)
                      00114344    0000002e     powerup.obj (.ebss)
                      00114372    00000008     HAL_TMS320F28335.lib : I2C.obj (.ebss)
                      0011437a    00000004                          : McBSPI.obj (.ebss)
                      0011437e    00000002                          : RS485.obj (.ebss)
                      00114380    00000160     rts2800_fpu32.lib : defs.obj (.ebss)
                      001144e0    00000016     HAL_TMS320F28335.lib : NotchSpd.obj (.ebss)
                      001144f6    00000004     rts2800_fpu32.lib : _lock.obj (.ebss)
                      001144fa    00000004                       : exit.obj (.ebss)
                      001144fe    00000002                       : rand.obj (.ebss)
                      00114500    00000108                       : trgdrv.obj (.ebss)
                      00114608    00000026     HAL_TMS320F28335.lib : Stepper.obj (.ebss)
                      0011462e    00000003     sysbios.lib : BIOS.obj (.ebss)
                      00114631    00000001     --HOLE--
                      00114632    00000002     rts2800_fpu32.lib : sinit.obj (.ebss)

    .ebss.2    1    00114640    00000188     UNINITIALIZED
                      00114640    00000100     rts2800_fpu32.lib : atexit.obj (.ebss)
                      00114740    00000088                       : lowlev.obj (.ebss)

  • Putting a breakpoint in initExternMem it appears _c_int00 make this call for me. So it shouldn't make a difference if I am booting the BIOS app from my bootloader that calls its _c_int00 or if _c_int00 is called via the normal BIOS boot procedure.

  • c_int00 is calling initExternMem() because you configured it as a Startup reset function.

    Is it ok if initExternMem() is called twice? (Is that even happening?)

    Have you been able to determine where in the boot-loader managed climbup sequence things start to go bad?

    Alan

  • Is the source for _c_init00 available in the TI directories? If I could step into the C code I could get an idea where it goes off the deep end.

  • The source for c_int00 is in your installed xdc product repository.

    It will be in the "packages/ti/targets/rts2800" directory in "boot_cg.asm".

    c_int00 calls the Startup.resetFxn(s), then initializes global variables, then calls '_xdc_runtime_Startup_exec__E' which then initializes all the modules used by your application. Sometime after that it calls main().

    Does the application ever reach its own main()?

    Alan

  • Yes. It does get to main().

  • That is main() in the BIOS app that the bootloader calls.

  • Issue is resolved and it had nothing to do with software. We just moved to a new spin of our prototype board that apparently was having a power issue that manifested itself as an ITRAP. Running on a previous version of the board every seems to work. One follow on, and let me know if I should put it in another thread, is that using the CMD file method to forcibly place _c_int00 at a specific address is not working.

    IE.

     SECTIONS {
       .text:_c_int00 > 0x300000
     }

    produces

    ENTRY POINT SYMBOL: "_c_int00"  address: 00320d9d

    in my map file.

    Should it not place _c_int00 precisely at 0x300000.
  • I'm glad you were able to resolve the problem!

    I have NEVER had any success trying to place _c_int00 at a specific address (and I've tried several times...).

    You may want to post that question to the codegen tools forum:

         http://e2e.ti.com/support/development_tools/compiler/default.aspx

    Alan

  • I have posted there. Thanks for the help.