TwinCAT3 实时核中ADS实现C++ server、clinet数据传输

news2024/12/23 17:28:20

一、基本概念

ADS :Automation Device Specification,ADS设备间进行通信的协议规范。协议定义了ADS device之间如何寻址对方、ADS device之间可以执行哪些操作、执行这些操作需要哪些参数,以及操作完成后如何返回结果等。从编程角度看,协议涵盖了AMS netID,port number(二者用于寻址ADS device)以及AdsReadWriteInd、AdsReadWriteRes、AdsReadWriteReq、AdsReadWriteCon、AdsReadReq……等一系列函数(用于在ADS device之间传输数据)。

ADS device:具备ADS接口的软件模块。 下图是从倍福官网拷贝的,从图中可以看出,所有的ADS device连接在ADS Router Engine上,那么通过ADS通讯时,是如何识别通讯的ADS device双方呢?这就涉及到后面提到的AMS了。

AMS :Automation Message Specification,指定了ADS数据的交互格式。从编程的角度,需要关心Ams NetId、Ams Prot,二者用于寻址通讯双方的 ADS device。

AMS NetId:默认的AMS NetId是本机IP地址后面加上.1.1,比如192.168.56.1.1.1。但是,AMS NetId与IP地址是没有任何关系的,可以通过下面步骤改成其他值。

AMS Port:通过AMS NetId只能找到对应的PC或控制器,PC或控制器中可能运行很多ADS device,所以还需要AMS Port识别具体的ADS device。AMS Port与linux、Windows中的端口一样,用于识别应用程序,每个应用程序分配有唯一的端口号,port的范围见参考资料4。

Route :通讯的server、client双方必须配置路由信息,路由包含路由名称、AmsNetId、对方的ip地址、路由类型。 TwinCAT 3中添加路由操作如下:

TwinCAT device:装有TwinCAT runtime的PC或控制器。

实时核:TwinCAT可以设置共享实时核、独占实时核,用于对运行时间要求严格的任务。

二、Server与Client通讯模型

与非实时ADS通讯不同,实时核中通信双方不能阻塞,需要采用异步的方式,TwinCAT提供的实时核通信接口见参考资料3。ADS通讯模型是Client-Server模式,客户端发起请求,服务端进行响应。

图中的Req()可以是AdsReadWriteReq、AdsReadReq、AdsWriteReq、AdsReadStateReq等等。
这些函数都有对应的Ind()、Res()、Con(),比如AdsReadWriteReq--AdsReadWriteInd--AdsReadWriteRes--AdsReadWriteCon等等,见参考资料3。

以Client读写Server端的变量为例,流程如下:

1)Client端申请一个AMS port,其他的ADS device(比如Server)可通过该port识别到该Client。

并且获取服务端的AMS NetId和AMS Port。

// State transition from PREOP to SAFEOP

HRESULT CClient::SetObjStatePS(PTComInitDataHdr pInitData)
{
    /*
     * Client端的端口范围是32768–65535,
     * m_AmsPort 的值不要与其它ADS device Client用的端口重复。
     */
	WORD m_AmsPort = 33275;
    AmsAddr m_Addr;

	HRESULT hr = S_OK;
	IMPLEMENT_ITCOMOBJECT_EVALUATE_INITDATA(pInitData);

	hr = SUCCEEDED(hr) ? InitAmsPort(m_spSrv, m_AmsPort) : hr;

	m_Addr.netId = AmsGetNetId(); //服务端AMS NetId
	m_Addr.port = 25100; //服务端AMS Port

	// cleanup on failure
	if (FAILED(hr)) {
		ShutdownAmsPort();
	}
	m_Trace.Log(tlVerbose, FLEAVEA "hr=0x%08x", hr);
	return hr;
}

2)Server端申请一个AMS Port,用于识别本ADS device。

// State transition from PREOP to SAFEOP

HRESULT CModule1::SetObjStatePS(PTComInitDataHdr pInitData)
{
    /*
     * Server端的端口范围是25000–25999,
     * m_AmsPort 的值不要与其它ADS device Server用的端口重复。
     */
	WORD m_AmsPort = 25100;
	m_Trace.Log(tlVerbose, FENTERA);
	HRESULT hr = S_OK;
	IMPLEMENT_ITCOMOBJECT_EVALUATE_INITDATA(pInitData);

	hr = SUCCEEDED(hr) ? InitAmsPort(m_spSrv, m_AmsPort) : hr;

	// cleanup on failure
	if (FAILED(hr)) {
		ShutdownAmsPort();
	}
	m_Trace.Log(tlVerbose, FLEAVEA "hr=0x%08x", hr);
	return hr;
}

3)与Client端需获取Server端的AMS NetId、Port不同,Server端不需要获取Clinet的这些信息。因为TwinCAT采用的是请求-响应的方式,请求发送至Server端时,是含有Client端的AMS NetId、Port这些信息的。

4)Client通过AdsReadWriteReq发送一个读写Server端的请求。

int nErr;
ULONG test_data;
ULONG InvokeId = 0x00000001;
ULONG IndexGroup = 0x08;
ULONG IndexOffset = 0x09;
ULONG cbReadLength = sizeof(test_data);
ULONG cbWriteLength = 0;

/*
 * m_Addr,服务端的AMS NetId、AMS Port
 * InvokeId是一个ULONG数值,用于代表Client端的这个请求。
 * 因为实时核ADS通讯不能阻塞,是异步的,所以Client端收到Server端的响应时,
 * 需要通过invoke id响应对应的是哪个请求。
 *
 * IndexGroup、IndexOffset用于识别具体的命令。比如服务端识别出0x08、0x09后,
 * 就将数值拷贝到test_data中。
 * cbReadLength,读数据的长度,本例中是都一个ULONG类型的数值,读到test_data
 * 变量中。
 * cbWriteLength,写数据的长度,本例中只读不写,该参数可忽略。
nErr = AdsReadWriteReq(m_Addr, InvokeId, IndexGroup, IndexOffset, cbReadLength, cbWriteLength, & test_data);

5)Server端收到Client的请求,自动触发AdsReadWriteInd函数执行。

AdsReadWriteInd通过解析参数indexGroup、indexOffset,执行对应的处理操作,填充Client端请求的数据。还有重要的一点,需要执行AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, cbReadLength, pData)把响应发送给Client端。

enum Module1IndexGroups : ULONG
{
	Module1IndexGroup1 = 0x00000001,
	Module1IndexGroup2 = 0x00000002,
	IG_OVERWRITE = 0x00000003,
	ServerIndexGroup8 = 0x00000008
};

enum Module1IndexOffsets : ULONG
{
	Module1IndexOffset1 = 0x00000001,
	Module1IndexOffset2 = 0x00000002,
	ServerIndexGroup9 = 0x00000009
};

void CModule1::AdsReadWriteInd
(
	AmsAddr& rAddr,
	ULONG invokeId,
	ULONG indexGroup,
	ULONG indexOffset,
	ULONG cbReadLength,
	ULONG cbWriteLength,
	PVOID pData
)
{
	m_Trace.Log(tlVerbose, FENTERA "oid=0x%08x, invokeId=%d, indexGroup=0x%08x, indexOffset=0x%08x, cbReadLength=%d, cbWriteLength=%d, pData=0x%p",
		m_objId.value, invokeId, indexGroup, indexOffset, cbReadLength, cbWriteLength, pData);

	switch(indexGroup)
	{
	case ServerIndexGroup8:
		switch (indexOffset)
		{
		case ServerIndexGroup9:
			// TODO: add custom code here     // override counter with value provided by ADS-client
			unsigned long* pCounter = (unsigned long*)pData;
			//m_Counter = *pCounter;
			*pCounter = 8234;
			AdsReadWriteRes(rAddr, invokeId, ADSERR_NOERR, cbReadLength, pData);
			break;
		}
		break;
	default:
		__super::AdsReadWriteInd(rAddr, invokeId, indexGroup, indexOffset, cbReadLength, cbWriteLength, pData); 
		break;
	}
	m_Trace.Log(tlVerbose, FLEAVEA);
}

7)Client收到Server端的响应,自动触发AdsReadWriteCon函数执行。

函数的参数@cbLength,服务端响应数据的长度。
                  @pData,响应数据的起始地址。

void  CClient::AdsReadWriteCon(AmsAddr& rAddr, ULONG invokeId, ULONG nResult, ULONG cbLength, PVOID pData)
{
	if (nResult == S_OK && invokeId == ClientIndexGroup1) {
		m_bCount_client = *(int*)pData;
		m_Trace.Log(tlAlways, FNAMEA "AdsReadWrite for ads-variable getHdl got invokeid=0x%08x and nresult=0x%08x", invokeId, nResult);
	} else {
		m_Trace.Log(tlAlways, FNAMEA "AdsReadWrite for ads-variable getHdl failed nresult=0x%08x - retrying", nResult);
	}
}

三、参考资料

1,ADS、AMS、Router官网说明

 手册左侧:TwinCAT 3 --> Technologies --> ADS --> AmsNAT --> Introduction 

ADS (Automation Device Specification) is the TwinCAT communication protocol that specifies the interaction between two ADS devices. For example, it defines what operations can be executed on another ADS device, what parameters are necessary for that and what return value is sent after execution.

AMS (Automation Message Specification) specifies the exchange of the ADS data. A major component of the communication protocol is the AmsNetId. This is specified in the AMS/ADS package for the source and target device. An ADS device can be explicitly addressed using the AmsNetId.

route between two devices must be setup in TwinCAT so that they can communicate. This route is configured on both sides and typically contains the route name, the AmsNetId and the address of the communication partner as well as the type of connection. The configuration of new routes and an overview of existing routes in a TwinCAT system are shown in the following figure.

2, ADS device官网说明

手册左侧:TwinCAT 3 --> Technologies --> ADS --> ADS Basics --> ADS device concept 

The TwinCAT system architecture allows the individual modules of the software (e.g. TwinCAT PLC, User HMI, ...) to be treated as independent devices: For every task there is a software module ("Server" or "Client"). The servers in the system are the executing working "devices" in the form of software, whose operating behaviour is exactly like that of a hardware device. For this reason we can speak of "virtual" devices implemented in the software. The "clients" are programs which request the services of the "servers", e.g. a visualisation, or even a "programming device" in the form of a program. It is thus possible for TwinCAT to grow, since there can always be new servers and clients for tasks such as camshaft controllers, oscilloscopes, PID controllers etc. 

3,ADS实时核函数官网说明

手册左侧:TwinCAT 3 --> TE1000 XAE --> C/C++ --> Programming Reference  --> ADS Communication

  • AdsReadDeviceInfo
  • AdsRead
  • AdsWrite
  • AdsReadWrite
  • AdsReadState
  • AdsWriteControl
  • AdsAddDeviceNotification
  • AdsDelDeviceNotification
  • AdsDeviceNotification

4,AMS Port官网说明

手册左侧:TwinCAT 3 --> Technologies --> ADS --> ADS Basics --> ADS device indentification

The unique identification of ADS devices is implemented with the aid of two identifiers:

  • PortNr
  • NetId

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123288.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SVM 监督学习

一、分类问题 利用一条直线分类存在很多问题 二、SVM 支持向量机 其核心思想是通过在特征空间中找到一个最优的超平面来进行分类,并且间隔最大。分类面尽可能远离样本点,宽度越大越好。 适用于中小型复杂数据集的分类。 三、硬间隔和软间隔 硬&#x…

Android Studio -> Android Studio 获取release模式和debug模式的APK

Android Studio上鼠标修改构建类型 Release版本 激活路径:More tool windows->Build Variants->Active Build Variant->releaseAPK路径:Project\app\build\intermediates\apk\app-release.apk Debug版本 激活路径:More tool w…

linux上使用rpm的方式安装mysql

1.从mysql官网上下载需要的版本,根据操作系统版本,CPU架构,下载让rpm bundle,这个版本是个完整版,包含其他所有版本 上传到服务器的一个目录,进行解压 执行tar -xvf mysql*.tar tar -xvf mysql*.tar 2.卸载老版本m…

【Canvas与电脑桌面】用六角回旋镖铺满一个平面(1920*1080)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>六角回旋镖桌面1920x1080</title><style type"text/cs…

动手学深度学习(pytorch)学习记录27-深度卷积神经网络(AlexNet)[学习记录]

目录 创建模型读取数据集训练AlexNet AlexNet 是由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 在 2012 年提出的深度卷积神经网络&#xff0c;它在当年的 ImageNet 大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中取得了显著的成绩&#xff0c;从而引起了深度…

动手学深度学习(pytorch土堆)-02TensorBoard的使用

1.可视化 代码使用了 torch.utils.tensorboard 将数据记录到 TensorBoard 以便可视化。具体来说&#xff0c;它将标量数据记录到目录 logs 中&#xff0c;使用的是 SummaryWriter 类。 代码分解如下&#xff1a; SummaryWriter("logs")&#xff1a;初始化一个 Ten…

常用的 git命令的使用

一. 简介 本文简单学习一下&#xff0c;在从远程仓库中拉取代码&#xff0c;或者向远程仓库提交代码时&#xff0c;经常用到的一些 git命令。 二. git的其他命令的使用 1. 重新提交代码的命令 当已经提交过一笔代码&#xff0c;并经过了 CI自动化编译通过。这时可能发现…

WebAPI(二)、DOM事件监听、事件对象event、事件流、事件委托、页面加载与滚动事件、client,offset

文章目录 一、 DOM事件1. 事件监听2. 事件类型(1)、鼠标事件(2)、焦点事件(3)、键盘事件(4)、文本事件 3. 事件对象(1)、获取事件对象(2)、事件对象常用属性 4. 环境对象 this5. 回调函数 二、 DOM事件进阶1. 事件流(1)、 捕获阶段(2)、 冒泡阶段(3)、 阻止冒泡(4) 、阻止元素默…

python绘制3D瀑布图

成品&#xff1a; 代码&#xff1a; def line_3d(x, y, z, x_label_indexs):"""在y轴的每个点&#xff0c;向x轴的方向延伸出一个折线面&#xff1a;展示每个变量的时序变化。x: x轴&#xff0c;时间维&#xff0c;右边。y: y轴&#xff0c;变量维&#xff0c;…

前端:JavaScript 实现类

文章目录 1. Es6-类-class2. Es6-class 实现继承3. Es6-class 静态属性和私有属性4. Es5-寄生组合式继承 1. Es6-类-class 类是创建对象的模板&#xff0c;用代码封装数据以处理该数据&#xff0c;js中的类建立在原型上。 如何定义类&#xff0c;首先需要关键字 class&#x…

C++之打造my vector篇

目录 前言 1.参照官版&#xff0c;打造vector的基本框架 2.丰富框架&#xff0c;实现接口方法 基本的迭代器实现 数据的[]访问 容量和数据空间的改变 vector空间大小的返回与判空 数据的增删 数据打印 拷贝构造和赋值重载 3.扩展延伸&#xff0c;深度理解代码 迭代器…

iText2KG:显著降低LLM构建知识图谱时的幻觉现象

1. 当前知识图谱构建存在的问题 知识图谱通过捕捉实体之间的关系来构建知识的结构化表示&#xff0c;在分析文本数据集和从结构化异构数据中推断知识方面具有显著优势。比如&#xff0c;知识图谱能够融合来自多个来源的不同数据&#xff0c;提供一个具有凝聚力的信息视角。还能…

【Python进阶】学习Python从入门到进阶,详细步骤,就看这一篇。文末附带项目演练!!!

详细的Python学习路线 1. Python基础 Python安装和环境配置&#xff1a;学习如何在你的操作系统上安装Python&#xff0c;并配置开发环境。变量和数据类型&#xff1a;学习如何定义变量&#xff0c;以及Python中的基本数据类型&#xff0c;如整数、浮点数、字符串等。 Pytho…

【人工智能学习笔记】4_3 深度学习基础之循环神经网络

循环神经网络(Recurrent Neural Network, RNN) 是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network),循环神经网络具有短期记忆能力 RNN核心思想 RNN的结构 一个典型…

基于CNN-BiLSTM-Attention的流量预测 完整数据代码可直接运行

直接看视频: 基于CNN-BiLSTM-Attention的流量预测 完整数据代码可直接运行_哔哩哔哩_bilibili 模型: 有效提取径流时间序列的信息特征,提高径流预测模型的高维非线性拟合能力和预测性能的稳定性,将卷积神经网络(CNN),双向长短期记忆网络(BiLSTM)和注意力机制(attention)相…

tomcat端口被占用解决方法

在安装目录的conf下修改server.xml文件&#xff0c;修改后保存重启即可

十四、MySQL高级— 分库分表(7)

&#x1f33b;&#x1f33b; 目录 一、分库1.1 修改配置 schema.xml1.2 如何选择分库表1.3 SQLyog 连接 mycat 二、水平分表2.1 schema.xml2.2 rule.xml2.3 跨库join2.3.1 ER表2.3.2 全局表 2.4 全局序列2.4.1 本地文件2.4.2 数据库方式(一般都用这个)2.4.3 时间戳方式2.4.4 自…

时间序列预测学习方向总概括

推荐资源&#xff1a; 1.MA、AR、ARIMA 算法小陈-CSDN博客 2.informer论文讲解 【2024最火的两个模型&#xff1a;InformerLSTM两大时间序列预测模型&#xff0c;论文精读代码复现&#xff0c;究极通俗易懂&#xff01;——人工智能|AI|机器学习|深度学习-哔哩哔哩】 https…

微波无源器件 4 基于高阶定向耦合器的双极化波束形成网络

摘要&#xff1a; 一种Ka频段的双极化3dB定向耦合器被设计用于波束形成网络应用。所提出的解决方案对于紧凑Nolen网络。Nolen结构优于器平面和无损特别具有吸引力。两个平行方波导通过口径阵列耦合&#xff0c;设计用于获得两个正交极化之间的所需耦合和高隔离度。 索引词&…

sql语句的训练2024/9/9

1题 需要看清思路&#xff1a;不是将数据库中的device_id的名字改为user_infors_example&#xff0c;而是在查找的时候&#xff0c;需要将device_id看成user_infors_example来进行查找。 答案 select device_id AS user_infos_example FROM user_profile limit 2 2 当固定查找…