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.

AM2631: NOINIT variables and CSS debug

Part Number: AM2631
Other Parts Discussed in Thread: UNIFLASH

Hello,

I'm using an AM2631 device and need help with a few questions.

1) I want to know how to configure startup and linker script to be able to preserve some memory regions from erasing after the soft reset.
2) How to configure memory access breakpoint on write access operation.
3) How flush the cache back into the memory

Regards,
Artem

  • Hi Arterm,

    1. You can create a dedicate section and assign NOINIT type to this output section in linker script: For example:

      .section_noinit:  > OCRAM, type=NOINIT

    A NOINIT section is not C auto-initialized by the linker. It is your responsibility to initialize this section as needed.

    2. Have you tried watchpoint? A watchpoint can be triggered for a particular memory read/write.

        CCS-->Run-->New breakpoint-->Hardware watchpoints

    3. You can call the cache API for cache invalidate:

        CacheP_wbInv(addr, size, CacheP_TYPE_ALL);

    Please refer to SDK API reference:

        https://software-dl.ti.com/mcu-plus-sdk/esd/AM263X/latest/exports/docs/api_guide_am263x/group__KERNEL__DPL__CACHE.html#ga894fcf969b6afb5f30e25861d39c9219

       

  • Thanks for you answers.
    Please clarify is it possible to reflash the external memory using XDS110 and QSPI boot without switching to UART boot mode?

  • Hi Artem,

    You can use UART, or CAN, or JTAG to transfer file from host PC to the flash on EVM. If you want to use UART protocol, the MCU has to be switched to UART bootmode.

  • Thank you.

    I used the JTAG uniflash sbl to flash the program - it worked.

    Another problem I have encountered is that after running system reset or core reset from CSS or running the SOC warm reset API from code then the app won't boot and the PC is actively running on low address regions like 0x3000, and only after the power cycle I can reach the application.

    What causes this issue and how to solve it?

  • Hi Artem,

    I think it is expected. The bootmode is determined by reading the bootstrap pins (SOP[3:0]) during powering-up. 

  • Hello. SOP pins pulled down externally. I expect that should work as QSPI boot mode. What is wrong with software resets?

  • I attached the demo project that you can try to use to reproduce the issue.

    Steps:

    1. Using the SBL QSPI and QSPI boot configuration flash the exmaple into the external flash from offset 0x80000
    2. Run the application and check the output and reset_address variable value
    3. Wait until the application performs the warm reset
    4. Check the output again

    Actual result:
    reset_address variable is getting reset to 0 after software reset

    Expected result:
    reset_address variable is increasing each reset cycle.


    gpio_led_blink_am263x-lp_r5fss0-0_nortos_ti-arm-clang.zip

  • Hi Artem,

    I will do a test with your LED blink code.

  • I expect that should work as QSPI boot mode. What is wrong with software resets?

    The ARM Cortex-R5F processor core starts execution from the reset vector address of 0x00000000 whenever the core gets reset. The exception vector at 0x00000000 is updated to the reset vector of application image after power-cycling, If the content of exception vector is not corrupted (noise, radiation, etc), the CPU reset, SW reset should start the code execution. 

  • I modified the RTI LED blinky example and programmed this example to flash through QSPI SBL as the application image.

    The application image can be started via Power-On reset, SW reset, and nRESET.

    To enable the nRESET pin to control the warm reset, the bit field [2:0] of WARM_RESET_CONFIG register has to be cleared:

        SOC_configureWarmResetSource(0x77777770);//QJ added

    attached is my example:

    /*
     *  Copyright (C) 2022 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <drivers/gpio.h>
    #include <kernel/dpl/AddrTranslateP.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #define LED_ON           (0x01)
    #define LED_OFF          (0x00)
    #define LED_BLINK_COUNT  (10)
    
    
    /*
     * This example configures a GPIO pin connected to an LED on the EVM in
     * output mode.
     * The application toggles the LED on/off using RTI timer.
     */
    
    volatile uint32_t gLedState, gBlinkCount;
    uint32_t gpioBaseAddr, pinNum;
    
    
    volatile uint32_t __attribute__((section(".noinit"))) reset_address; //From Artem
    
    void rti_led_blink(void *args)
    {
        int32_t status = SystemP_SUCCESS;
        uint32_t    delaySec = 2;
        uint32_t rstCause;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        SOC_configureWarmResetSource(0x77777770);//QJ added
        rstCause = SOC_getWarmResetCause(); //QJ
    
        DebugP_log("[RTI LED Blink Test] Starting ...\r\n");
        DebugP_log("reset address %d\r\n", reset_address++); //From Artem
    
        /* Get address after translation translate */
        gpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(GPIO_LED_BASE_ADDR);
        pinNum       = GPIO_LED_PIN;
        gLedState = LED_ON;
        gBlinkCount = 0;
    
        /* Set LED GPIO pin in output mode */
        GPIO_setDirMode(gpioBaseAddr, pinNum, GPIO_LED_DIR);
        /* Set LED GPIO pin HIGH */
        GPIO_pinWriteHigh(gpioBaseAddr, pinNum);
    
        /* Start the RTI counter */
        RTI_counterEnable(CONFIG_RTI0_BASE_ADDR, RTI_TMR_CNT_BLK_INDEX_0);
    
        DebugP_log("[RTI LED Blink Test] Timer Started...\r\n");
    
        /* Wait until the LED is blinked specified number of times */
        while(gBlinkCount < LED_BLINK_COUNT);
    
        /* Stop the RTI counter */
        RTI_counterDisable(CONFIG_RTI0_BASE_ADDR, RTI_TMR_CNT_BLK_INDEX_0);
    
        DebugP_log("[RTI LED Blink Test] Timer Stopped...\r\n");
    
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
    //    Drivers_close();
    
        //added by QJ, 10-6-2023
        CacheP_wbInv(&reset_address, 4, CacheP_TYPE_ALL);
        ClockP_sleep(delaySec);
    
        if(rstCause==0x41){
            DebugP_log("Reset cause: PORRST!\r\n");
            DebugP_log("Generating SW warm reset...\r\n");
            Drivers_close();
            SOC_generateSwWarmReset();
        }else if(rstCause==0x60){
            DebugP_log("Reset cause: SW Reset!\r\n");
            DebugP_log("SW reset was generated successfully!!\r\n");
            Drivers_close();
        }else if(rstCause==0x40){
            DebugP_log("Reset cause: nRESET!\r\n");
            DebugP_log("Generating SW warm reset...\r\n");
            Drivers_close();
            SOC_generateSwWarmReset();
        }
    }
    
    void rtiEvent0(void)
    {
        if(gLedState == LED_ON)
        {
            GPIO_pinWriteLow(gpioBaseAddr, pinNum);
            gLedState = LED_OFF;
        }
        else{
            GPIO_pinWriteHigh(gpioBaseAddr, pinNum);
            gLedState = LED_ON;
        }
        gBlinkCount++;
    }
    

  • Regarding the picture you attached, Are you able to increase reset_address variable on each reset cycle? Please follow the steps to reproduce and refer the main question of this topic

  • Are you able to increase reset_address variable on each reset cycle?

     reset_address isn't increase. This is a different issue.

    My test shows that the application image can start execution via PORRST, nRESET, and SW reset.

  • The ROM code executes only on initial power up (POR) or power-on reset. On subsequent (warm) resets, the reset vector base address will point to run-time loaded code (the SBL).

    The example OSPI SBL initializes the TCMA/B and L2OSRAM bank 2 and bank 3.

  • My test shows that the warm reset itself cleans the content of SRAM.

  • Hi Artem,

    The first 1MB OCSRAM (bank0 and bank1) is initialized by ROM code. The 2nd 1MB region (bank2 and bank3) is initialized by OSPI SBL. I will check if we can use the unused peripheral RAM (for example MCAN RAM) to preserve a variable from initialization during warm reset. 

  • Unlike TMS570 device, the AM263x peripheral RAMs are also initialized after a SW warm reset.

  • Hi Artem,

    My suggestion is to write the "reset_address" to flash instead of SRAM. 

    or

    You can modify the SBL to only initialize the one bank of OCSRAM (for example bank 2 or bank 3), then you store "set_address" to the un-initialized bank of OCSRAM.

    From functional safety perspective, I prefer storing the variable to flash to avoid being cleaned by device's reset.

  • Hello,

    We can't store anything in flash memory due to design limitations.
    The reset address is captured from the exception context, such as a hard_fault handler, so the only way to store it is in RAM or any system register that is not cleared on reset.

    Several questions needs your clarification:

    Is it possible not to initialize OCSRAM regions in SBL, or why its required to initialize them?

    Why breakpoints are getting cleared after software reset?

    Should we override the vector table by application reset handler to prevent SBL from being executed on reset?

  • Is it possible not to initialize OCSRAM regions in SBL, or why its required to initialize them?

    The SBL initializes the TCMA, TCMB, and bank2 and bank3 of OCSRAM. It is possible not to initialize bank (2 or 3) or banks (2 and 3) of OCSRAM (after warm reset).

    The intent of having the hardware initialization is to program the memory arrays with error detection capability to a known state based on their error detection scheme – ECC. For example, the contents of the OCSRAM after power-on reset is unknown. A hardware auto-initialization can be started so that there is no ECC error.

    Why breakpoints are getting cleared after software reset?

    As stated in TRM, all IO configurations are reset during warm reset assertion, and after reset is de-asserted, device will boot-up, and application will be reloaded to OCSRAM, and breakpoints should not be kept.

    Should we override the vector table by application reset handler to prevent SBL from being executed on reset?

    The exception vector or reset vector of the application image is copied to 0x00000000 by SBL during boot.