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.

CC2642R: How to use noinit to define variables in CC2642

Part Number: CC2642R

Tool/software:

HI,

C2642 chip, I use IAR environment and define variables using noinit. Before software reset, I assigned userResetReason a value of 1234. Why is this variable still 0 after reset. I often try the following three methods but none of them work.

//uint32_t userResetReason __attribute__ ((section (".noinit")));  

//__no_init uint32_t userResetReason;
uint32_t userResetReason __attribute__ ((retain, noinit));



IAR 9.32.1
sdk:simplelink_cc13xx_cc26xx_sdk_7_10_01_24
  • Hi,

    The attribute "retain" means that variable should be included in the final build. This prevents cases where the compiler might remove a variable if it is not referenced by any of the code.

    The attribute "noinit" means the compiler will not initialize that variable when the program starts. So it may contain an unknown value until it is assigned by the program.

    (By the way, here is a good resource for detailing the attributes: https://software-dl.ti.com/codegen/docs/tiarmclang/rel2_1_0_LTS/migration_guide/migrating_c_and_cpp_source/pragmas_and_attributes.html )

    It seems you want to save a value even after it a device reset.
    The variable you have here, userResetReason, is very likely placed in RAM, so its value will not persist across a reset.
    To persist across a reset, the variable must be placed in flash. For a reference of this, try building the nvsinternal example: https://dev.ti.com/tirex/explore/node?node=A__ANuUJDdHffNrvt7.ckoWLg__com.ti.SIMPLELINK_CC13XX_CC26XX_SDK__BSEc4rl__LATEST 

    This example shows concept of allocation non-volatile storage in device internal flash, including initialization and reading/writing to it.
    Same concept would apply in your case.
    "Reading" can technically happen as with normal c, e.g. uint32_t ramVar_u32 = flashVar_u32.
    "Writing" can only happen with the flash API (flash.h --> FlashProgram).

    Thanks,
    Toby

  • Hi,

    I don't want to put it into FLASH for storage if I can because it will operate the LASH frequently. i see the docs use __attribute__((noinit)), defined in the following way, and after a reset through the software it still has a value of 0. Is there something else i need to do with the IAR for the configuration.

    __attribute__((noinit)) uint32_t userResetReason;
    userResetReason = 1234;
    SystemReset();

  • I see now that document is for ticlang compiler, it might look different in IAR.

    From the IAR Development Guide (wwwfiles.iar.com/.../EWARM_DevelopmentGuide.ENU.pdf), see "Examples of placing variables in named sections".

    It offers other ways for variable placement, such as:

    __no_init int alpha @ "MY_NOINIT"; /* OK */

    #pragma location="MY_CONSTANTS"
    const int beta = 42; /* OK */
    

    const int gamma @ "MY_CONSTANTS" = 17; /* OK */
    int theta @ "MY_ZEROS"; /* OK */
    int phi @ "MY_INITED" = 4711; /* OK */

    Then in the linker file (.icf), the relevant section which that variable is placed must have directive of "do not initialize".
    An example of this is in the empty example's cc13x2_cc26x2_freertos.icf (C:\ti\simplelink_cc13xx_cc26xx_sdk_7_40_00_77\examples\rtos\CC26X2R1_LAUNCHXL\drivers\empty\freertos\iar).
    It has: do not initialize { section .stack, section .noinit};

    Other examples include (from IAR Development Guide):

    __no_init volatile char alpha @ 0xFF2000;/* OK */

  • HI,

    I used the project C:\ti\simplelink_cc13xx_cc26xx_sdk_7_40_00_77\examples\rtos\CC26X2R1_LAUNCHXL\drivers\empty and modified the file as follows, and the alpha is still 0 after calling the software reset.

    /*
     * Copyright (c) 2015-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
    
    /*
     *  ======== empty.c ========
     */
    
    /* For usleep() */
    #include <unistd.h>
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    // #include <ti/drivers/I2C.h>
    // #include <ti/drivers/SPI.h>
    // #include <ti/drivers/Watchdog.h>
    
    /* Driver configuration */
    
    #include "ti_drivers_config.h"
    #include <ti/display/Display.h>
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(inc/hw_ccfg.h)
    #include DeviceFamily_constructPath(inc/hw_ccfg_simple_struct.h)
    #include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
    
    Display_Handle dispHandle = NULL;
    
    
    //__no_init int alpha @ "MY_NOINIT"; 
    __no_init volatile char alpha;/* OK */
    //uint32_t alpha __attribute__ ((section (".noinit")));
    
    
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
      
        dispHandle = Display_open(Display_Type_ANY, NULL);
        Display_printf(dispHandle, 0, 0, "====================:%d",alpha);
      
        /* 1 second delay */
        uint32_t time = 1;
    
        /* Call driver init functions */
        GPIO_init();
        // I2C_init();
        // SPI_init();
        // Watchdog_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Turn on user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        while (1)
        {
            sleep(time);
            GPIO_toggle(CONFIG_GPIO_LED_0);
            
            alpha = 123;
            SysCtrlSystemReset();
        }
    }
    

  • It seems you are declaring it correctly, but still see it initialized to 0...I'd recommend reaching out to IAR about it, along with your most recent code snippet.

    Before software reset, I assigned userResetReason a value of 1234. Why is this variable still 0 after reset. I often try the following three methods but none of them work.

    Going back to your original question, userResetReason is placed in RAM, so if any value it's set to before a reset will NOT be retained after a reset.
    In your example, you have this sequence:

    1. userResetReason = 1234;
    2. reset
    3. temp = userResetReason

    At step 3, temp will not have the value 1234.