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.

TMS320F280039C: Possible for CCS to monitor if a bit inside an uint16_t is changed during runtime

Part Number: TMS320F280039C
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hi champs,

I am asking this for our customer.

The user uses bit-field based structure for their flag usage.

Now, they want to know if a bit inside an uint16_t variable is changed or not during runtime.

Is it possible for CCS to monitor if a bit inside an uint16_t variable is changed during runtime?

The challenge here is the other 15 bits of the same unit16_t variable can be changed.

The user tried to use CCS hardware watchpoint to monitor the variable, but it will break as along as any bit of the variable is changed.

The user wants to monitor bit 4 of the variable only.

Or do you have any other suggestion?

  • Hi Wayne,

    Conditional Breakpoints can be used to have the BP trigger when (var ^ PreviousValue) & 0x0010 or some similar statement.

    Customer could also create variables that logs the previous and current values of the fourth bit and have some simple logic to check it that way. 

    I'll loop in the CCS experts for further confirmation. 

    Best Regards,

    Aishwarya

  • The user tried to use CCS hardware watchpoint to monitor the variable, but it will break as along as any bit of the variable is changed.

    F280039C watchpoints support specifying a Data Mask:

    The data mask can be used to filter or mask the bits of the data being watched, so that only specific bits or patterns of bits trigger the watchpoint.

    Thanks

    ki

  • Hi Ki,

    Let me check again.

    Their definition is like this (almost same as our bit-field codes) below.

     

    struct ADCCTL1_BITS {           // bits  description
        Uint16  TEMPCONV:1;         // 0     Temperature sensor connection
        Uint16  VREFLOCONV:1;       // 1     VSSA connection
        Uint16  INTPULSEPOS:1;      // 2     INT pulse generation control
        Uint16  ADCREFSEL:1;        // 3     Internal/external reference select
        Uint16  rsvd1:1;            // 4     reserved
        Uint16  ADCREFPWD:1;        // 5     Reference buffers powerdown
        Uint16  ADCBGPWD:1;         // 6     ADC bandgap powerdown
        Uint16  ADCPWDN:1;          // 7     ADC powerdown
       Uint16  ADCBSYCHN:5;        // 12:8  ADC busy on a channel
        Uint16  ADCBSY:1;           // 13    ADC busy signal
        Uint16  ADCENABLE:1;        // 14    ADC enable
        Uint16  RESET:1;            // 15    ADC master reset
    };
    
    union ADCCTL1_REG {
        Uint16                all;
        struct ADCCTL1_BITS   bit;
    };
    

    Now, we want to monitor a bit, say bit 0, TEMPCONV here.

    Then, we can use a watchpoint with its mask.

    1 means to mask it (block it) and 0 means to allow it.

    So, if we only want to observe bit 0, we should use data mask as FFFE.

    In this way, even if other bits are changed bit1-15, they are ignored.

    Only change in bit 0 can be triggered.

    Is our understanding correct?

  • So, if we only want to observe bit 0, we should use data mask as FFFE.

    If you want to ignore changed to bits 1-15 and only trigger on a change to bit 0, then you should use a data mask value of 0x1

  • Hi Ki,

    It seems something wrong in our testing.

    The user uses

    C:\ti\c2000\C2000Ware_5_04_00_00\driverlib\f28003x\examples\led

    And only modified led_ex1_blinky.c as below.

    //#############################################################################
    //
    // FILE:   main.c
    //
    // TITLE:  Universal LED Project
    //
    // Universal LED Project Example
    //
    // This example demonstrates how to blink an LED using the **Universal Project**.
    // In order to migrate the project within syscfg, click the swtich button under 
    // the device view and select your corresponding device to migrate, saving the
    // project will auto-migrate your project settings.
    //!
    //!  \note This example project has support for migration across our C2000 
    //!  device families. If you are wanting to build this project from launchpad
    //!  or controlCARD, please specify in the .syscfg file the board you're using.
    //!  At any time you can select another device to migrate this example.
    //
    //#############################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
    //
    // 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.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    #include "c2000ware_libraries.h"
    
    typedef struct BitFieldReg {           // bits  description
        uint16_t  bit0:1;
        uint16_t  bit1:1;
        uint16_t  bit2:1;
        uint16_t  bit3:1;
        uint16_t  bit4:1;
        uint16_t  bit5:1;
        uint16_t  bit6:1;
        uint16_t  bit7:1;
        uint16_t  bit8:1;
        uint16_t  bit9:1;
        uint16_t  bit10:1;
        uint16_t  bit11:1;
        uint16_t  bit12:1;
        uint16_t  bit13:1;
        uint16_t  bit14:1;
        uint16_t  bit15:1;
    }   BitFieldReg;
    
    typedef union BitFieldRegType {
        uint16_t            all;
        BitFieldReg         bit;
    } BitFieldRegType;
    
    BitFieldRegType BitFieldRegType_Inst1;
    BitFieldRegType *BitFieldRegType_pt1;
    
    
    // Main
    //
    void main(void)
    {
    
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pull-ups.
        //
        Device_initGPIO();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        //
        // PinMux and Peripheral Initialization
        //
        Board_init();
    
        //
        // C2000Ware Library initialization
        //
        C2000Ware_libraries_init();
    
        //
        // Enable Global Interrupt (INTM) and real time interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop Forever
        //
        for(;;)
        {
            //
            // Turn on LED
            //
            GPIO_writePin(myBoardLED0_GPIO, 0);
    
            //
            // Delay for a bit.
            //
            DEVICE_DELAY_US(500000);
    
            BitFieldRegType_Inst1.bit.bit0 = 0;
    //        BitFieldRegType_Inst1.bit.bit1 = 1;
    //        BitFieldRegType_Inst1.bit.bit2 = 1;
    //        BitFieldRegType_Inst1.bit.bit3 = 1;
    
    
            //
            // Turn off LED
            //
            GPIO_writePin(myBoardLED0_GPIO, 1);
    
            //
            // Delay for a bit.
            //
            DEVICE_DELAY_US(500000);
    
            BitFieldRegType_Inst1.bit.bit0 = 1;
    //        BitFieldRegType_Inst1.bit.bit1 = 0;
    //        BitFieldRegType_Inst1.bit.bit2 = 0;
    //        BitFieldRegType_Inst1.bit.bit3 = 0;
        }
    }
    
    //
    // End of File
    //
    
    

    Bit 0 changes between 0 and 1 during runtime as expected.

    After setting the watchpoint like the above, it does not halt.

    Is there anything wrong?

  • Bit 0 changes between 0 and 1 during runtime as expected.

    Note that the "Data Value" is set to "0x0" so setting a mask of 0x1 with Data Value of "0x0" will trigger only when bit 0 is cleared. If you want it to trigger when bit 0 is set (changes from 0 to 1), then you would need to specify a Data Value of "0x1". If you want to trigger on any change, then two watchpoints may need to be set.

    With that said, I was trying on both CCS 12.8 and CCS 20.2 and I think there is some bug here. On 20.2.0 when I set the value to 0 and mask to 1, it never halts even when bit 0 is cleared. When I set the value to 1 and mask to 1, it always triggers - even if when the bit is cleared. This does not seem to be the behavior I am expecting. I will need to check with engineering on this.

    Thanks

    ki

  • Hi Ki,

    Yes.

    I have tested on CCS 12.8.1 and saw the same behaviors you said above. This is why I am confused and suspect if there is a bug, too.

    Please keep me posted after you check with engineering.

  • Please keep me posted after you check with engineering.

    I demonstrated the behavior with engineering and they seem to agree that the behavior is not what they expected either. I filed a bug for this issue. Tracking link: https://sir.ext.ti.com/jira/browse/EXT_EP-12629

  • Hi Ki,

    Would you please increase its priority because the user needs to use it to debug an issue in their product on the field side?

    It will be appreciated if you can solve this as soon as possible because it has business impact.

  • I will discuss it. Note that it may not be a trivial fix so I cannot guarantee a timeline yet. Customer may wish to explore the workaround suggested by Aishwarya.

    After more investigation, the issue appears to impact more recent C2000 devices, like the ones with ERAD. Older C2000 devices do not seem to have this issue/

  • Hi Ki,

    Would you please show me what the workaround is suggested by Aishwarya?

    I do not see it.

  • Would you please show me what the workaround is suggested by Aishwarya?

    I do not see it.

    It is the first reply to this thread:

    Hi Wayne,

    Conditional Breakpoints can be used to have the BP trigger when (var ^ PreviousValue) & 0x0010 or some similar statement.

    Customer could also create variables that logs the previous and current values of the fourth bit and have some simple logic to check it that way. 

  • Hi Ki,

    Let me clarify the logic behind.

    In my understanding, CCS watchpoint is using F280039 ERAD, which is a hardware to monitor the data line directly.

    By using the conditional breakpoints, it is like a post-processing by CCS gel software. That is, CCS watchpoint is triggered by any change of the variable and then use gel to calculate filter the bit of the variable. In this way, it only makes sense if the change of the variable is far slower than CCS gel computational time so that CCS gel can calculate it and generate a trigger.

    Is my understanding correct?

  • By using the conditional breakpoints, it is like a post-processing by CCS gel software. That is, CCS watchpoint is triggered by any change of the variable and then use gel to calculate filter the bit of the variable.

    This is correct.

    In this way, it only makes sense if the change of the variable is far slower than CCS gel computational time so that CCS gel can calculate it and generate a trigger.

    This type of conditional breakpoint is intrusive. So when the watchpoint is triggered on any write, the CPU is halted so that the debugger can then evaluate the expression to see if the condition is met. If it is, then the CPU will remain halted if the desired action is to stay halted or perform any other specified action and then auto-resume execution of the CPU. If the condition is not met, then the CPU is auto-executed. The key thing to note is that the CPU is always halted while the debugger evaluates the condition.