IntervalZero RTX64 4.x 帮助文档

⌘K
  1. 主页
  2. 文档
  3. IntervalZero RTX64 4.x 帮助...
  4. RTX64 实时网络
  5. NAL SDK – 移植 TCP/IP 驱动程序

NAL SDK – 移植 TCP/IP 驱动程序

本部分介绍移植现有(RTX64 4.0 版本之前)RT-TCP/IP 栈驱动程序的步骤,以便其用于 RTX64 4.0 及更高版本中。

注意:更多细节请参考随 RTX64 SDK 安装的网络驱动源代码。

注意:如果编写了自定义 NIC 驱动程序,但使用了现有的 NIC 驱动名称,RTX64 控制面板和其他 RTX64 工具将基于 IntervalZero 提供的原始驱动程序对设备进行默认设置。


第 1 步:包含 NAL 头文件

  • 在 Visual Studio 中打开驱动程序的源代码;
  • #include rtnapi.h 之后添加 #include rtNalApi.h

第 2 步:链接到 NAL 库文件步骤

  • 在 Visual Studio 中打开驱动程序的项目属性。
  • 在链接器/输入(Linker/Input)下,将 rttcpip.lib 替换为 RTX64Nal.lib

第 3步:DMA,发送 DMA,IOCTL 锁定

  • 对接收 DMA 环、发送 DMA 环和 IOCTL 使用单独的锁;

注意:如果驱动程序支持多个接收和发送队列,则必须为每个接收 DMA 环和发送 DMA 环使用单独的锁。

第 4 步:向驱动程序结构体添加新字段

  • 将以下新字段添加到设备驱动程序结构体中(每个队列):
    • 存储应用程序上下文指针的字段;
    • 存储接收数据包回调指针的字段;
    • 用于存储标志的字段:1,应用程序已附加到接收队列;2,接收通知已启用;
    • 用于存储多播标志掩码的字段(每个接收队列一位);

第 5 步:将 RtndInitialize 替换为 RtndInitializeInterface

RtndInitializeInterface 第三个参数是一个指向结构体 RTNAL_INTERFACE 的指针,该参数用于输入/输出。如果驱动程序必须更改配置才能运行,则驱动程序应正确配置并更新结构体。

例如,驱动程序可能不支持建议的中断类型,或者可能不监控以太网链路;或可能只支持少于请求数量的接收或发送队列,又或者数据包大小小于最大值;可能支持较少数量的缓冲区,或者必须对缓冲区的数量进行舍入以满足要求等。

MaxPacketSize 包括了 14 字节的以太网报头,但不包括 4 字节 FCS。如果驱动程序需要校验发送或接收缓冲区,或任何其他附加空间,则在分配其缓冲区时必须考虑 FCS。例如,旧驱动中 RTNINTERFACE中 的 1500 RequestedMtu 相当于 RTNAL_INTERFACE中 的 1514 MaxPacketSize

如果驱动程序支持单个接收队列和发送队列,则必须将 NumberOfRxQueues NumberOfTxQueues 设置为 1,并将 DefaultRxQueue 设置为 0。

如果失败,RtndInitializeInterface 应设置最后一个错误。

第 6 步:更改 RtndReceive,RtndTransmit,RtndIoctl 和驱动 IST 函数

更改 RtndReceive

  • RtndReceive 成功执行返回 0,如果失败则返回 -1。失败时必须设置最后一个错误代码。错误代码列表请参阅 RtndReceive 详细说明;
  • 当没有数据包等待接收时,驱动程序必须设置错误代码 ERROR_NO_DATA
  • RtndReceive 必须调用 GetDataLong(ndp, 0) 检索驱动程序接口索引;
  • 如果驱动程序支持多个接收队列:
    • RtndReceive 必须调用 GetDataLong(ndp, 1) 来检索设备队列号;
    • RtndReceive 不得使用存储在 RtndConfigure 中的网络设备指针。而改为使用 ndp 参数;

更改 RtndTransmit

  • RtndTransmit 成功执行返回 0,如果失败则返回 -1。失败时必须设置最后一个错误代码。错误代码列表请参阅 RtndTransmit 详细说明;
  • RtndTransmit 必须通过调用 RtnDecodePacket 获取网络设备指针。再调用 GetDataLong(ndp, 0) 检索驱动程序接口索引;
  • 如果驱动程序支持多个接收队列:
    • RtndTransmit 必须调用 GetDataLong(ndp, 1) 来检索设备队列号;
    • RtndTransmit 不得使用存储在 RtndConfigure 中的网络设备指针。必须改用 RtnDecodePacket 提供的指针;

更改 RtndIoctl

  • RtndIoctl 成功执行返回 0,如果失败则返回 -1。失败时必须设置最后一个错误代码。错误代码列表请参阅 RtndIOCTLDriver 详细说明;
  • 添加以下控制代码的处理:
    • RTNAL_IOCTL_USE_RX_NOTIFICATIONS:将接收队列的通知标志设置为开启;
    • RTNAL_IOCTL_GET_PCI_BUS_LOCATION:指向 RTNAL_PCI_LOCATION 结构体的 addr 参数返回设备的 PCI 总线位置;
  • 更改 ENIOADDMULTIENIODELMULTI 控制代码的处理:
    • 删除对 RtnGetMcastCount( ) 的调用。启用 ENIOADDMULTI 多播混杂模式;
    • 如果驱动程序支持单个接收队列,它可能会使用 NULL addr 参数在 ENIODELMULTI 上禁用多播混杂模式;
    • 如果驱动程序支持多个接收队列,应使用位掩码来确定哪些队列请求使用多播。仅当没有队列使用多播时,应禁用多播混杂模式;

其他可选 IOCTL 控制代码的列表,请参阅 RtndIoctl

  • 如果驱动程序支持多个接收或发送队列:
    • RtndIoctl 不得使用存储在 RtndConfigure 中的网络设备指针。而改为使用 ndp 参数;
    • 对于结构体中不使用队列号的控制代码,RtndIoctl 必须使用 RtnGetDataLong(ndp, 1) 来获取 addr 指向队列号。

更改驱动程序 IST 函数

  • RtnNotifyRev 必须替换为 RtnNotifyRecvQueue 并为每个队列调用,等待接收数据包;
  • 旧驱动程序中计算 IST 新接收数据包的逻辑是使用两个接收 DMA 环索引:一个在 RtndReceive 中用于接收数据包 (NextRxDescriptorToCheck),另一个在 IST 中对接收数据包进行计数 (NextRxDescriptorToFill)。该逻辑必须被替换,使用 RtndReceive 中的 NextRxDescriptorToCheck 索引和 RxDescriptorsNotified 对等待接收但尚未通知的数据包进行计数。IST 中的此计数,必须加上自上次 RtnNotifyRecvQueue(或 RtnNotifyRecv)调用以来收到的数据包数量。RtndReceive 中的计数必须递减;
  • 仅当启用接收通知,且连接接收应用程序时,IST 才应调用 RtnNotifyRecvQueue。当接收应用程序未连接时,驱动程序必须丢弃 IST 中队列的接收数据包;

第 7 步:添加附加和分离函数

添加 RtndAttachToReceiveQueue

  • 锁定接收 DMA 环;
  • 存储应用程序上下文指针;
  • 存储接收数据包回调指针;
  • 设置附加到接收应用程序的标志(flag);
  • 计算接收队列 DMA 环中等待的数据包数量;
  • 解锁接收 DMA 环;

注意:该函数必须返回等待接收的数据包数量。

注意:如果使用无效参数调用,该函数必须返回 -1 并将最后一个错误设置为 ERROR_BAD_ARGUMENTS

添加 RtndDetachReceiveQueue

  • 锁定设备 IOCTL 锁;
  • 清除队列多播标志;
  • 如果所有队列的多播标志都为 0,则清除多播混杂(Multicast Promiscuous)模式;
  • 清除队列的所有接收过滤器;
  • 解锁设备 IOCTL 锁;
  • 锁定接收 DMA 环;
  • 清除应用程序上下文指针;
  • 清除接收包回调指针;
  • 清除接收附加和接收通知标志(flag);
  • 丢弃接收 DMA 环中所有等待的数据包;
  • 解锁接收 DMA 环;

注意:如果成功,该函数必须返回 0。

注意:如果使用无效参数调用,该函数必须返回 -1 并将最后一个错误设置为 ERROR_BAD_ARGUMENTS

第 8 步:修改函数以设置失败时的最后一个错误

修改以下这些函数,以设置失败时的最后一个错误:

  • RtndReceive
  • RtndTransmit
  • RtndIoctl
  • RtndInitializeInterface
  • RtndConfigure
  • RtndUpdown

第 9 步:支持多个接收队列

为了支持多个接收队列(DMA 环),设备必须支持接收队列过滤。NAL API 和 RTX64 网络驱动程序支持以太网类型接收过滤。如果驱动程序实现不同类型的接收过滤,则应添加自定义 IOCTL 控制代码以启用和禁用它。