AM625-Q1: optimization vs stack overflow

Part Number: AM625-Q1

Tool/software:

Hello,

    Good day!

    There is customer's issue, could you help? Thank you so much.

    Preface: External watchdog is used to feed dogs in RTOS tasks. During troubleshooting the issue of abnormal reset, it was found that I2C communication abnormalities can cause reset. The following is detailed information on simulation debugging.
I2C communication exception caused program crash, interrupt continues to I2C_lld_targetIsr, unable to enter task function, all tasks starved to death.

   I found that enabling the optimization feature in the compiler leads to the above issues. The compiler optimization settings are shown in the picture:

  After turning off the compiler optimization, the issue did not reoccur. The compiler settings for this are shown in the picture:

  However, if our project does not enable optimization, the stack will overflow. Is there any solution to this?

  • Hi,

    From the above it looks like it fails, when you use -O1 optimization level. Or is this because of -flto optimization?

    Also can you try different optimization level like -O2. Please refer ti-arm-clang-optimization to understand different optimization levels.

    Regards,

    Tushar

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply:

        We replaced it with a new board for testing and found that we could not reproduce the above content at any optimization level.

         However, the program occasionally experiences an I2C communication exception that loops indefinitely at line 2176 in i2c_v0_lld.c, unable to wait for the bus busy release.

        Looking at it with a logic analyzer, both SDA and SCL are pulled high.

        

          The diagram shows it is waiting for bbtimeout to reduce to 0.

            Is there any way to avoid this issue?

          The CCS version is 12.7.0, and the SDK version is mcu_plus_sdk_am62x_10_00_00_14.

  • Hi Alice,

     However, the program occasionally experiences an I2C communication exception that loops indefinitely at line 2176 in i2c_v0_lld.c, unable to wait for the bus busy release.

    Have you configured timeout value for I2C? The default value for timeout is Wait forever. So it will wait until the BB bit in the Interrupt RAW register is cleared or the timeout has happened.

    Regards,

    Tushar

  • Hello Tushar,   

        Thanks for your support.

        Please check the customer's reply and support further , thank you so much.

        

        The timeout here is not configurable by me; it is hardcoded in the SDK code. The SDK version is mcu_plus_sdk_am62x_11_01_00_16.    

        In the latest version of the SDK, there has been no change in this regard, as shown in the image below:

       

       Let me update the status of the issue here. This was directly checked using the XDS110 debug. The configuration was set to host, but whenever the fault was reproduced, it kept entering the slave interrupt. In the end, I found that the macro value for NULL was defined as 0 #define NULL ((void) 0), and maybe some pointer is out of bounds somewhere. After masking, the aforementioned issue hasn't been reproduced. However, in the I2C_waitForBb function, it gets stuck waiting for the bus to release the busy state. Can you help me see if there is any way to avoid this? Because I checked with a logic analyzer, both SDA and SCL are high, but the bus is still busy.

       

  • Hi Alice,

    Can you help me see if there is any way to avoid this? Because I checked with a logic analyzer, both SDA and SCL are high, but the bus is still busy.

    While configuring the I2C parameters, you can also configure this timeout value.

    Please refer below code.

    Try once after configuring the timeout value and update the result.

    Regards,

    Tushar

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply and support further, thank you so much.

        The timeout here has always been configured, with a value of 0x100.

       The effect of the timeout value is not on the problem mentioned above, but at line 506 of i2c_v0.c, as shown in the image below:

       

  • Hi Alice,

    Yes, I can see this that the timeout is not effective here for I2C_waitforbb() API. The I2C_lld_primeTransferIntr() API internally calls the I2C_waitforbb() API with the timeout value for I2C_WAIT_FOREVER.

    Can you try once providing the I2C_DELAY_MED value for the timeout and update the results?

    Please refer below image.

    Regards,

    Tushar

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply and support further, thank you so much.

        The code I modified using the example ipc_rpmsg_echo_linux_am62x-sk-lp_m4fss0-0_freertos_ti-arm-clang is shown in the figure:

        SDK version: mcu_plus_sdk_am62x_10_00_00_14, CCS version: Code Composer Studio 12.7.0.

        

        When an I2C exception is detected, it may occasionally enter the HwiP_hardFault_handler function:

        

       I would like to ask, under what conditions does the HwiP_hardFault_handler function get called?

  • Hi Alice,

    So, the code is now not stuck at bus busy bit to get clear. Instead it is going to exception.

    Can you do step by step debug and check after which function call it goes to exception?

    Regards,

    Tushar

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply and support further, thank you so much.     

        Regarding the I2C issue, when the I2C_transfer function does not return I2C_STS_SUCCESS, I first call Drivers_i2cClose and then call Drivers_i2cOpen. In fact, the exception can be recovered, and it temporarily resolves the issue. As long as it doesn't enter HwiP_hardFault_handler afterward and keeps entering I2C_lld_targetIsr, it's fine. Could you please help analyze the possible reasons for entering HwiP_hardFault_handler and continuously entering I2C_lld_targetIsr?                                                                                                                                          

  • Hi Alice,

    Could you please help analyze the possible reasons for entering HwiP_hardFault_handler and continuously entering I2C_lld_targetIsr?

    The I2C_lld_targetIsr API is called when the controller operates in the target mode instead of controller mode. Are you configuring I2C to operate in target mode?

    Regards,

    Tushar

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply and support further, thank you so much.     

        I have not configured to target mode, see my previous screenshot (below).

         I made modifications on the example ipc_rpmsg_echo_linux_am62x-sk-lp_m4fss0-0_freertos_ti-arm-clang.

        The screenshot is already the complete code. The default configuration is as follows, all in control mode (host) and not in target mode.

         

       In addition, the version of the IDE I am using is Code Composer Studio 12.7.0.

         Where can I find the Call Stack View? By the way, I want to see the difference between the optimized and unoptimized generated firmware.

        Is there a way to generate assembly files to see the difference in the assembly code generated after optimization and without optimization?

  • Hi Alice,

    The default configuration is as follows, all in control mode (host) and not in target mode.

    The configuration shared above is correct and the I2C operates in controller mode. I am still not sure why the CPU is executing I2C_lld_targetIsr, as this API is supposed to get called when I2C is in target mode.

    You can reconfirm the same by halting the CPU at I2C_lld_targetIsr API, and read the I2C_CON register. If the value of MST bit is set then the I2C is in controller mode, otherwise in target mode.

    Please refer below image.

    Regards,

    Tushar

  • Where can I find the Call Stack View?

    The call stack view can been seen in the debug view of the CCS once the core is halted.

    By the way, I want to see the difference between the optimized and unoptimized generated firmware

    You can compare the *map files of the optimized and unoptimized firmware to see differences.

    Is there a way to generate assembly files to see the difference in the assembly code generated after optimization and without optimization?

    You can enable the option to keep all files generated during compilation. To enable this, navigate to Project Properties -> Build -> Arm Compiler -> Advance Options -> Control Options. Please refer below image.

  • Hello Tushar,

        Thanks for your support.

        Please check the customer's reply and support further, thank you so much.   

        6661.ipc_rpmsg_echo_linux_am62x-sk-lp_m4fss0-0_freertos_ti-arm-clang.zip

        The version of the SDK used for the uploaded project is: mcu_plus_sdk_am62x_10_00_00_14

        IDE version: Code Composer Studio 12.7.0

        Debugger: XDS110The above project, configured as a host (control mode), alternately short-circuits the I2C SDA and SCL to GND (simulating a fault), and will automatically switch to slave mode (target mode).The project has optimization enabled.When optimization is not enabled, it enters HwiP_hardFault_handler, as shown in the image below:

        

  • Hi Alice,

    Thanks for providing additional details and project.

    alternately short-circuits the I2C SDA and SCL to GND

    Can you please explain why there is need to short-circuit the SCL and SDA line? It will break the I2C communication protocol.

    The project has optimization enabled.When optimization is not enabled, it enters HwiP_hardFault_handler, as shown in the image below:

    Do you mean, when optimization is enabled everything works as expected without issues?

    I am checking the above project and will revert back with feedback.

    Regards,

    Tushar