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.

[参考译文] TMS570LC4357:由 HalCoGen 为 DP83640芯片生成的代码中的竞态条件

Guru**** 1794070 points
Other Parts Discussed in Thread: DP83640, HALCOGEN
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/573286/tms570lc4357-race-condition-in-code-generated-by-halcogen-for-the-dp83640-chip

器件型号:TMS570LC4357
主题中讨论的其他器件:HALCOGENDP83640

你(们)好

HalCoGen 生成的文件 source/hL_phy_dp83640.c (所有版本都包含最新的4.6.0)包含此代码

uint32 Dp83640IDGet (uint32 mdioBaseAddr、uint32 phyAddr)
{
uint32 id = 0U;
uint16 data = 0U;

/*读取 ID1寄存器*/
(void) MDIOPhyRegRead (mdioBaseAddr、phyAddr、(uint32) PHY_ID1、&data);

/*更新 ID1值*/
id =(uint32) data;
id =(uint32)(((uint32) id << phy_ID_shift);

/*读取 ID2寄存器*/
(void) MDIOPhyRegRead (mdioBaseAddr、phyAddr、(uint32) PHY_ID2、&data);

/*更新 ID2值*/
ID |=数据;

/*以 ID1:ID2格式返回 ID */
返回 ID;
}

此代码对芯片复位时的竞态条件很敏感。  当芯片复位未完成时、第一个 MDIOPhyRegRead 可能会失败。 之后可以立即完成芯片复位。 在这种情况下、第二 个 MDIOPhyRegRead 没有失败。 函数返回无效的 PHY_ID。

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

    您好、Jiri、

    您是指违反了这两个时序规格之一吗?  还是其他东西?

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

    是的、我是说这两个复位时间中的任何一个。 哪一项并不重要。 问题是、当这个复位结束的时序完全适合于 ID 值的两个读取之间。

    在这种情况下、ID 的升频16位将为0x0000、低位将正确为0x5CE1

    最终的无效32位结果为0x00005CE1。 预期值为 0x20005CE1

    更好的代码是:

    uint32 Dp83640IDGet (uint32 mdioBaseAddr、uint32 phyAddr)
    {
    uint32 id = 0U;
    uint16 data = 0U;
    
    /*读取 ID1寄存器*/
    布尔状态= MDIOPhyRegRead (mdioBaseAddr、phyAddr、(UINT32) PHY_ID1、&data);
    
    如果(status == true)
    {
    /*更新 ID1值*/
    ID =(uint32)数据;
    ID =(uint32)(((uint32) id << PHY_ID_SHIFT);
    
    /*读取 ID2寄存器*/
    STATUS = MDIOPhyRegRead (mdioBaseAddr、phyAddr、(uint32) PHY_ID2、&data);
    如果(status == true)
    {
    /*更新 ID2值*/
    ID |=数据;
    }
    其他
    {
    ID = 0U;//作为错误值
    }
    }否则{}
    
    /*以 ID1:ID2格式返回 ID */
    返回 ID;
    }
    

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

    实际上、我看不到一种处理这种情况的好方法、至少在任何 PHY API 调用中都是如此。

    我们与另一位客户进行了一些调试、当其中一个 phy 时序未满足时、PHY 将永远不会响应。 (不仅仅是使用错误的 ID 进行响应)。 我认为在加电复位时出现了这个问题、该问题的时间更长。 phy 团队告诉我们、需要时间重置 phy 上的管理接口和寄存器、如果违反该时间、phy 可能无法初始化。

    因此,问题比我认为在 Dp83640IDGet()中的某个条件下应该解决的严重得多,因为在满足 phy 数据表中的时序之前,不应该调用此问题。

    真正需要的是从释放复位到启动 PHY 初始化的延迟时间、这不适合于随 HalCoGen 提供的简单生成的 API。 我认为这应该出现在应用示例中、例如 TCP/IP 堆栈的初始化部分。 它实际上是特定于 PHY 的。

    这些类型的时序竞态条件、尤其是在上电时、经常在同一电路板上的芯片之间出现。
    因此、我将其归类为 HALCoGen 不考虑并成为应用程序代码一部分的众多条件之一。 我认为 lwIP 示例只是"幸运"、因为有足够的初始化内容、只能满足延迟、但却是"意外"而不是显式地满足延迟。