硬汉嵌入式论坛

 找回密码
 立即注册
查看: 491|回复: 5
收起左侧

[NetX] 双数据包池是什么意思?不是很理解。

[复制链接]

38

主题

194

回帖

318

积分

高级会员

积分
318
发表于 2024-1-30 17:22:19 | 显示全部楼层 |阅读模式
主要参考资料是硬汉哥的教程还有微软的那个文档。

我看了一下github上stm32的例程:https://github.com/STMicroelectronics/x-cube-azrtos-h7/tree/main/Middlewares/ST/netxduo

看它里面demo都是先nx_system_initialize再nx_packet_pool_create。
[C] 纯文本查看 复制代码
...

nx_system_initialize();


ret = nx_packet_pool_create(&NxAppPool, "NetXDuo App Pool", DEFAULT_PAYLOAD_SIZE, pointer, NX_APP_PACKET_POOL_SIZE);

...


这个流程和教程里的第三章也对的上,所以心里能接受。https://learn.microsoft.com/zh-cn/azure/rtos/netx-duo/chapter3#execution-overview

然后看到数据包的说明:
双数据包池
通常,默认 IP 数据包池的有效负载大小足以容纳网络接口 MTU 以下的帧大小。 在正常操作期间,IP 线程需要发送诸如 ARP、TCP 控制消息、IGMP 消息、ICMPv6 消息之类的消息。 这些消息使用从 IP 实例中的默认数据包池分配的数据包。 在可用于数据包池的内存量受到限制的内存受限系统中,使用单个数据包池(有效负载大小较大,以匹配 MTU 大小)可能不是最佳解决方案。 NetX Duo 允许应用程序安装有效负载大小较小的辅助数据包池。 一旦安装了辅助数据包池,IP 帮助程序线程就会根据其传输的消息大小,从默认数据包池或辅助池中分配数据包。 对于辅助数据包池,200 字节的有效负载大小适用于 IP 帮助程序线程传输的大多数消息。

默认情况下,生成 NetX Duo 库时不会启用双数据包池。 若要启用该功能,生成库时需要定义 NX_DUAL_PACKET_POOL_ENABLE。 然后,可以通过调用 nx_ip_auxiliary_packet_pool_set 来设置辅助数据包池。

还可以选择创建多个数据包池。 例如,使用最适合预期消息大小的有效负载大小来创建传输数据包池。 由于无法预测接收的数据包的大小,因此,系统会在驱动程序中创建一个有效负载大小设置为驱动程序 MTU 的接收数据包池。


不是很理解这个双数据包有什么用?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2024-1-31 08:36:29 | 显示全部楼层
这个玩法还真不太清楚,有必要研究下他的源码实现了。
回复

使用道具 举报

38

主题

194

回帖

318

积分

高级会员

积分
318
 楼主| 发表于 2024-2-2 18:31:17 | 显示全部楼层
硬汉哥,请教一下,这个PHY芯片是如何传输网络的信息的,我不是很清楚?


dm9162.c这个文件里面只是实现了两个函数,一个初始化芯片,一个读取连接状态。这里的使用方法和手册里的都对的上。
然后从nx_stm32_eth_driver.c这个文件里,可以知道要实现以下的函数:
[C] 纯文本查看 复制代码
static VOID         _nx_driver_interface_attach(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_initialize(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_enable(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_disable(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_packet_send(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_multicast_join(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_multicast_leave(NX_IP_DRIVER *driver_req_ptr);
static VOID         _nx_driver_get_status(NX_IP_DRIVER *driver_req_ptr);


从名字猜测,在驱动注册后,实际上调用_nx_driver_hardware_packet_send和 _nx_driver_hardware_packet_received 这两个函数来收发。
看了里面实际的代码实现,里面应该是调了STM32的接口,不过不明白你们是怎么知道要这样子去实现的?
[C] 纯文本查看 复制代码
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_driver_hardware_packet_received               STM32H7xx/IAR     */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Yuxin Zhou, Microsoft Corporation                                   */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function processes packets received by the ethernet            */
/*    controller. This driver assumes NX_PACKET to be MTU size            */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _nx_driver_transfer_to_netx           Transfer packet to NetX       */
/*    nx_packet_allocate                    Allocate receive packets      */
/*    _nx_packet_release                    Release receive packets       */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    _nx_driver_deferred_processing        Deferred driver processing    */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
/*  xx-xx-xxxx     Yuxin Zhou               Modified comment(s),          */
/*                                            resulting in version 6.1    */
/*                                                                        */
/**************************************************************************/
static VOID  _nx_driver_hardware_packet_received(VOID)
{

    NX_PACKET     *packet_ptr;
    NX_PACKET  *received_packet_ptr;
    INT            i;
    uint32_t framelength = 0;
    static ETH_BufferTypeDef RxBuff[NX_DRIVER_RX_DESCRIPTORS];
    
    memset(RxBuff, 0 , NX_DRIVER_RX_DESCRIPTORS*sizeof(ETH_BufferTypeDef));
    
    for(i = 0; i < NX_DRIVER_RX_DESCRIPTORS -1; i++)
    {
        RxBuff[i].next=&RxBuff[i+1];
    }
           
    while (HAL_ETH_GetRxDataBuffer(&heth, RxBuff) == HAL_OK)
    {
        HAL_ETH_GetRxDataLength(&heth, &framelength);
        
        ETH_RxDescListTypeDef *dmarxdesclist = &heth.RxDescList;
        uint32_t FirstAppDesc = dmarxdesclist->FirstAppDesc;

        /* This driver assumes the recieved packet size is 1536 bytes */
        received_packet_ptr = nx_driver_information.nx_driver_information_receive_packets[FirstAppDesc];
        received_packet_ptr->nx_packet_append_ptr = received_packet_ptr->nx_packet_prepend_ptr + framelength;
        received_packet_ptr->nx_packet_length = framelength;
        received_packet_ptr->nx_packet_next = NULL;
        
        if (nx_packet_allocate(nx_driver_information.nx_driver_information_packet_pool_ptr, &packet_ptr,
                                NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
        {
            /* Adjust the packet.  */
            packet_ptr -> nx_packet_prepend_ptr += 2;
            SCB_InvalidateDCache_by_Addr((uint32_t*)packet_ptr -> nx_packet_data_start, packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start);
            HAL_ETH_DescAssignMemory(&heth, FirstAppDesc, packet_ptr -> nx_packet_prepend_ptr, NULL);
            nx_driver_information.nx_driver_information_receive_packets[FirstAppDesc] = packet_ptr;

            /* Build Rx descriptor to be ready for next data reception */
            HAL_ETH_BuildRxDescriptors(&heth);

            /* Transfer the packet to NetX.  */
            _nx_driver_transfer_to_netx(nx_driver_information.nx_driver_information_ip_ptr, received_packet_ptr);
        }
        else
        {
            HAL_ETH_BuildRxDescriptors(&heth);
        }
    }
}


[C] 纯文本查看 复制代码
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_driver_hardware_packet_send                   STM32H7xx/IAR     */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Yuxin Zhou, Microsoft Corporation                                   */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function processes hardware-specific packet send requests.     */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    packet_ptr                            Pointer to packet to send     */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    status                                [NX_SUCCESS|NX_DRIVER_ERROR]  */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    [_nx_driver_transmit_packet_enqueue]  Optional internal transmit    */
/*                                            packet queue routine        */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    _nx_driver_packet_send                Driver packet send processing */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
/*  xx-xx-xxxx     Yuxin Zhou               Modified comment(s),          */
/*                                            resulting in version 6.1    */
/*                                                                        */
/**************************************************************************/
static UINT  _nx_driver_hardware_packet_send(NX_PACKET *packet_ptr)
{

NX_PACKET       *pktIdx;
UINT            buffLen = 0;

ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));


int i = 0;

    for (pktIdx = packet_ptr;pktIdx != NX_NULL ; pktIdx = pktIdx -> nx_packet_next)
    {
        if (i >= ETH_TX_DESC_CNT)
        {
            return NX_DRIVER_ERROR;
    }

        Txbuffer[i].buffer = pktIdx->nx_packet_prepend_ptr;
        Txbuffer[i].len = (pktIdx -> nx_packet_append_ptr - pktIdx->nx_packet_prepend_ptr);
        buffLen += (pktIdx -> nx_packet_append_ptr - pktIdx->nx_packet_prepend_ptr);

        if(i>0)
        {
          Txbuffer[i-1].next = &Txbuffer[i];
        }

        if (pktIdx-> nx_packet_next ==NULL)
        {
          Txbuffer[i].next = NULL;
        }

        i++;
        SCB_CleanDCache_by_Addr((uint32_t*)(pktIdx -> nx_packet_data_start), pktIdx -> nx_packet_data_end - pktIdx -> nx_packet_data_start);
    }

#ifdef NX_ENABLE_INTERFACE_CAPABILITY
    if (packet_ptr -> nx_packet_interface_capability_flag & (NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM |
                                                             NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM |
                                                             NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM |
                                                             NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM))
    {
        TxPacketCfg.ChecksumCtrl = ETH_DMATXNDESCRF_CIC_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
    }
    else if (packet_ptr -> nx_packet_interface_capability_flag & NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM)
        {

        TxPacketCfg.ChecksumCtrl = ETH_DMATXNDESCRF_CIC_IPHDR_INSERT;
        }
#else
        TxPacketCfg.ChecksumCtrl = ETH_DMATXNDESCRF_CIC_DISABLE;
#endif /* NX_ENABLE_INTERFACE_CAPABILITY */

    TxPacketCfg.Length = buffLen;
    TxPacketCfg.TxBuffer = Txbuffer;
 
    /* transmit the packet */
    if(HAL_ETH_Transmit(&heth, &TxPacketCfg, 2000))
    {
        /* Return error.  */
        return(NX_DRIVER_ERROR);
    }

      /* Remove the Ethernet header.  */
    NX_DRIVER_ETHERNET_HEADER_REMOVE(packet_ptr);

    /* Free the packet.  */
    nx_packet_transmit_release(packet_ptr);

    return(NX_SUCCESS);
}

回复

使用道具 举报

38

主题

194

回帖

318

积分

高级会员

积分
318
 楼主| 发表于 2024-2-2 18:39:39 | 显示全部楼层
拿_nx_driver_hardware_packet_send这个函数的其中一小段来说:


[C] 纯文本查看 复制代码
static UINT  _nx_driver_hardware_packet_send(NX_PACKET *packet_ptr)
{

		NX_PACKET       *pktIdx;
		UINT            buffLen = 0;

		ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
		memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));


		int i = 0;

    for (pktIdx = packet_ptr;pktIdx != NX_NULL ; pktIdx = pktIdx -> nx_packet_next)
    {
        if (i >= ETH_TX_DESC_CNT)
        {
            return NX_DRIVER_ERROR;
    }

        Txbuffer[i].buffer = pktIdx->nx_packet_prepend_ptr;
        Txbuffer[i].len = (pktIdx -> nx_packet_append_ptr - pktIdx->nx_packet_prepend_ptr);
        buffLen += (pktIdx -> nx_packet_append_ptr - pktIdx->nx_packet_prepend_ptr);

        if(i>0)
        {
          Txbuffer[i-1].next = &Txbuffer[i];
        }

        if (pktIdx-> nx_packet_next ==NULL)
        {
          Txbuffer[i].next = NULL;
        }

        i++;
        SCB_CleanDCache_by_Addr((uint32_t*)(pktIdx -> nx_packet_data_start), pktIdx -> nx_packet_data_end - pktIdx -> nx_packet_data_start);
    }
,,,
,,,


一上来,就定义了一个数据结构
[C] 纯文本查看 复制代码
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
,那么这里的ETH_TX_DESC_CNT是什么?它从哪里来的?
在cubeMX中我找到了如下配置:
Snipaste_2024-02-02_18-36-24.png

这个Tx Descriptor Length仿佛可以和该配置对应。

但是我更加疑惑了,这个东西到底是什么?它在网络中又是起到了什么作用。把它改大或者改小又会有什么作用。


回复

使用道具 举报

38

主题

194

回帖

318

积分

高级会员

积分
318
 楼主| 发表于 2024-2-2 18:41:40 | 显示全部楼层
感觉这里的内容,三言两语讲不清,如果我想解答这些疑惑的话,需要去阅读什么书籍或者网站吗?有什么文档,协议是和这些知识相关的。
我感觉我就是对ETH这个东西一点都不了解,才会有这样的疑惑。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2024-2-3 08:39:47 | 显示全部楼层
会飞的猪_2020 发表于 2024-2-2 18:39
拿_nx_driver_hardware_packet_send这个函数的其中一小段来说:

这个看参考手册的以太网章节就行。

他是这样的,以太网DMA的发送和接收都有个环形描述符,比如你贴得这个Txbuffer[ETH_TX_DESC_CNT];,就标识定义了ETH_TX_DESC_CNT个描述符数组,这几个数组会组成一个环形队列,每个描述符下有个发送缓冲,比如1500字节。每次DMA发送就会添加数据到环形队列的缓冲里面。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 05:10 , Processed in 0.218031 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表