高速以太网:网络模块
对于工业应用,通常需要实时操作以太网接口。KRTS网络模块可以提供这一点。它允许传输任何以太网数据包,包括 IP 数据包。也可以使用其他基本协议或原始以太网。在任何情况下,用户都可以创建数据包。对于 UDP 和 TCP 等更高级别的协议,请参阅本教程的第二部分 (套接字)。
打开网络适配器
为了通过以太网网络适配器进行通信,必须首先使用函数 KS_openNetworkAdapter 打开它。作为参数,适配器句柄、设备字符串、可选的适配器配置和标志被传递。在函数调用之后,适配器句柄将写回参数 phAdapter。
可以使用函数"KS_enumDevices"找到有效的设备。设备将动态更新为Kithara驱动程序,也可以将其永久分配。有关详细信息,请参阅如何查找设备。
用于接收和发送操作的网络数据包数是通过"KSNetworkAdapterConfig"结构中的参数 recvPoolLength 和"sendPoolLength"给出的。如果它们为零,则使用默认计数 256。在本教程的后面部分,用户使用 KS_requestNetworkPacket 请求网络数据包,并使用 KS_releaseNetworkPacket 释放网络数据包。有关其他选项的列表,请参阅 KSNetworkAdapterConfig。
可以使用标志设置多个选项。更多信息,请参阅 KS_openNetworkAdapter。
函数 KS_openNetworkAdapterEx 也可以打开以太网适配器。此外,还可以传递连接句柄。连接手柄可以是零适配器、适配器手柄或 EtherCAT EoE 从站手柄。
空适配器是没有物理接口的适配器。如果传递了上一次调用"KS_openNetworkAdapter(Ex)"的适配器句柄,则会创建网络网桥。如果传递了 EtherCAT EoE 从站句柄,则会创建到 EoE 从站的网桥。
关闭网络适配器
要关闭网络适配器,请使用函数 KS_closeNetwork。
发送数据包
在可以发送数据包之前,首先使用函数 KS_requestNetworkPacket 从发送池请求数据包。作为适配器处理的参数,将传递数据包和标志。调用函数后,将在参数 ppPacket 中返回一个数据包。
下一步,数据包将填充所需的内容。
然后可以使用函数 KS_sendNetworkPacket 发送数据包。作为适配器处理的参数,传递数据包、数据包大小和标志。数据包大小等于帧(包括标头)的大小(以字节为单位)。
使用标志可以设置四个数据包优先级之一:“KSF_PRIO_NORMAL”、“KSF_PRIO_LOW”、“KSF_PRIO_LOWER”、“KSF_PRIO_LOWEST”。
接收数据包
接收数据包有 2 个选项:
-
循环使用 KS_recvNetworkPacket 检查数据包是否已准备好被收集。
-
安装数据包接收处理程序(请查阅下文)。
在这两种情况下,都可以分析数据,然后使用 KS_releaseNetworkPacket 返回到接收池。这两种方法都是互斥的,即您可以使用"KS_recvNetworkPacket"或安装网络接收处理程序。
函数"KS_recvNetworkPacket"有一个适配器句柄、一个数据包、大小和标志作为参数。
如果调用了"KS_recvPacket",但没有准备好收集数据包,则返回错误"KSERROR_NO_DATA_AVAILABLE"。
对于以太网帧,在 ppPacket 中传递的指针的类型为 KSMACHeader。
函数"KS_releaseNetworkPacket"在处理数据包后将数据包释放到接收池。作为适配器处理的参数,将传递数据包和标志。必须调用此函数以确保释放内存资源。
获取适配器状态
函数 KS_getNetworkAdapterState 获取以太网适配器的状态。作为适配器句柄的参数,将传递结构 KSNetworkAdapterState 和标志。
在调用函数之前,请务必将结构成员 structSize 初始化为结构"KSNetworkAdapterState"的实际大小。在调用"KS_getNetworkAdapterState"之后,该结构将填充有关已发送和已接收数据包的信息。
执行适配器命令
函数 KS_execNetworkCommand 在适配器上执行特定命令。作为适配器句柄的参数,将传递命令、可选参数和标志。
具体命令的说明可以在 KS_execNetworkCommand 的 API 文档中找到。有关如何设置可选参数 pParam 或标志的信息也可以在此处找到。
例如,如果应设置 IP 配置,则可以使用命令"KS_NETWORK_SET_IP_CONFIG"。可选参数 pParam 设置为结构 KSIPConfig 。
安装处理程序
要安装网络处理程序,可以使用函数 KS_installNetworkHandler。
作为参数,适配器句柄、事件代码、回调句柄和标志被传递。使用事件代码时,将指定处理程序的类型。
对于事件代码"KS_NETWORK_RECV"、“KS_NETWORK_LINK_CHANGE”、"KS_NETWORK_SEND_EMPTY"和"KS_NETWORK_SEND_LOW"可以实现数据包接收处理程序、链接更改处理程序、发送池空处理程序和发送池低处理程序。如果数据包已准备好接收,则调用第一个处理程序,如果链接状态发生变化,则调用第二个处理程序,当发送池为空时调用第三个处理程序,当发送池较低时调用第四个处理程序。
调用处理程序时应执行的代码作为回调句柄传递(参见 创建回调)。对于不同的事件代码,特殊的上下文结构在 context 参数中传递给回调函数。可以在函数 KS_installNetworkHandler 的 API 文档中找到列表。
对于"KS_NETWORK_RECV"事件代码,相应的上下文结构为 KSNetworkRecvContext。
如果 KS_INVALID_HANDLE 作为回调句柄传递,则再次卸载处理程序。
安装数据包接收处理程序
首先,我们实现一个回调例程,该例程在调用处理程序时执行。接收回调从参数 pContext 获取结构 KSNetworkRecvContext。结构"KSNetworkRecvContext"的字段 pPacketSys 包含在内核级别具有访问权限的数据包。可以使用函数 KS_releaseNetworkPacket 将数据包分析回接收池。
static Error __stdcall _recvCallBack(void* pArgs, void* pContext) {
KSNetworkRecvContext* pUserContext = (KSNetworkRecvContext*)pContext;
KSMACHeader* pMacHeader = (KSMACHeader*)(pUserContext->pPacketSys);
Error ksError;
if (pMacHeader->typeOrLength == KS_htons(USER_ETHERTYPE)) {
// 分析数据包
}
ksError = KS_releaseNetworkPacket(
hAdapter, // 适配器手柄
pUserContext->pPacketSys, // 指向数据包的指针
0); // 标记
if (ksError != KS_OK)
return ksError;
return KS_OK;
}
下一步,将创建一个回调,调用带有标志"KSF_DIRECT_EXEC"的函数 KS_createKernelCallBack,以便在实时上下文中在内核级别执行。接收数据包处理程序使用函数 KS_installNetworkHandler 安装,事件代码为"KS_NETWORK_RECV"。
KSHandle hCallBack;
ksError = KS_createKernelCallBack(
&hCallBack, // 回调句柄的地址
hKernel, // 内核句柄
"_recvCallBack", // 回调例程
NULL, // 引用回调参数
KSF_DIRECT_EXEC, // 标志,这里是内核级别的
// 在实时上下文中
0); // 优先级
ksError = KS_installNetworkHandler(
hAdapter, // 适配器手柄
KS_NETWORK_RECV, // 事件代码
hCallBack, // 回调句柄
0); // 标记
343

被折叠的 条评论
为什么被折叠?



