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.

[参考译文] RTOS/PROCESSOR-SDK-AM437X:IGMP 问题

Guru**** 2601915 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/641595/rtos-processor-sdk-am437x-igmp-issues

器件型号:PROCESSOR-SDK-AM437X

工具/软件:TI-RTOS

我的程序将打开2个 UDP 套接字: 端口#1:IP 192.168.1.16和 eth0上的端口6000以及端口#2: IP 192.168.2.33和端口6000和
然后、它将端口#1连接到多播组226.10.1.7、将端口#2连接到多播组226.10.2.7。

电路板的两个以太网接口都连接到网络交换机。 PC 也连接到交换机。

Wireshark 仅显示来自 IP 192.168.2.33的 IGMP 消息。 它显示4条消息:2条表示226.10.1.7、2条表示226.10.2.7。 它不显示来自 IP 192.168.1.16的消息。

以下是打开套接字并加入组的函数。

ERROR_CODES_T UDP:::Open (uint32_t ipaddr、uint16_t port)
{
套筒垫;
struct sockaddr_in sockAddress;
int sockOption;

//创建套接字。
sock = NDK_socket (AF_iNet、SOCK_DGRAM、IPPROTO_UDP);
如果(sock == invalid_socket)
{
返回 EC_FAIL;
}

//将端口绑定到套接字
bzero (等位地址、sizeof (struct sockaddr_in));
sockAddress.Sin_Family = AF_iNet;
sockAddress.Sin_port =端口;
sockAddress.sin addr.s_addr = ipaddr;

if (socket_error =NDK_bind (sock、(struct sockaddr *)&sockAddress、sizeof (struct sockaddr_in)))
{
返回 EC_FAIL;
}

//设置广播包的套接字选项。
sockOption = true;
if (socket_error =NDK_setsockopt (sock、SOL_socket、SO_broadcast、(void *)等式选项、sizeof (int))))
{
返回 EC_FAIL;
}

//设置输出的缓冲区大小。
sockOption = 8192;
if (socket_error =NDK_setsockopt (sock、SOL_socket、SO_SNDBUF、等式选项、sizeof (int))))
{
返回 EC_FAIL;
}

//设置输入的缓冲区大小。
sockOption = 8192;
if (socket_error =NDK_setsockopt (sock、SOL_socket、SO_RCVBUF、等式选项、sizeof (int))))
{
返回 EC_FAIL;
}

//成功。
socketPtr = sock;
状态=已打开;

返回 EC_SUCCESS;
}//打开

ERROR_CODES_T UDP:::Join (uint32_t multIpAddr)
{
struct ip_mreq mreq;

//为多播地址套接字选项创建结构。
bzero (&mreq、sizeof (struct ip_mreq));
mreq.IMR_multiaddr.s_addr = multIpAddr;
mreq.IMR_interface.s_addr = LocalIpAddr ();

//加入组。
if (socket_error =NDK_setsockopt (socketPtr、IPPROTO_IP、IP_Add_Membership、&mreq、sizeof (struct ip_mreq))))
{
返回 EC_FAIL;
}

返回 EC_SUCCESS;
}//加入 


您看到代码有什么问题吗?
您以前是否见过这种行为?
你有什么线索吗?


已安装的组件:
CCS 7.2
GCC ARM 编译器4.9.3
PROCESSOR_SDK_RTOS_AM437X 4.00.04
AM437x PDK v1.0.7
BIOS 6.46.05.55
xdctools 3.32.02.25_core

电路板:AM437X 入门套件


此致、
Marcio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    RTOS 团队已收到通知。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好!

    您是否有机会了解我的 IGMP 问题?

    此致、

    Marcio。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉耽误你的时间。 上周在美国有假期。 我已上报请求。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    对我的问题有任何反馈吗? 您是否成功重现了问题?

    此致、

    Marcio。

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

    很抱歉迟到了! 您能否提供 CCS 项目来重现问题、而这需要一个具有两个以太网端口的 EVM、对吗? 您是否使用 NIMU 驱动程序和 NDK 封装进行编程? NDK 的哪个版本?

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

    尊敬的 Eric:

    您写道:您能否提供 CCS 项目来重现问题、这需要一个具有两个以太网端口的 EVM、对吧?

    是的、您需要一个具有两个以太网端口(cpsw) 的 EVM、如 AM437x 入门套件。
    我的 CCS 程序有很多代码无法公开、我必须去除额外的代码、这需要一段时间。 但您可以使用任何使用两个以太网端口的 CCS 项目。 当我打开此主题时、我提供了用于打开端口和配置 IGMP 的功能。

    您写道:您的编程是否使用 Nimu 驱动程序和 NDK 封装? NDK 的哪个版本?

    是的、它使用 NIMU 驱动程序和 NDK 封装:PROCESSOR_SDK_RTOS_AM437X  4.00.00.04。CCS 为7.2。

    此致、
    Marcio。

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

    您的测试是否基于 NIMU_BasicExample_skAM437x_armExampleProject 示例? 还是 EMAC_BasicExample_skAM437x_armBiosExampleProject?

    如果是 NIMU、则替换了 MAIN_skAM437x.c 的哪些部分? 如何将代码集成到测试示例中?

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

    您好!

    实际上、我的项目基于 Nimu_DualMacExample_idkAM572x_armExampleproject、这是 TI 团队推荐的项目。 我认为 AM437x 没有使用2个端口的示例。

    以下是对2个端口进行初始化的代码。 调用 ethInit()过程以初始化 EMAC 和 Nimu。

    附加了我对 EMAC 驱动程序所做的更改。 它们是其他线程的结果。

    e2e.ti.com/.../MB_2D00_pdk_5F00_am437x_5F00_1_5F00_0_5F00_7_5F00_Fix.zip

    如果您需要更多信息、请告诉我。

    此致、

    Marcio。

    #define EMAC_CPSW_PORT0_PHY_ADDR_SK 4 //< CPSW 端口1的 PHY 地址
    #define EMAC_CPSW_PORT1_PHY_ADDR_SK 5 //< CPSW 端口2
    
    的 PHY 地址 NIMU_DEVICE_TABLE_Entry NIMUDeviceTable[NUM_NIMU_DEVICE_SK + void 1;
    
    
    1 (void)
    EMAC_HwAttrs_V4 cfg;
    
    dcPrint ("正在初始化以太网模块...\n");
    
    /*芯片配置 MII/RMII 选择*/
    ethCpswPortMacModeSelect (0、Ethernet_MAC_TYPE_RGMII);
    ethCpswPortMacModeSelect (1、Ethernet_MAC_TYPE_RGMII);
    
    EMAC_socGetInitCfg (0、&cfg);
    cfg.numPorts = 2;
    cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_SK;
    cfg.port[1].phy_addr = EMAC_CPSW_Port1_PHY_ADDR_SK;
    EMAC_socSetInitCfg (0、&cfg);
    
    //填充 NIMU 器件表以初始化2个器件(以太网接口)。
    NIMUDeviceTable[0].init =&CpswEmacInit;
    NIMUDeviceTable[1].init =&CpswEmacInit;
    NIMUDeviceTable[2].init = NULL;
    
    }// ethInit
    
    void ethCpswPortMacModeSelect (uint16_t ethIndex、uint32_t macMode)
    {
    uint32_t portnum = ethIndex + 1;
    uint32_t regVal = 0U;
    
    regVal = HW_RD_REG32 (SOC_CONTRAL_MODULE_REG + CTRL_GMII_SEL);
    
    switch (macMode)
    {
    案例 Ethernet_MAC_TYPE_MII:
    案例 Ethernet_MAC_TYPE_GMII:
    if (1U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII1、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII1_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII1_IO_CLK_EN、0U);
    }
    否则 if (2U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII2、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII2_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII2_IO_CLK_EN、0U);
    }
    其他
    {
    /*由于检查已完成,因此未发生此错误*/
    }
    中断;
    
    案例 Ethernet_MAC_TYPE_RMII://* RMII *
    if (1U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII1、1U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII1_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII1_IO_CLK_EN、0U);
    }
    否则 if (2U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII2、1U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII2_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII2_IO_CLK_EN、0U);
    }
    其他
    {
    /*由于检查已完成,因此未发生此错误*/
    }
    中断;
    
    案例 Ethernet_MAC_TYPE_RGMII://* RGMII *
    if (1U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII1、2U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII1_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII1_IO_CLK_EN、0U);
    }
    否则 if (2U == portnum)
    {
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_GMII2、2U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RGMII2_IDMODE、0U);
    HW_SET_FIELD (regVal、CTRL_GMII_SEL_RMII2_IO_CLK_EN、0U);
    }
    其他
    {
    /*由于检查已完成,因此未发生此错误*/
    }
    中断;
    
    默认值:
    中断;
    }
    
    HW_WR_REG32 ((SOC_CONTRAL_MODULE_REG + CTRL_GMII_SEL)、regVal);
    }// ethCpswPortMacModeSelect
    


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

    感谢您提供详细信息。 我们仅测试了 AM57x EMAC 的两个以太网端口、并且在驱动程序示例中支持该端口、但 AM437x 不支持该端口。 更改 AM437x 的两个端口支持后、您是否能够运行两个独立的以太网接口并从 PC ping 它们? 如果不是、则驱动程序中可能存在一些问题。 如果是、则问题出在 NDK 中的套接字编程或 IGMP 支持。

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

    尊敬的 Eric:

    是的、我可以单独在两个以太网接口上接收 ping 并从 PC 发送回复。 我还可以使用单播地址发送和接收 UDP 消息。

    我无法在第一个接口上接收 UDP 多播消息、因为 IGMP 仅在第二个接口上工作(主板发送2个请求来加入第二个接口的组、而不发送第一个接口的请求)。

    我提供了用于对套接字进行编程并在该主题的第一条消息中加入 IGMP 组的功能。

    您是否可以尝试使用 AM57x 板重现问题? 我相信 NDK 是一样的。 如果工作正常、问题可能在硬件和驱动程序(NIMU + EMAC)之间、而 NDK 将是正确的。

    此致、