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.

repost - problem with flash programming - concerto

Other Parts Discussed in Thread: CONTROLSUITE

Reposted from TI-RTOS concerning flash boot programming...

I only need to boot the cm3. I download the app upgrade code from a communication network that the c28 controls. I transfer the code through the IPC and first store it into high flash on the cm3 side, using the falsh programming tools. Next I attempt to transfer the code from the high flash memory location down to 0x200000.

I have not had much luck in doing this. It appears that the ramfuncs code does not get overwritten (works until I cycle power).  I believe I could get it to work if I fix the boot up location and then only transfer the app code minus the ramfuncs. How do I determine the location of the c_int00() startup location and how do I fix it in memory? Any other suggestions as to how to overcome this / solve the flash code transfer problem would be helpful. I have had zero luck trying to set breakpoints in RAM with the debugger. The XDS560V2 does not support trace on the Concerto.

CCS5.4, Concerto f28m35h52c1, XDS560V2 STM USB are what I am using.

Thanks,

Pat

  • Follow up -

    Transferring all code from the start (0x200000), including boot up code at 0x200030 will work properly as long as the code is identical to the existing code (not much use) and as long as I do not cycle power. If the code is not the same, then the process fails until I restart it using debug. It also will not restart with a power cycle. What is missing here? What is different about reset and run using the debugger vs. just a power cycle?

    Thanks,

    Pat

    .

    .

  • A power cycle clears all the registers to their reset value.  The debug reset leaves a few registers with their previous value.

    Could you elaborate more on this whole process and what is supposed to be where when?  If I have a better idea of the big picture I may be able to better assist you.

    Regards,

  • Pat,

    what are you trying to achieve, upgrade firmware image on M3? is code running on M3 doing the firmware upgrade and the new image that needs to be flashed is copied by C28x using IPC into M3 flash?

    Can you break down the problem and tell what works and what doesn't so we can help you better?

     

    Best Regards

    Santosh

     

     

  • Apologies for not responding sooner. I had been out of the office.

    My "download" transfers the CCS5.4 .hex upgrade file (vs the .out file) from C28 controlled power-line communication network, through the IPC, and then stores it into high flash memory. Following the succesful complete transfer of the new image to high flash, I then move the code from high flash to low flash, halt the CM3 processor and restart.

    Normally, when I download a new CM3 image through the CCS debug and then either reset and run the C28 followed by the CM3, the application will run properly. Or I can also achieve the normal running condition by first disconnecting the CM3 with the debug utility (to avoid locking up CCS5.4) and then cycle the power switch for the MCU board.

    What I have determined now is that the transfer of flash code ( the CM3 firmware image) from high flash (0x240000) to the normally operating location at 0x200000 is successful, but will only run if I execute it with the debug tool through CCS 5.4 (XDS560V2 STM JTAG). It will not run if I cycle power. Following my transfer of code, I delay to force a watchdog restart. This is successful. If I cycle power, then the program hangs. By reconnecting , resetting, and restarting through debug, it will run again.

     So power-on is apparently initializing something that debug reset does not. This lack of initialization is crucial for proper startup, it appears. Would you agree?  What would be the likely suspect?

    Thanks,

    Pat

     

     

  • Pat,

    to be able to stand alone boot to flash, you need to have proper boot mode selected by the boot mode GPIO. When boot to flash is set, the device CPU branches to the Flash Entry Point, the location is documented in the device TRM boot ROM chapter. At the entry point you would need to have your application entry point code flashed (code start or a branch to _c_init00 or a branch to main) ...else it wont work stand alone.

     

    but when you have debugger connected, after a program load the control is automatically set to where your entry point is linked to, so it will work. But when booting stand-alone for it to work the entry point of your application and the entry point where boot ROM is branching to should match.

    I assume since you are moving your code from one location to another, you must have linked the code at RUN address properly.

     

    Best Regards

    Santosh

  • Santosh,

    I am booting from flash (GPIO35, 43 and 47 tied high). When I download from CCS debug , the reset location at 0x200030 has the following code when usinh memory view:

    F01BBBA2 4770FFFF FF.....

    After moving the code from 0x240000, I have:

    F01BBBA4 47700000 A5A5A5A5 A5A5A5A5 FF....

    (same as the code at 0x240000). The two sets of code are slightly different, so this may account for the ..A4.. vs ..A2.. . Is it necessary that I use a definite reset location? Does the different code following the ..4770.. make any difference? Where can I find an explanation of the binary op codes?

    Thanks.

    Pat

     

     

     

  • Added note. I am getting a compiler warning that .resetisr was padded by two bytes. Apparently the padding is '0000'. Should it be 'FFFF'? How do I make it so? Is there a 16 bit asm instruction that compiles to 0xffff?

    Thanks,

    Pat

     

  • There should be four boot mode pins, please refer to the device datasheet for the boot mode pins. The TRM update is pending.

    There would be a startup_ccs.c file in your project (you can look at controlsuite examples) - it has below function. This is considered the entry point to your application if your project properties are set right. Your linker command file has to make sure that .resetisr section is linked to the flash entry point. This entry point is fixed per device because bootROM code branches to this location to start the application.

    I'm not sure about the padding, but please refer to the generic flash M3 linker command file in control suite (C:\ti\controlSUITE\device_support\f28m35x\v201\MWare\cmd) to understand how to link the .resetisr to the default entry point in flash.

    #pragma CODE_SECTION(ResetISR, ".resetisr")

    void ResetISR(void)

    {

       // Jump to the CCS C Initialization Routine.

    __asm("    .global _c_int00\n"

    "    b.w     _c_int00");

    }

    Best Regards

    Santosh

     

  • Santosh,

    Yes, my startup file has the required code and the .cmd file declares RESETISR to be 8 bytes at 0x200030.

    I'm concerned that the warning message stating that RESETISR was padded with 2 bytes of 0x00s may be causing a problem???
    If so, how do I get rid of the warning message? Is there some code that I could add to the RESETISR routine that would append 2 bytes of 0xff?

    All four pins of the boot mode programming pins are pulled high. I can normally boot to flash with a power cycle with no problem. It's just when I do the internal transfer of the new app stored in high flash memory down to low memory that the problem occurs.

    Pat

     

     

  • Pat,

    you can pad it with 0xFFFF by using a FILL=0xFFFF in your linker command file line as shown below.

        RESETISR (RX)   : origin = 0x00200030, length = 0x0008, FILL=0xFFFFFFFF   /* Reset ISR is mapped to boot to Flash location */

     

    You can debug it...after you are done with copy to 0x200030 - you can load the application symbols and step through. So is the code linked as LOAD to HIGHMEM but RUN from LOWMEM?

     

    Best Regards

    Santosh

     

  • Santosh,

    Putting the FILL= 0xFFFFFFFF gives a warning "($fill000) at 0200036h overlaps". I cannot find this fill statement anywhere. Is this a problem? Does the instruction require the last half to be filled with 0xFFFF or is the 0000 okay? Do you have any idea where this $fill000 might have occurred - perhaps a configuration file?

    The 0000 is a product of the hex conversion, apparently. The hex data for the start of the file is:

    :020000040020DA

    :080030001BF0A2BB70470000A9

    :20100000E41F002031002000CDBE210075B2210011B82100E5B9210011B8210000000000D5

    Note "70470000" whereas the debug downloaded code is "7047FFFF".

    Is this a problem? I'm trying to eliminate non problems in order to narrow down the possibilities.

    Thanks,

    Pat

  • Perhaps this is done as part of the "padding" to fill the two bytes (another warning message). Where is this done?

    Pat'

  • Pat Harris said:
    Putting the FILL= 0xFFFFFFFF gives a warning "($fill000) at 0200036h overlaps

    I don't see that warning when building the blinky_dc_m3 project in control suite with FILL. Fill is one of the linker directives which puts 0xFFFF at the unused memory locations in a section. It must be documented in the compiler/linker documentation.

     

    pad with 0x0000 or with 0xFFFF shouldn't cause any problem as you won't be executing that.

     

    after you download your code through boot peripheral and after the code is copied from one location to the final location, could you connect CCS (JTAG) and load the application coff symbols and debug?

    Which version of MCU are you running this on and this F28M35x or F28M36x? You should be able to do all this with CCS connected and findout what is going on. Just to be sure of it, could you clarify below?

    > the code that copies your application from one part of flash to other part, where is it located and how is that started? What is M3 doing on boot - is it running any application at all?

     

    Best Regards

    Santosh

     

     

  • Santosh,

    I added "NOP"s to the RESETISR asm code to cover all the bogus data I have been seeing. Now both the warning messages have gone away and the transferred code at 0x200030 is identical to the debug download code, but my problem still persists.

    I am using the f28m35h52c1 chip. In my m3 application, I have a routine that collects new m3 image code from a special network that is controlled by the c28 and passed through the IPC. This "network download" function receives myapp.hex file records, converts them to binary, and stores them into high m3 flash memory at 0x240000. Following a successful network download of all records, the function then, using ramfuncts routines, moves the high flash code down to 0x200000 where myapp normally runs. Following this transfer, the function enters an infinite delay, waiting for the watchdog to fire, which then restarts the new myapp image. This works as long as I am connected using CCS5.4 debug. But, when I disconnect the debug control, myapp stops running. Recycling power does not restart it either. Using the trace would not seem to be helpful as the problem occurs when the debugger is disconnected.

    What am I missing?

    Pat

     

  • Pat Harris said:
    I am using the f28m35h52c1 chip. In my m3 application, I have a routine that collects new m3 image code from a special network that is controlled by the c28 and passed through the IPC. This "network download" function receives myapp.hex file records, converts them to binary, and stores them into high m3 flash memory at 0x240000. Following a successful network download of all records, the function then, using ramfuncts routines, moves the high flash code down to 0x200000 where myapp normally runs. Following this transfer, the function enters an infinite delay, waiting for the watchdog to fire, which then restarts the new myapp image. This works as long as I am connected using CCS5.4 debug. But, when I disconnect the debug control, myapp stops running.

     

    Pat,

    looks like you are missing some variable initializations or RAM funcs copy in the new image that's copied from one sector of flash to another. It works with debugger connected means there is some initialization done in that environment (something available in RAM, function or a an initialized variable) which is not available when running stand alone. What is the new application doing? could you simplify it to just toggle a GPIO - no global variables, no RAMFUNCS...etc - just a simple GPIO toggle and try. You would still need to keep the resetisr and toggle the IO in main.

    if this works then you can rule out that the rest of the application is fine.

    Best Regards

    Santosh

     

     

  • I am using a different approach, trying to duplicate the same failed start up indications that I see when I cycle power after a netword download. I get similar results when I comment out the lines

      // enable serial uart port 0
      SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    In my configuration file. What could that mean?

    Also, when the program completes the transfer from high flash to low flash, I call ResetISR() directly to force a restart. But, this procedure, although appearing to cause the program to run normally, although it fails to output anything from the UART0 that I put into the startup in main(), So, it seems that this failure has something to do with UART0. However, the ResetISR() startup also accesses the UART0 output routine which is simply

    UARTCharPutNonBlocking(UART0_BASE, ucByte);

    but does not hang up. Starting from power-on does cause a hangup which is very similar to the hangup experienced when commenting the config line..

    Any ideas???

    Thanks,

    Pat

     

  • Can anyone define the exact steps that the f28m35h52c1 chip takes during power-on startup and how this differs with a soft reset to ResetISR()?

    Thanks,

    Pat

     

  • Pat Harris said:

    In my configuration file. What could that mean?

    Also, when the program completes the transfer from high flash to low flash, I call ResetISR() directly to force a restart. But, this procedure, although appearing to cause the program to run normally, although it fails to output anything from the UART0 that I put into the startup in main(), S

     

    Pat,

    what is the reason you call ResetISR(), is this the reset entry in boot ROM? why don't you try triggering a WDOG reset and let the device boot through flash (the new one copied)?

     

    Also the device execution after a POR/XRSn or debug reset is documented in the TRM (system control and boot ROM section).

    On M3, if you try to write to a peripheral without enabling the peripheral you will hit a FAULT. Also the application that you are copying and expecting to start - can you use a simple blinky which just toggles an IO, to minimize the scenarios that are causing the error.

     

    I saw you posted another question in a separate thread about _c_int00. This is an RTS library function, if you inspect your map file you will see a .cinit section - all the global variables (initialized) are put in this section and the _c_int00 function in the RTS library executes a loop where it copies the initialization values to the variable addresses, this is needed if your main() routine expect any variable to be zero-initialized or initialized to some constants.

     

    Best Regards

    Santosh

     

  • Santosh,

    I've tried waiting for the WDT, calling ResetISR(), calling _c_int00() - all with the same result.

    I have been focussing on the GEL file actions and have gotten the uart0 functions by adding GEL type initializations to the ResetISR function. I have since added all that I could easily to see if that would help:

    #pragma CODE_SECTION(ResetISR, ".resetisr")

    void

    ResetISR(void)

    {

        //vPortRemapVecterTable();   

        //STOR->stor1 = 0xabff;

        // Jump to the CCS C Initialization Routine.

        // M3_Disable_Flash_ECC();

           *(unsigned short *)0x400FA600 = 0x0; /* Disable Flash ECC */

           // flash activate

    //    int i;

        *(unsigned long *)0x400FA048 = 0x1;

        *(unsigned long *)0x400FA040 = 0x3;

    //    for (i=0; i<10; i++)

    //    {

    //        R1 = 0x00000000;

    //    }

     

        //M3_Ram_Init();

        *(unsigned long *)0x400FB240 |= 0x00000055; /* Initialize C0, C1, C2, C3 RAM's */

        *(unsigned long *)0x400FB260 |= 0x00000001; /* Initialize MtoC MSG RAM's */

        while(*(unsigned long *)0x400FB270 != 0x55);

        while(*(unsigned long *)0x400FB288 != 0x01);

        //watchdog_enable();

        *(unsigned long*)0x400FE100 |= 0x10000008;

        // uart enable

        *(unsigned long*)0x400FE104 |= 0xF;

     

        __asm("    .global _c_int00\n"

              "    b.w     _c_int00\n"

                  "  mov r0,r0\n"            // "nop" for padding to avoid warning message

                  ); // added nop

     

    }

     

    What happens now is that transfer completes and my app runs properly including the uart0 functions. But, when I cycle power or do an on-board reset (XRST), the app will not run  -- UNLESS  --- using CCS debug (which is connectedto this board), I Connect Target AND THEN Disconnect . The disconnect seems to release the chip to run. Do you have any idea why this would occur? Is there any problem with the extra initialization in ResetISR? Does anyone have any idea what else I could do?

    Thanks,

    Pat

     

  • yes this could be problem because of extra inits in reset.

    Resetting through WDT is the right way, calling ResetISR is not good because you will eventually over run the stack or use up large stack or corrupt someone else's stack.

    Are you able to get to use a simple GPIO toggle example as second application? You might want to create a small ppt one slide or simple diagram showing where your first application is - at what address it gets loaded and where the second application gets loaded, at what address. Where this second application is copied to, what is at the flash entry point at the end of this copy , then when you reset what do you expect to happen. Also please show where you place the stack for first application and second application.

    you shouldn't be needing all this code in your reset ISR.

        //vPortRemapVecterTable();   

        //STOR->stor1 = 0xabff;

        // Jump to the CCS C Initialization Routine.

        // M3_Disable_Flash_ECC();

           *(unsigned short *)0x400FA600 = 0x0; /* Disable Flash ECC */

           // flash activate

    //    int i;

        *(unsigned long *)0x400FA048 = 0x1;

        *(unsigned long *)0x400FA040 = 0x3;

    //    for (i=0; i<10; i++)

    //    {

    //        R1 = 0x00000000;

    //    }

     

        //M3_Ram_Init();

        *(unsigned long *)0x400FB240 |= 0x00000055; /* Initialize C0, C1, C2, C3 RAM's */

        *(unsigned long *)0x400FB260 |= 0x00000001; /* Initialize MtoC MSG RAM's */

        while(*(unsigned long *)0x400FB270 != 0x55);

        while(*(unsigned long *)0x400FB288 != 0x01);

        //watchdog_enable();

        *(unsigned long*)0x400FE100 |= 0x10000008;

        // uart enable

        *(unsigned long*)0x400FE104 |= 0xF;

     

     

    Best Regards

    santosh

  • Santosh,

    I am running FreeRTOS in this application. Could that be the problem. I have only two tasks running, one is a 25ms timer and the other is a servicing loop task that uses the timer function to determint the servicing schedule. The RTOS was included in the TI example code that I started with and I continued using it.

    Pat

     

  • Santosh,

    To address your specific questions, for test purposes, I am simply trying to copy the same image over the old one. The app image is first downloaded thru debug. I then use a utility to transfer the .hex version of the image over my communication network. This is my NDL or newtork download vs the Debug Download (DDL). Each hex record is converted to binary and verified before it is stored into high flash memory at 0x240000. I also do a final checksum test on the entire program. It is then copied using ranfuncs from 0x240000 down to the operational area at 0x200000. The transfer copies all data from 0x240000 to the upper end of the code transferred, not just the .hex defined regions. In other words, non programmed sections are also transferred. I then verify via checksum the transferred code. Folowing this I use a while(1) statement to wait for the WDT to fire.

    Should some or all of the WDT functions be placed in ramfuncs?

    Pat

     

  • Also note that if the two images are different, the NDL image does not run after the WDT timeout and reset. If I connect the m3 target and then disconnect, the different image will run. What is actually happening when the debug conects and then disconnects? Is there a detailed explanation somewhere? You stated that the problem could be due some "extra inits in reset". What could these most likely be?

    Thanks,

    Pat

     

  • Pat,

    there are too many things to scope in the failure. We need to simplify the system, can you try to stick to the simple blinky example as the second image that gets copied and expected to start after a reset?

     

    The first image - you said you are downloading using debugger. Does this image run stand alone without any problems?

     

    When the debugger connects, the GEL script functions are run - look for OnTargetConnect, OnReset in your Gel script. Then when you download through debugger the program control is moved to main or the entry point as set up in the debugger options. When you click disconnect the program starts running from the current PC as JTAG HALT is removed now.

     

    Best Regards

    Santosh

     

  • Santosh,

    In my attempt to implement a simple blinky, I found that the example has different sections assignments. This brings up another issue. Could you refresh my memory on how specific sections are assigned specific memory locations?

    .text   :   > FLASH_M |FLASH_L | FLASH_K | FLASH_J | FLASH_I | FLASH_H

        FLASH_M (RX)    : origin = 0x00205000, length = 0x3000 

        FLASH_L (RX)    : origin = 0x00208000, length = 0x4000  

        FLASH_K (RX)    : origin = 0x0020C000, length = 0x4000  

        FLASH_J (RX)    : origin = 0x00210000, length = 0x10000 

        FLASH_I (RX)    : origin = 0x00220000, length = 0x10000

        FLASH_H (RX)    : origin = 0x00230000, length = 0x10000  

    However the actual start of the .text section is at 0x210000. Where would this be assigned and how?

    Thanks

    Pat

     

  • Pat,

    you can control where a particular function gets loaded by creating user specific sections using #PRAGMA CODE_SECTION or #PRAGMA DATA_SECTION directives.

    but in your case you want to load the blinky at some X location and have your first image move the blinky to Y, so that after reset your blinky would run.

    so

    1.> get the blinky flash example linked as it is in the control suite.

    2.> load it to flash and reset and run - is it working?

    3.> once you are confident that it is working, now change the linker command file to have separate LOAD and RUN address for your text segment (including the reset ISR). pick the LOAD address to where your first application would copy the blinky from. Keep the RUN address atleast the reset ISR to what it is at step 1 and 2. The RUN address for the rest of the text segment can be anywhere.

    4.> Now build and use the new blinky as second image in your application.

    Hope it helps...

     

    Best Regards

    santosh

     

  • Santosh,

    Yes the blinky example, which is just a modified main() in my app works. I saved this as a seperate .hex file, then proceeded to use the unmodified app to download it through my network. I then moved it down to low flash. I saved each of the five code segments that the linker.cmd file assigned using the memory save feature of the debugger. I had previously saved the same segments from the modified app so both sets of code should be the same.

    I verified using WinMerge that the only differences were that the NDL version had a couple extra words attached to the end of the code segments.

    When testing the modified app that I downloaded using debug, I would normally need to reset and run using the debugger and the LED would start flashing. Or I could just cycle power and it would also start.

    After downloading over the network, the WDT fires, but the blinky app will not run (doesn't appear to reset). Using debug, I can reset and run blinky normally. IF I cycle power, the app hangs as if it cannot reset just like wdt reset. Using debug, again, resetting, then run, and it will start.

    If I place a while(1); anywhere else in my app prior will cause resets to both the C28 and the CM3 and restart my app properly. But, erasing the flash memory from 0x200000 to 0x220000 and then moving the blinky app there followed by the while(1); delay causes a hangup.

    What do I need to do in my wdt reset to insure that it behaves properly . Do I need all the WDT functions placed into ramfuncs or just certain WDT functions. How do I place these into ranfuncs?

    Thanks,

    Pat

     

     

  • Also, I have LEDs that indicate reset occurances on both the c28 and the m3. During normal power cycle or reset, both leds will flash. If I timeout the wdt anywhere in my program prior to erasing the lower flash, I will get both indicators.

    Following my network download, I force a wait for the WDT, and when it fires, only the c28 reset indicator flashes. I get no indication from the cm3.

    I need to know the specific steps that reset vs wdt reset take and how I can force a true reset in my program. Can anyone help with this? Is this a bug in the Concerto chip? Anyone?

    Thanks,

    Pat

     

  • Pat,

    Thanks for trying to run with blinky, it looks cleaner now.

     

    Looks like the memory where your watchdog functions are loaded by your first app are being erased and reprogrammed with the second app (blinky) in our tests.

    Now while we can go ahead and figure out how to handle the watchdog text sections placement, could you try resetting M3 using NVIC Software reset feature - USING BELOW CODE.

     

        HWREG(SYSCTL_MWRALLOW) =  0xA5A5A5A5;

    //hold C28x under reset

        HWREG(SYSCTL_CRESCNF) &=         ~((0x3& SYSCTL_RES_CNF_MASK) << SYSCTL_RES_CNF_SHIFT);

        // Perform a software reset request.  This will cause the device to reset,     // no further code will be executed.     HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;

     

    once you confirm that after doing above your blinky starts blinking, we will get a better picture on what the error in your system is.

    Best Regards

    Santosh

     

     

  • Santosh,

    I have been unable to test this for awhile due to the fact that all boards stopped working. I had the F28M35H52C1 MCUs replaced and am now trying to get the boards up and running again.

    I am unable to download the c28 side of the project still. Since I believe the MCU is eliminated from being at fault, I am experimenting with the simple dual blinky example and here's what I found. I think this is related to my original problem so I mention it here. It doesn't explain why I cannot download the C28 side of my project, directly.

    This is version V200 of the example list for the F28M35x. When I load the CM3 followed by the C28, reset and run the C28, then the CM3, the example runs with both LED2 and LED3 flashing. When I disconnect the c28 and then the cm3, it continues to run. But if I cycle power, LED2 (C28) stops flashing. LED3 continues to flash.

    It is possible to insert your proposed patch into this example code to see if that would fix this problem? How? Again, this is CCS5.4.

    Thanks,

    Pat

     

     

  • Follow up:

    I don't have the problem with the V140 example dual blinky. The differences seem to be the addition of the HWBistRegsFile. What does this file do?

    Thanks,

    Pat

     

  • Further info:

    The difference is in the map file. The .cmd files are identical. The V200 has the HWBistRegsFile included whereas the V140 does not. I understand that this is a self test feature. How could this be causing the C28 failure to run? What is the work-around for this problem?

    Thanks,

    Pat

  • Pat,

    there is new version of collateral released yesterday, can you try v201 and see if it makes any difference. This might have already been fixed.

    I will also take a look at it with the help of team as soon as possible.

     

    Best Regards

    santosh

  • Santosh,

    Where, exactly should I place this code??

    Placing it in the ResetISR function hangs everything. I can no longer load files, much less run anything. Could you explain where this code goes and what it's function is?

    Thanks,

    Pat

     

  • Santosh,

    Where, exactly should I place this code??

    Placing it in the ResetISR function hangs everything. I can no longer load files, much less run anything. Could you explain where this code goes and what it's function is?

    Once this code in installed, I cannot reprogram the device directly. It appears that I must first load some other program, such as the dual blinky example, then reload my app.

    Thanks,

    Pat

  • Pat,

    I'm sorry - I thought you were saying that the blinky from v200 of device support isn't working. Did you try v201?

     

    could you remind me what you are placing in ResetISR?

     

    Best Regards

    Santosh