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.

LAUNCHXL-F280049C: Compiler not linking Boolean struct member state between C modules.

Guru 56093 points
Part Number: LAUNCHXL-F280049C
Other Parts Discussed in Thread: UNIFLASH

Hello,

Follow up of unanswered question why the compiler fails to link the Boolean state of struct members between all C modules in the build. Even if using pointers to the members of a struct such a obj->flagEnableRunAndIdentify the compiler is not linking the Boolean state changes of several struct members defined as Boolean type in universal Motor Control Suite. There is a disassociated orphaned symbolic link between identical named symbols between C modules in the project build without a single compiler warning.

What compiler or linker settings could cause this odd behavior in TI 22.6.0.LTS CCS v13.3?

Here are the compiler switches made no difference: --gen_func_subsections=on --gen_data_subsections=on.

Oddly the inverter DC bus voltage ADC data can only be read from obj->estInputData.Iab_A.value[1] rather than motorVars_M1.adcData.VdcBus_V which shows up in CCS debug Expressions +24vdc. So this indicates to me the compiler is not associating symbols with state changes in the CPU instruction decode between parent and children modules of the project build.

 These struct member Boolean flags fail to detect or change state between parent and child C modules: (motorVars_M1.flagEnableRunAndIdentify), (motorVarssystemVars.flagEnableSystem), (motorVarsmotorVars_M1.flagEnableMotorIdentify) etc. Struct member Boolean flags do not work when testing the Boolean state in any other C module added to the project build.

When the Boolean state is changed in the parent C module the children C modules have no link connection to the state changes of the parent that asserted the state change.

  • What compiler or linker settings could cause this odd behavior in TI 22.6.0.LTS CCS v13.3?

    Can you provide the codes you used for this? Any changes you made in the example labs?

  • Hi Yanming,

    You can verify the Boolean flags only work when added to sys_main.c in forever loop. Set false should stop motor from running in debug but does not when asserted in any added module functions. It seems only the systemVars.flagEnableSystem flag is now working after moving motor_data pragma to RAMM0_1.

    The control flags are being ignored in any added C file to test or force bool state changes. Adding the object ( MOTOR_Vars_t *obj = (MOTOR_Vars_t *)motorHandle_M1;) to a functions declarations of any added C files or testing the bool flag via motorVars_M1 either case fails to return the actual bool state of these flags from the asserted bool flags in motor1_drive.c during debug or Boot from flash. 

    f28004x_flash_cpu_is_eabi.cmd:

       GROUP
       {
          user_data
    	  foc_data
    	  motor_data
       }
       		LOAD = RAMM0_1
            LOAD_START(ctrlVarsLoadStart),
            LOAD_SIZE(ctrlVarsLoadSize),
            LOAD_END(ctrlVarsLoadEnd)
    

    Added C module control function via Boolean flags works great SDK but not in MCSDK. 

    void
    Print_vars(void)
    {
        MOTOR_Vars_t *obj = (MOTOR_Vars_t *)motorHandle_M1;
        
        static bool SetFlag = false;
        static bool ClearFlag = true;
      
       /* Check motor is online running */
        if((obj->flagEnableRunAndIdentify == true) && (systemVars.flagEnableSystem == true)) //(obj->flagRunIdentAndOnLine == true))
        {
        	/* Reset flags each run time */
        	ClearFlag = false;
        	SetFlag = false;
    
        	/* Just return saving parameters */
            if(bParamSave == 0)
            {
                return;
            }
        }
        else if(systemVars.flagEnableSystem == true)
        {
            /* Indicate OFC Button blue LED offsetCalc has ended */
            //motorVars_M1.flagEnableOffsetCalc == 0 &&
           if(obj->flagEnableRunAndIdentify == false)
           {
               /* Enable Global Blue LED indicator */
               NexSendCmd("vis n13,1", 0, 0, 0);
               NexSendCmd("vis p11,0", 0, 0, 0);
           }
    
            /* Turn on Stop and off Start LED */
            NexSendCmd("vis p10,1", 0, 0, 0);//stop
            NexSendCmd("vis n12,0", 0, 0, 0);//start
    
            //
        	ClearFlag = true;
    		SetFlag = true;
        }

  • Can you try to define the variables as global variable without static?

    bool SetFlag = false;
    bool ClearFlag = true;

  • Those two are not a problem in SDK 4.01. As stated, added custom C modules cannot start or stop the motor, e.g. enable/disable any of the struct (MOTOR_Vars_t_) defined bool flags loaded to seemingly flash memory (.const string motor1_drive.obj). Also tested there is no custom module control of state machine flags for the motor ID process or to set other FAST/eSMO estimator modes. I have past seen where a volatile warning can be missed by the compiler. Though I believe it was the tag key missing (volatile) keyword. I try to move the global extern to where the struct is defined (motor_common,h) causes not allowed warning.

    I see a pattern here where #pragma in data section (motor_data) is not linked to the flash loaded controls of some struct members. And debug XDS110 emulator can find Boolean flags by symbolic reference but not custom functions not using debug or the emulator *.out file. 

    motor1_drive.c/obj: RAMM0_1

     volatile MOTOR_Vars_t motorVars_M1;
    #pragma DATA_SECTION(motorVars_M1, "motor_data");

    motor1_drive.h: extern volatile MOTOR_Vars_t motorVars_M1;

    motor_common.h:

    //! \brief Defines the MOTOR_Vars_t handle
    //!
    typedef struct _MOTOR_Vars_t_ *MOTOR_Handle;

    bool flagEnableMotorIdentify;

    bool flagEnableRsRecalc;
    bool flagEnablePowerWarp;
    bool flagBypassLockRotor;
    bool flagEnableRsOnLine;
    bool flagStartRsOnLine;
    bool flagRsOnLineContinue;
    #endif // MOTOR1_FAST

    bool flagEnableRestart;
    bool flagEnableRunAndIdentify;
    bool flagRunIdentAndOnLine;
    bool flagMotorIdentified;
    bool flagEnableForceAngle;
    bool flagEnableOffsetCalc;
    bool flagEnableAlignment;

    bool flagSetupController;
    bool flagEnableSpeedCtrl;
    bool flagEnableCurrentCtrl;

    bool flagEnableFlyingStart;
    bool flagStateFlyingStart;
    bool flagEnableBraking;

    bool flagEnableIPD;
    bool flagEnableFWC;
    bool flagEnableMTPA;
    bool flagUpdateMTPAParams;

    bool flagClearFaults;
    bool flagVIrmsCal;

    bool enableSpeedCtrl;
    bool enableCurrentCtrl;
    }MOTOR_Vars_t;

  • I see a pattern here where #pragma in data section (motor_data) is not linked to the flash loaded controls of some struct members. And debug XDS110 emulator can find Boolean flags by symbolic reference but not custom functions not using debug or the emulator *.out file.

    What do you mean this? Which boolean variable do you use in this struct object?

  • What do you mean this? Which boolean variable do you use in this struct object?

    Any of the Boolean flags do not work from added custom C modules. The bool flags only work via XDS110 emulator and debug simulator as they should. The flash #prama is being mcopy() to either LSRAM, GSRAM or CPU shared RAM does not make any difference what memory it is copied into. These bool flags state changes are not being linked in the added C file, only the symbol name is being linked but not the logic state changes. 

    Oddly even when CCS debug loads the firmware upon exit the same bool flags fail in the custom C modules during and after debug exit. Same thing occurs after UniFlash firmware loads, seems the symbol names are present but logic state is not linked to the MCSDK project modules that use the same bool symbols. Could it be that using the *.out file versus *.bin file in the build is causing such mayhem?

    BTW: I moved the SDK4.01 MOTOR_Vars_t  struct (labs.h) and #pragma to (labs.c). Perhaps why the Boolean flags are being linked to the custom C module in that project. So the motor_common.h (MOTOR_Vars_t ) above moved into motor_common.c to match SDK Boolean logic. I can't recall if the custom C module had the same issues before moving the motorVars struct, though I don't think it did.

  • Any of the Boolean flags do not work from added custom C modules.

    How do you add the Boolean flags? Where the Boolean flags will be used? 

    The flash #prama is being mcopy() to either LSRAM, GSRAM or CPU shared RAM does not make any difference what memory it is copied into.

    The DATA_SECTION pragma allocates space for the symbol in a section named section name. This pragma is useful if you have data objects that you want to link into an area separate from the .ebss or .bss section. The DATA_SECTION pragma is only for the variables defined in RAM, not in Flash that don't need to be copied for Flash to RAM by calling mcopy.

    The CODE_SECTION pragma allocates space for the symbol/code in a section named section name. The CODE_SECTION pragma is useful if you have code objects that you want to link into an area separate from the .text section.

  • How do you add the Boolean flags? Where the Boolean flags will be used?

    Not by pragma Data or Code sections in the custom C module where MOTOR_Vars_t  struct Boolean flags do not work. The Boolean flags MOTOR_Vars_t struct do Not change state globally when directed. Why do the Boolean flags work globally when moved into C file in the SDK seems to be the question.

    Methods that do not control bool state changes globally or state changes from CCS debug:

    motor1_drive.c: volatile MOTOR_Handle motorHandle_M1;
                             #pragma DATA_SECTION(motorHandle_M1,"motor_data");

    motor1_drive.c: volatile MOTOR_Vars_t motorVars_M1;
                             #pragma DATA_SECTION(motorVars_M1, "motor_data");

     MOTOR_Vars_t *obj = (MOTOR_Vars_t *)motorHandle_M1; 

    motorVars_M1.flagEnableRunAndIdentify = true;

    obj->flagEnableRunAndIdentify = true

    if(obj->flagEnableRunAndIdentify == true)

    if(motorVars_M1.flagEnableRunAndIdentify == true)

  • It's difficult to repeat the issue you met. You may have to share the project you change with us.

  • Admit it is puzzling why the SDK works ok but the MCSDK does not. I can PM the archived project, though it uses 3.5" LCD screen via SCIB. With UMCDSK the boot LCD shows real time DC bus voltage, motor amps scope signals, oddly not the watts signal the SDK with same code does very well. 

  • As mentioned above. Please share the project or post the changes you made in the example project. We can have a test to find the issue.