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.

TMS570LC4357: software reset reinitializes RAM

Part Number: TMS570LC4357

Hi all,

I'm developing a bootloader for TMS570LC4357.

At the moment I have a working bootloader that allows me to write flash memory and an application.

When switching on the bootloader has to start, it has to recognize that a poweron reset has occured and jump to the application.

The application while running has to set a RAM variable to jump to the bootloader; this variable resides into a shared RAm between the bootloader and the application.

The jump from the application to the boot is done setting : systemREG1->SYSECR = 0x8000;

The problem is: this reset is not recognized as a sowtware reset but as a "NO_RESET"; this causes a RAM initialization that deletes the information stored into the shared RAM; as a consequence the bootloader will jump back to the application.

How is it possible to avoid the RAM initialization?

I did this following this thread: 

Any help will be appreciated.

Thanks

Valentina

  • An additional info: after the reset looking at the register SYS_ECR I see 0x00004000 and looking at SYS_ESR I see 0x00000010
  • Which register are you checking when going through reset to determine if the SW reset has occurred? You should be checking the SYSESR which from your prior post is showing the bit set indicating a SWRST (bit 4 of SYSESR). This should be sufficient to allow retaining RAM and entering the appropriate execution path.

    the SYSECR register is only provided to initiate the SW reset it is not intended as a status register. So, even though you write a 1 to bit 15 or a 0 to bit 14 to trigger a SW reset when you read back the SYSECR you will read a value of 0x4000.
  • Hello Mr. Davenport,

    thank you for the quick reply. 

    To determine the sw reset I'm looking at SYSESR and it is showing the right value. By the way I run some more tests and here is what I noticed.

    The application has to:

     - receive a defined SPI message

     - write a defined value into a RAM address

     - check the RAM address and eventually jump to the bootloader.

    When I run this test sending the SPI message I see the jump to the bootloader but immediatly it switches back to the application.

    On the other hand if, using the IDE CCS 7.1, I manually write the same value into the RAM address while running the application, it jumps to the bootloader and stays there (as I want).

    Is there any explanation for this behaviour? Does it have something to do with SPI message? I can't figure what is different in the two cases since the RAM is reinitialized in one case.

    Following the startup code inside the bootloader (if it can help):

    void _c_int00(void)
    {
    
    /* USER CODE BEGIN (5) */
    /* USER CODE END */
    
        /* Initialize Core Registers to avoid CCM Error */
        _coreInitRegisters_();
    	
        /* Initialize Stack Pointers */
        _coreInitStackPointer_();
    
        /* Reset handler: the following instructions read from the system exception status register
         * to identify the cause of the CPU reset.
         */
        switch(getResetSource())
        {
            case POWERON_RESET:
            case DEBUG_RESET:
            case EXT_RESET:
    
    /* USER CODE BEGIN (6) */
    /* USER CODE END */
    
            /* Initialize L2RAM to avoid ECC errors right after power on */
            _memInit_();
    
    /* USER CODE BEGIN (7) */
    /* USER CODE END */
    
    /* USER CODE BEGIN (8) */
    /* USER CODE END */
    
    
    /* USER CODE BEGIN (9) */
    /* USER CODE END */
    
            /* Enable CPU Event Export */
            /* This allows the CPU to signal any single-bit or double-bit errors detected
             * by its ECC logic for accesses to program flash or data RAM.
             */
            _coreEnableEventBusExport_();
    
    /* USER CODE BEGIN (10) */
    /* USER CODE END */
    
            /* Check if there were ESM group3 errors during power-up.
             * These could occur during eFuse auto-load or during reads from flash OTP
             * during power-up. Device operation is not reliable and not recommended
             * in this case. */
            if ((esmREG->SR1[2]) != 0U)
            {
               esmGroup3Notification(esmREG,esmREG->SR1[2]);               
            }
    	
            /* Initialize System - Clock, Flash settings with Efuse self check */
            systemInit();
    
    /* USER CODE BEGIN (11) */
    /* USER CODE END */
    
            /* Enable IRQ offset via Vic controller */
            _coreEnableIrqVicOffset_();
                
            /* Initialize VIM table */
    	    vimInit();
    
    /* USER CODE BEGIN (12) */
    /* USER CODE END */
            /* Configure system response to error conditions signaled to the ESM group1 */
            /* This function can be configured from the ESM tab of HALCoGen */
            esmInit();
    
    /* USER CODE BEGIN (13) */
    /* USER CODE END */
    
            break;
    
            case OSC_FAILURE_RESET:
    /* USER CODE BEGIN (14) */
    /* USER CODE END */
            break;
    		
            case WATCHDOG_RESET:
            case WATCHDOG2_RESET:
    /* USER CODE BEGIN (15) */
    /* USER CODE END */
            break;
        
            case CPU0_RESET:
    /* USER CODE BEGIN (16) */
    /* USER CODE END */
    
    /* USER CODE BEGIN (17) */
    /* USER CODE END */
    		
    /* USER CODE BEGIN (18) */
    /* USER CODE END */
    
            /* Enable CPU Event Export */
            /* This allows the CPU to signal any single-bit or double-bit errors detected
             * by its ECC logic for accesses to program flash or data RAM.
             */
            _coreEnableEventBusExport_();
    		
    /* USER CODE BEGIN (19) */
    /* USER CODE END */
            break;
        
            case SW_RESET:
            case NO_RESET:
    /* USER CODE BEGIN (20) */
                _coreEnableEventBusExport_();
                systemInit();
                _coreEnableIrqVicOffset_();
                vimInit();
                esmInit();
    /* USER CODE END */
            break;
        
            default:
    /* USER CODE BEGIN (21) */
    /* USER CODE END */
            break;
        }
    
    /* USER CODE BEGIN (22) */
    /* USER CODE END */
    
        _mpuInit_();
    	
    /* USER CODE BEGIN (23) */
    /* USER CODE END */
    
        _cacheEnable_(); 
    
    /* USER CODE BEGIN (24) */
    /* USER CODE END */
    
    
    /* USER CODE BEGIN (25) */
    /* USER CODE END */
    
            /* initialize global variable and constructors */
       __TI_auto_init();
    
    /* USER CODE BEGIN (26) */
    /* USER CODE END */
        
            /* call the application */
    /*SAFETYMCUSW 296 S MR:8.6 <APPROVED> "Startup code(library functions at block scope)" */
    /*SAFETYMCUSW 326 S MR:8.2 <APPROVED> "Startup code(Declaration for main in library)" */
    /*SAFETYMCUSW 60 D MR:8.8 <APPROVED> "Startup code(Declaration for main in library;Only doing an extern for the same)" */
        main();
    /* USER CODE BEGIN (27) */
    /* USER CODE END */
    /*SAFETYMCUSW 122 S MR:20.11 <APPROVED> "Startup code(exit and abort need to be present)" */
        exit(0);
    
    
    /* USER CODE BEGIN (28) */
    /* USER CODE END */
    
    }
    

    Besides I also changed the getResetSource() function as follows because it always ended up into External reset:

    resetSource_t getResetSource(void)
    {
        register resetSource_t rst_source;
    
        if ((SYS_EXCEPTION & (uint32)POWERON_RESET) != 0U)
        {
            /* power-on reset condition */
            rst_source = POWERON_RESET;
    
            /* Clear all exception status Flag and proceed since it's power up */
            SYS_EXCEPTION = 0x0000FFFFU;
        }
       // else if ((SYS_EXCEPTION & (uint32)EXT_RESET) != 0U)
     //   {
            /* Reset caused due to External reset. */
       //     rst_source = EXT_RESET;
       //     SYS_EXCEPTION = (uint32)EXT_RESET;
       // }
        else if ((SYS_EXCEPTION & (uint32)DEBUG_RESET) !=0U)
        {
            /* Reset caused due Debug reset request */
            rst_source = DEBUG_RESET;
            SYS_EXCEPTION = (uint32)DEBUG_RESET;
        }
        else if ((SYS_EXCEPTION & (uint32)OSC_FAILURE_RESET) != 0U)
        {
         /* Reset caused due to oscillator failure.
            Add user code here to handle oscillator failure */
            rst_source = OSC_FAILURE_RESET;
            SYS_EXCEPTION = (uint32)OSC_FAILURE_RESET;
        }
        else if ((SYS_EXCEPTION & (uint32)WATCHDOG_RESET) !=0U)
        {
            /* Reset caused due watchdog violation */
            rst_source = WATCHDOG_RESET;
            SYS_EXCEPTION = (uint32)WATCHDOG_RESET;
        }
        else if ((SYS_EXCEPTION & (uint32)WATCHDOG2_RESET) !=0U)
        {
            /* Reset caused due watchdog violation */
            rst_source = WATCHDOG2_RESET;
            SYS_EXCEPTION = (uint32)WATCHDOG2_RESET;
        }
        else if ((SYS_EXCEPTION & (uint32)CPU0_RESET) !=0U)
        {
            /* Reset caused due to CPU0 reset.
            CPU reset can be caused by CPU self-test completion, or
            by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
            rst_source = CPU0_RESET;
            SYS_EXCEPTION = (uint32)CPU0_RESET;
        }
        else if ((SYS_EXCEPTION & (uint32)SW_RESET) != 0U)
        {
            /* Reset caused due to software reset. */
            rst_source = SW_RESET;
            SYS_EXCEPTION = (uint32)SW_RESET;
        }
        else
        {
            /* No_reset occured. */
            rst_source = NO_RESET;
        }
    
        return rst_source;
    }

    Thank you for your attention.

  • Hello Valentina,

    I apologize for the delay in getting back to you as I had been pulled away for a bit. I will review your code and get back to you on Monday with any findings or additional questions/suggestions.
  • Hello Valentina,

    MY apologies for the delay in getting back to you, but I think the issue here is multiple bits in the SYSESR register being set. Note that teh EXT_RST is asserted for most resets see the description below from the TRM:

    This combined with the structure of the code in the getResetSource() function, will result in the first exception bit tested during the if-else if structure of code. Because of this and the special case/use of SW reset, you may need to make adjustments in the getResetSource() function by putting the test for EXT_RST to the last test in the series of if- if else statements. 

    Note, my original thought was to remove the else if statements and make them all simple if statement blocks but this would result in a return value with the potential for multiple reset bits being set and cause the switch-case architecture to break. My suggestion is to re-arrange the test of bits in the getResetSource() function to suit your needs and required priority for your project.

  • Hello Valentina,

    I have given this some more thought and the code update to  getResetSource would probably make more since and provide the correct return value for your application.

    resetSource_t getResetSource(void)
    {
        register resetSource_t rst_source;
    
        if ((SYS_EXCEPTION & (uint32)POWERON_RESET) != 0U)
        {
            /* power-on reset condition */
            rst_source = POWERON_RESET;
    
            /* Clear all exception status Flag and proceed since it's power up */
            SYS_EXCEPTION = 0x0000FFFFU;
        }
        else if ((SYS_EXCEPTION & (uint32)EXT_RESET) != 0U)
        {
               /* Reset caused due to External reset. */
               rst_source = EXT_RESET;
               SYS_EXCEPTION = (uint32)EXT_RESET;
    
               /*** Check for other causes of EXT_RESET that would take precedence  **/    

    if ((SYS_EXCEPTION & (uint32)OSC_FAILURE_RESET) != 0U) { /* Reset caused due to oscillator failure. Add user code here to handle oscillator failure */ rst_source = OSC_FAILURE_RESET; SYS_EXCEPTION = (uint32)OSC_FAILURE_RESET;
    } else if ((SYS_EXCEPTION & (uint32)WATCHDOG_RESET) !=0U) { /* Reset caused due watchdog violation */ rst_source = WATCHDOG_RESET; SYS_EXCEPTION = (uint32)WATCHDOG_RESET; } else if ((SYS_EXCEPTION & (uint32)WATCHDOG2_RESET) !=0U) { /* Reset caused due watchdog violation */ rst_source = WATCHDOG2_RESET; SYS_EXCEPTION = (uint32)WATCHDOG2_RESET; } else if ((SYS_EXCEPTION & (uint32)SW_RESET) != 0U) { /* Reset caused due to software reset. */ rst_source = SW_RESET; SYS_EXCEPTION = (uint32)SW_RESET; } } else if ((SYS_EXCEPTION & (uint32)DEBUG_RESET) !=0U) { /* Reset caused due Debug reset request */ rst_source = DEBUG_RESET; SYS_EXCEPTION = (uint32)DEBUG_RESET; } else if ((SYS_EXCEPTION & (uint32)CPU0_RESET) !=0U) { /* Reset caused due to CPU0 reset. CPU reset can be caused by CPU self-test completion, or by toggling the "CPU RESET" bit of the CPU Reset Control Register. */ rst_source = CPU0_RESET; SYS_EXCEPTION = (uint32)CPU0_RESET; } else { /* No_reset occured. */ rst_source = NO_RESET; } return rst_source; }

    Check my logic here, but I think this should work for you.

  • Hello Chuck,

    thanks for your replies.

    Unfortunately I was in rush with this project so I had to overcome the RAM problem using an hw pin. But your explanation makes sense and as soon as I have time I'll test the suggested code.

    Thanks for your help.