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.

problem with DSP/BIOS application branch to non-DSP/BIOS application

Other Parts Discussed in Thread: TMS320F28235

The environment: CCS4, TMS320F28235

 

We have a main application, which use DSP/BIOS, running from internal flash.

And we have a small application (boot loader), which does not use DSP/BIOS, running from external flash.

Both of the two applications we've tested and are sure they works.

Both of the two applications have a RS232 service routine, which can receive commands from RS232 port.  The difference is that the main application use PRD and software interrupt call the RS232 service routine, the boot loader use the main( ) function ,  in a infinity loop call the RS232 service routine.

 We have a command that tell the existing running application branch to the other application's entry point. In the main application we use this piece of code to do the branch: asm(" LB #0x00298064");

 

Before we do the branch, in main application all the PRDs are stopped and SWIs are disabled.

The problem is that when the main application received the command and executed the  asm(" LB #0x00298064"); the bootloader application can not start to run, instead the F28235 rebooted, and the main application start to run again.

 

If we run a small application instead of the main application in the internal flash, which doesn't not use the DSP/BIOS, When it received the command and executed the branch, the boot loader in the external flash can start to run.

 

Are there anybody know what's the possible reason? Are there any know issue that from a DSP/BIOS application branch to a non DSP/BIOS application?

Thanks,

Anna

 

  • Before your LB instruction make sure...

    1. PIEIER are all zeroed.
    2. you have also zeroed all core IER bits.
    3. your stack pointer is set back to its reset value

    This may, or may not, help depending on how you've implemented your application code.

    You may also want to zero all PIEIFR and IFR bits since you probably don't want any boot code interrupt flags to transfer over to application code.

  • Hi, quark,

     

    Thank you so much for your suggestions, it's very helpful.

    Following your suggestion 1. I zeroed all the PIEIER and PIEIFR before the LB instruction. It works! The code can switch from the internal flash main app to the external boot loader and running.

     

    But I have another problem, which is I cannot switch back.  I don't know if that is because I didn't do your suggestion 2 and 3.  Could you please let me know how to zero all the core IER bits and set the stack pointer back to its reset value? Could you please give me an example code?

     

    Here is what I did:

    In the main app's  link command file, I added

     

    .start : LOAD = FLASH_FOR_BOOT, PAGE = 0

        {

           bios.a28L <boot.o28L> (.sysinit)       

        }

     

    Here the FLASH_FOR_BOOT = 0x300000

     

    So after build I can see from the map file

     

    ENTRY POINT SYMBOL: "_c_int00"  address: 00300000

     

    The c_int00 is fixed at address 0x300000. So in the external flash boot loader code I use the following instruction to branch the code to the main app in the internal flash.

     

    asm(" LB #0x00300000"); //jump to internal flash main()of 28235 main code

     

    After I send the command asking the boot loader branch back to the main app, I can see (through the CCS4 emulator) the code did jump back to 0x300000 and run from there, but for some reason that I don't know, it did not run correctly.

     

    Then I powered off the board, hope it can start itself from the main app, but it didn't.

    I have to re-download the main app through the emulator.

     

    I did another test, I run the main app, send the command to let it branch to the external flash boot loader code, after the boot loader start running, did not send the command asking it branch back, I just cycle the power of the board, hope the main code can start. up. But it didn't. I have to re-download the main app.

     

    Do you have any idea why the main app can not run? Is that because I zeroed all the PIEIER and PIEIFR?

     

    Thanks,

    Anna

  • Zeroing IER and IFR can be easily done in C.

    IER = 0;

    IFR = 0;

     

    Resetting the SP will require assembly.

    asm("   MOV     AL,#0400h  ");
    asm("   PUSH    AL         ");
    asm("   POP     SP         ");

  • If your application code uses interrupts but you did not re-configure interrupts in the application code; that will make it not work.

  • Hi quark,

     

    What do you mean re-configure the interrupts? Please see the following, which are all the main application does in main( ) before doing other things:

     

    // Copy .hwi_vec section to RAM.  (Ref SPRA958H Sect. 4.2)

          asm(" EALLOW");        

          memcpy(      &hwi_vec_runstart,

                      &hwi_vec_loadstart,

                      &hwi_vec_loadend - &hwi_vec_loadstart);

          asm(" EDIS");

     

    // Copy Flash intitialization code to secure RAM. (Ref SPRA958H Sect. 4.4)

          memcpy(      &secureRamFuncs_runstart,

                      &secureRamFuncs_loadstart,

                      &secureRamFuncs_loadend - &secureRamFuncs_loadstart);

         

          // Initialize the on-chip flash registers.

          InitFlash();

               

    //--- CPU Initialization ---

          InitSysCtrl();      // Initialize the CPU.

          InitPieCtrl();      // Initialize and enable the PIE. -- this is zero all the PIEIER and PIEIFR, 

          InitWatchdog();      // Initialize the Watchdog Timer.

          InitGpio();       // Initialize the shared GPIO pins.

          InitEPwm();       // Initialize the Enhanced PWM.

          InitXintf();      // Initialize the external memory interface

          InitAdc();        // Initialize the ADC

     

     

    Also according to Ref SPRA958H Sect. 4.3

    We did this

    // The UserInit() function is run before main() and before DSP/BIOS

    //      initialization, which also happens before main(). (Ref SPRA958H Sect. 4.3)

    void UserInit(void)

    {

          // Initialize the .trcdata section before main().

          memcpy(      &trcdata_runstart,

                      &trcdata_loadstart,

                      &trcdata_loadend - &trcdata_loadstart);               

    }//<end> UserInit(void)

     

    What other else we should do to make it work?

    What I feel strange is that when I use emulator download the main app into the internal flash and cycle the power of the board, the code is running fine. But if I branched the main code to the external boot loader, and then cycle the power, the main app doesn't work. I think the code in the internal flash shouldn't have been changed, but why it cannot work after branched to the external flash boot loader?

     

    Many thanks,

    Anna

  • It appears that you're zeroing out PIEIER and PIEIFR in your main.  You may not want to do that because DSP/BIOS needs some interrupts to stay active.  Only zero those bits out just before the jump to your boot loader (and SP value reset should be between the interrupt zeroing and the jump).

    Since you're using DSP/BIOS, the DSP/BIOS initialization code should have reconfigured the interrupts.

    I do not know why it works differently in the two cases you mentioned.   Are your boot loader and application code in separate projects?  I would recommend that they be in separate projects, especially if you're using DSP/BIOS in both.  Even if you're not, it's good to have them separate so you can test them out individually.

  • Hi quark,

     

    I've test to comment out the InitPieCtrl();(zeroing out PIEIER and PIEIFR)line in the main app's main() function, it seems make no difference.

     

    The boot loader and the application code are in separate projects they are totally independent. The main app using DSP/BIOS, the boot loader not using DSP/BIOS.

     

    It seems something happened inside the F28235 after the code branch to the external flash and didn't recovered even after power cycle.

    You can see, the main app works fine from the internal flash, and the boot loader works fine from the external flash. But after the code branched from the main app to the external flash's boot loader, cycle the power, the main app cannot start up. We have to re-download the main code.

     

    The following is what I did for the branching to boot loader:

     

                      //stop PRDs                   

                      PRD_stop(&PRD_Heartbeat);

                      PRD_stop(&PRD_Keyboard_ScanRows);

                      PRD_stop(&PRD_analog_Inputs);

                      PRD_stop(&PRD_gpib_comm);

                      PRD_stop(&PRD_PicComm);

                      PRD_stop(&PRD_rs232_comm);

                      PRD_stop(&PRD_sync_channels);

                      PRD_stop(&PRD_usb_comm);

                      PRD_stop(&PRD_usb_parse_owner_check);

                      PRD_stop(&PRD_UsbHostComm);

                      //turn off the display

                      GuiDisplay_PowerOff();

                      //stop SWIs

                      SWI_disable(); //disable all the SWIs 

                      //disable the hardware interrupts                   

                      InitPieCtrl();

                      //zero all the core IERs

                      IER = 0;

                      IFR = 0;

                      //set stack pointer to it's reset value

                      asm("   MOV     AL,#0400h  ");

                      asm("   PUSH    AL         ");

                      asm("   POP     SP         ");

                      //disable the watch dog

                      InitWatchdog();

                      //jump to external flash boot loader

                      asm(" LB #0x00298064");   

     

    Do you have any idea?

    Thanks,

    Anna

  • I am guessing your external flash code's purpose is to erase and write to the internal flash's code-space.

    Perhaps there is a bug in the external flash's code which corrupts the internal flash?

    Try this...

    After programming both code and before running anything; perform a checksum check.

    Run only the internal flash code; perform a checksum check again.

    Run the internal flash and branch to external flash; perform a third checksum check.

    If any of the checksums are different, then something is corrupting the flash.

  • Hi quark,

    You are absolutely right!! I found the bug in the external falsh's code which erase a bit part of the internal flash.

    I really appreciate all your help. You were really very helpful!!!

    Thanks again,

    Anna