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:在 250ms 的环路中更改一些代码后、经过 10ms ISR 的 I2C 代码会使 FIFO 超时

Guru**** 2966500 points

Other Parts Discussed in Thread: TCAL9539

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1653062/launchxl-f280049c-i2c-code-in-10ms-isr-gives-fifo-timeout-after-changing-some-code-in-250ms-loop

器件型号: LAUNCHXL-F280049C
主题中讨论的其他器件: TCAL9539

我在 10ms ISR 内有 I2C 代码、在 25 次计数后有 250ms 的循环、在其中读取 ADC 数据。

我在 250ms 的循环中更改了 ADC 读取数据功能中的代码、之后得到了在 10ms 循环中的 I2C FIFO 超时。

以下代码是 I2C 读取数据代码:

uint8_t TCAL9539_ReadRegister (uint32_t base、uint8_t slaveAddress、uint8_t reg、uint8_t *I2Cstatus)
{
  if (I2C_Error (base))
  {
    *I2Cstatus = I2CMCUError;
    返回 0;
  }
   uint8_t data、i;
   uint8_t tempI2Cdata[2]={0};
   uint8_t 尝试= 0;
  /* while (I2CisBusy (base)= 1)
   {
       Trymouse++;
       DEVICE_DELAY_US (100);
       IF(尝试>= 5)
       {
         *I2Cstatus=I2CBusyTimout;
         //返回 0;
       }
   }*/
   尝试= 0;
   while (I2CgetStopConditionStatus (base)= 1)
   {
       Trymouse++;
       DEVICE_DELAY_US (200);
       IF(尝试>= 5)
       {
        *I2Cstatus=I2CStopTimout;
        返回 0;
       }
   }
   I2CentenableFIFO (BASE);
   I2CsetConfig (BASE、I2C_CONTROLLER_SEND_MODE);
   I2CsetSlaveAddress (base、slaveAddress);
   I2CsetDataCount (base、1);
   I2CputData (base、reg);
   I2CsendStartCondition (BASE);
   尝试= 0;
   while (I2CgetTxFIFOStatus (base))
   {
     Trymouse++;
     DEVICE_DELAY_US (200);
     IF(尝试>= 5)
      {
       *I2Cstatus=I2CTxFifoTimout;
       返回 0;
      }
   }
   I2CsetConfig (BASE、I2C_CONTROLLER_RECEIVE_MODE);
   I2CsetDataCount (base、2);
   I2CsendStartCondition (BASE);
   for (I=0;I<2;I++)
   {
     tempI2Cdata[i]= I2C_getData (base);
   }
   尝试= 0;
   while (I2CgetRxFIFOStatus (base)!= I2C_FIFO_RX2)
   {
     Trymouse++;
     DEVICE_DELAY_US (200);
     IF(尝试>= 5)
      {
       *I2Cstatus = I2CRxFifoTimout;
       返回 0;
      }
   }
   I2CsendStopCondition(base);
   尝试= 0;
   while (I2CgetStopConditionStatus (base)= 0)
   {
     Trymouse++;
     DEVICE_DELAY_US (200);
     IF(尝试>= 5)
     {
       *I2Cstatus = I2CStopTimout;
       返回 0;
     }
   }
   DATA =(tempI2Cdata[0]& 0xFF)+((tempI2Cdata[1]& 0xFF)<< 8);

   *I2Cstatus = I2CSuccess;

   返回数据;//发送停止条件以结束写入阶段

}

以下代码为 ADC 读取数据函数:
更改前:
浮点 GetNT1000TempValue (float32_t SensorVoltage);
 ChargerData.AMB = GetNT1000TempValueAMB (AMB、10000.0f、10000.0f);

更改后:
Float GetNT1000TempValue (float32_t SensorVoltage、Float RPULL、Float R01、Float Gain、float pullupvolt);

ChargerData.AMB = GetNT1000TempValue (AMB、10000.0f、10000.0f、1.0f、3300.0f);

上面的代码是唯一一项更改、我添加了 4 个浮点变量、并在 I2C 状态中导致了 I2CRxFifoTimout 、在更改之前、我们在 10ms 循环中获得了 I2C 状态为 I2CSucess。

我们的栈大小为 0x400、我们只使用了 0x200、从映射文件中我们需要知道这一点。

我们需要知道为什么会发生这种情况以及原因。 谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Harihara、

    谢谢你的耐心,当我离开办公室.  我明天就回来找你、谢谢。

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    对延迟深表歉意。 通过向函数标头添加更多输入变量、您会增加函数  的总时间、并且会暴露竞态条件。 在任何情况下、 在使用 I2C_getData () 读取 DRR 之前、都应该使用 I2CgetRxFIFOStatus () 进行轮询。

    此外、它不应该是 uint8_t 数据、而应该是 uint16_t 映射文件仅显示静态分配的原始.stack 大小。 使用内存分配工具更好地了解应用程序内存使用情况。

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aishwarya:

    在此控制器中、uint8_t 定义为 uint16_t。

    下一行来自此控制器的库
    typedef uint16_t uint8_t;
    typedef int16_t int8_t;


    在任何情况下、 在使用 I2C_getData () 读取 DRR 之前、都应该使用 I2CgetRxFIFOStatus () 进行轮询。
    我们还试图对其作出评论  

    while (I2CgetRxFIFOStatus (base)!= I2C_FIFO_RX2)
       {
         Trymouse++;
         DEVICE_DELAY_US (200);
         IF(尝试>= 5)
          {
           *I2Cstatus = I2CRxFifoTimout;
           返回 0;
          }
       }

    但无论有无评论,效果都是一样的。


    我们还分析了内存分配窗口和栈使用窗口。 不会超过栈边界。  

    我在 main() 函数的第一行中使用了栈涂刷、并将所有栈段值设置为 0xAAAA、并在执行过程中停止、然后检查内存浏览器、大约剩余 72 个字节被涂刷、所有其他值都已更改为值、在执行过程中所有值都在更改、并且没有溢出。

    我尝试增加堆栈大小、但也没有效果。 在内存分配方面、我们仅使用了 75%的栈和 78%的闪存、我们的代码仅在闪存上运行。

    下一行来自链接器文件
      RAMM1       :origin = 0x000400、length = 0x000400   /*片上 RAM 块 M1 */

    以下行来自映射文件  

           原点长度   
    .stack 1 00000400 00000200  

    我还随附了链接器文件

    MEMORY
    {
    PAGE 0 :
    
       RAMM0           	: origin = 0x0000F5, length = 0x00030B
    
       RAMLS0          	: origin = 0x008000, length = 0x000800
       RAMLS1          	: origin = 0x008800, length = 0x000800
       RAMLS2      		: origin = 0x009000, length = 0x000800
       RAMLS3      		: origin = 0x009800, length = 0x000800
       RAMLS4      		: origin = 0x00A000, length = 0x000800
       RESET           	: origin = 0x3FFFC0, length = 0x000002
    
    #ifdef __TI_COMPILER_VERSION__
       #if __TI_COMPILER_VERSION__ >= 20012000
    GROUP {      /* GROUP memory ranges for crc/checksum of entire flash */
       #endif
    #endif
      /* BEGIN is used for the "boot to Flash" bootloader mode   */
    
       BEGIN           	: origin = 0x085000, length = 0x000002
       FLASH_TEXT       : origin = 0x085002, length = 0x009FFE
    
       /* Flash sectors */
       /* BANK 0 */
       //FLASH_BANK0_SEC0  : origin = 0x080002, length = 0x000FFE	/* on-chip Flash */
       //FLASH_BANK0_SEC1  : origin = 0x081000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC2  : origin = 0x082000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC3  : origin = 0x083000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC4  : origin = 0x084000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC5  : origin = 0x085000, length = 0x000FFE	/* on-chip Flash */
       //FLASH_BANK0_SEC6  : origin = 0x086000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC7  : origin = 0x087000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC8  : origin = 0x088000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC9  : origin = 0x089000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000	/* on-chip Flash */
       //FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000	/* on-chip Flash */
      // FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000	/* on-chip Flash */
     //  FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000	/* on-chip Flash */
    //   FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000	/* on-chip Flash */
    
       /* BANK 1 */
       FLASH_BANK1_SEC0  : origin = 0x090000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC1  : origin = 0x091000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC2  : origin = 0x092000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC3  : origin = 0x093000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC4  : origin = 0x094000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC5  : origin = 0x095000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC6  : origin = 0x096000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC7  : origin = 0x097000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC8  : origin = 0x098000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC9  : origin = 0x099000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC10 : origin = 0x09A000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC11 : origin = 0x09B000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC12 : origin = 0x09C000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC13 : origin = 0x09D000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC14 : origin = 0x09E000, length = 0x001000	/* on-chip Flash */
       FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x000FF0	/* on-chip Flash */
       FLASH_BANK1_SEC15_DO_NOT_USE     : origin = 0x09FFF0, length = 0x000010  /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
    
    #ifdef __TI_COMPILER_VERSION__
      #if __TI_COMPILER_VERSION__ >= 20012000
    }crc(_ccs_flash_checksum, algorithm=C28_CHECKSUM_16)
      #endif
    #endif
    
    PAGE 1 :
    
       BOOT_RSVD       : origin = 0x000002, length = 0x0000F3     /* Part of M0, BOOT rom will use this for stack */
       RAMM1           : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
    
       RAMLS5      : origin = 0x00A800, length = 0x000800
       RAMLS6      : origin = 0x00B000, length = 0x000800
       RAMLS7      : origin = 0x00B800, length = 0x000800
    
       RAMGS0      : origin = 0x00C000, length = 0x002000
       RAMGS1      : origin = 0x00E000, length = 0x002000
       RAMGS2      : origin = 0x010000, length = 0x002000
       RAMGS3      : origin = 0x012000, length = 0x002000
    }
    
    
    SECTIONS
    {
       codestart        : > BEGIN,     PAGE = 0, ALIGN(4)
       .text            : > FLASH_TEXT,  PAGE = 0, ALIGN(4)
       .cinit           : > FLASH_TEXT,     PAGE = 0, ALIGN(4)
       .pinit           : > FLASH_TEXT,     PAGE = 0, ALIGN(4)
       .switch          : > FLASH_TEXT,     PAGE = 0, ALIGN(4)
       .reset           : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */
    
       .stack           : > RAMM1,     PAGE = 1
       .ebss            : > RAMLS5|RAMGS0,    PAGE = 1
       .esysmem         : > RAMLS5,    PAGE = 1
       .econst          : > FLASH_BANK0_SEC15,    PAGE = 0, ALIGN(4)
    
       ramgs0           : > RAMGS0,    PAGE = 1
       ramgs1           : > RAMGS1,    PAGE = 1
    
        .TI.ramfunc : {} LOAD = FLASH_TEXT,
                             RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_SIZE(_RamfuncsLoadSize),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             RUN_SIZE(_RamfuncsRunSize),
                             RUN_END(_RamfuncsRunEnd),
                             PAGE = 0, ALIGN(4)
    
       /* crc/checksum section configured as COPY section to avoid including in executable */
       .TI.memcrc          : type = COPY
    
    }
    
    /*
    //===========================================================================
    // End of file.
    //===========================================================================
    */
    


    我还附加了工程的内存分配。


    谢谢你。





  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    为了帮助排除存储器相关问题、您能否将.stack 显式移动到 .TI.ramfunc 或某个更大的 RAM 区域、看看这样是否解决了该问题?

    此处的快速说明是、注释掉这些代码行与接收数据前的轮询不同。 请明确尝试。  

    项目运行时是否进行了内存分配?

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aishwarya:

    我将.stack 移到了更大的 RAM 区域、但未解决问题。 我使用了以下 RAM、这是前一个存储器的两倍。
      RAMLS7   :原点= 0x00B800、长度= 0x000800

    我也增加了堆栈内存、但仍然不起作用。

    我们 尝试在读取数据之前显式轮询 Rx fifo、但效果是相同的。

    我上传的存储器分配图片不是在执行期间、我在调试模式下检查了栈指针、它始终仅保持在栈存储器区域边界中、即使在计时器 ISR 或我们使用的其他中断中、它也没有溢出。




  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    因此、我们尚未在运行时确认任何栈溢出/损坏。 我也可以与设计团队核实一下。

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    另外、看起来 控制器没有接收数据。 目标可能是 时钟延展 、因为它没有接收到正确的数据。 您能否检查 目标是否有可 发送到控制器的数据?

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aishwarya:

    目标器件可以发送到控制器、我已经对其进行了检查。

    问题是我在 250ms 环路中更改了一些功能、该更改如何影响 10ms 环路中的 I2C 功能?

    在 250ms 环路功能发生变化(我在初始帖子中分享了这一变化)后、如果我在 250ms 环路中恢复功能、为什么 I2C 状态是 I2C 成功?

    如果目标是时钟延展并且需要一些时间、那么 250ms 环路功能的变化对它有何影响?

    我也在我的第一篇文章中与您分享了项目的映射文件。 如果您想了解该项目的其他详细信息、我们可以提供给您。  

    谢谢你。


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    是否可以使用原始实现、因为它按预期工作? 我建议这样做、因为外围设备本身似乎没有问题、 可能只是时间问题。 如果没有完整的硬件/软件设置、我很难确定地为您提供任何答案、因为我最后看不到这个问题  

    如果要进一步调试这种情况、您可以在 I2C ISR 中添加一个 GPIO 切换开关、以使用原始代码与新代码测量效果、看看效果是否符合预期。

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aishwarya:

    我们的目的是了解 250ms 环路中函数的变化为何会在 10ms 内影响 I2C 功能。

    这是因为在新生成的映射文件中看到的新代码中函数的地址发生了变化吗?

    如果你对此有任何质疑,请让我们知道,以便我们能够提供假设的数据。

    谢谢你。


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    请完成 前面帖子中提到的所有测试、并在您的结尾处研究此问题 我已经从 I2C 的角度提供了所有可能的调试步骤和可能发生的问题。 此时、它可能只是一个与 C 编程相关的一般调试、我已经为它提供了一些线索。  

    此致、

    Aishwarya

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aishwarya:

    我已经尝试并验证了您告诉我们的步骤。

    但是、 在 250ms 内某个函数发生的一些变化如何在 10ms 内影响其他函数。 甚至一个函数都不会与这两个函数相关。

    这是因为阅读说明吗?

    因为在更改 250ms ADC 函数后、函数的地址已更改  

    然后再更改 250ms 功能

    0008a7b6 _ReadInputPort0
    0008a715 _TCAL9539_ReadRegister
    0008c07c _GetMuxInput

    在更改 250ms 功能后

    0008a76c _ReadInputPort0
    0008a6cb _TCAL9539_ReadRegister
    0008c032_GetMuxInput

    这三个函数在 10ms 内被调用、用于 I2C。 因此、在 _TCAL9539_ReadRegister 函数中、 我只得到了 100 微秒的延迟、是因为读取指令需要更多的时间、所以它在 I2C 的停止超时状态结束。

    请 参阅我在初始帖子中提供的上述代码。
    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Harihara

    如果您尝试了上述调试方法、我仍然不清楚。 正如我已经提到的、 您必须 进行轮询、然后按如下所示阅读:  

    I2CsendStartCondition(base);
    
    Attempt = 0;
    while(I2CgetRxFIFOStatus(base) != I2C_FIFO_RX2)  // poll FIRST
    {
        Attempt++;
        DEVICE_DELAY_US(200);
        if(Attempt >= 5)
        {
            *I2Cstatus = I2CRxFifoTimout;
            return 0;
        }
    }
    
    for(i=0; i<2; i++)
        tempI2Cdata[i] = I2C_getData(base);  // read only after FIFO confirmed ready
    

    您仅提到您评论了以下内容:

    如果已经进行了此更改、则确保在与 TX FIFO 连接时进行了类似的更改、因此 在发出重复启动之前、应轮询 I2CgetStatus () 来查看 I2C_STS_BYTE_SENT 标志或等效标志。 每次总线超时/错误时、您都应发送一个停止条件并将 I2C 模块复位。

    我也已经对此进行了说明、但修改函数后、您会更改函数的位置、形成一个不同的 128 位闪存对齐边界。 您可以检查闪存等待状态/其他配置、可能会看到 I2C_getData 函数受到影响的一些等待状态停顿。 这会导致时序问题、即在填充 I2C RX FIFO 之前调用函数。 随后的 while 循环将超时、因为 FIFO 为空。

    此致、

    Aishwarya