前言
本文档描述了如何将 PROFIsafe 驱动程序集成到 EK-ERTEC200P-2 评估套件的软件中。在实现中可以仿真单通道硬件架构和双通道硬件架构。
对于双通道实现,第二个微控制器被仿真,第二个独立定时器也是如此。该应用示例作为固件实现的示例,但凭借其现有硬件,它并不构成面向安全的模块,也没有安全证书。
GSDML 已针对 PROFIsafe 应用示例进行配置,使故障安全报文符合 PROFIsafe Profile V2.6 MU1。
用户数据结构如下:
- 1 字节用户数据(输入和输出)
- 1 字节状态/控制字节
- 4 字节 CRC
- 1 字节状态/控制字节
- 4 字节 CRC
此外,该实现基于评估套件的代码构建。在将 PROFIsafe 驱动程序添加到其中之前,用户应对评估套件有基本了解。本说明中会再次回顾并解释评估套件的基本功能。
PROFIsafe 驱动程序支持多实例运行。这意味着可以在一台设备上安装多个(最多 32 个)F 设备。本应用示例中只配置了一个实例。
**注意:**应用示例的目的是展示 PROFIsafe 驱动程序的一种可能实现。该应用示例不适用于真实 F 应用中的安全运行。
1. 引言
1.1 要求
在开始将 PROFIsafe 驱动程序集成到评估套件之前,用户应具备以下基本条件:对 EK-ERTEC200P-2 评估套件的基本功能有了解,熟悉 TIA Portal 的使用,并掌握 C 语言嵌入式开发的基本技能。
2. GSDML 配置
2.1 准备
GSDML 文件用于描述 PROFINET IO 设备的特性。在 TIA Portal 中集成 PROFIsafe 应用示例之前,需要先准备并调整 GSDML 配置。
2.2 扩展------分步说明
2.2.1 DAP(设备接入点)
DAP 是设备的接入点,定义了设备的基本通信属性。在此步骤中需要设置与 PROFIsafe 应用示例相匹配的 DAP 参数。
2.2.2 模块(槽子模块)
在此步骤中定义设备的槽和子模块,包括 PROFIsafe 相关的模块配置,例如 F 参数和 F 模块。
2.2.3 可选更改
可以根据实际项目需要对 GSDML 文件进行可选调整,例如设备标识、诊断文本等。
2.2.4 在 TIA Portal 中集成 GSDML 文件
调整完成后,将 GSDML 文件导入 TIA Portal,以便在项目中对设备进行配置和参数化。
3. DevKit 调试
3.1 安装工具
首先需要安装调试所需的工具,包括 IDE、工具链以及相关的调试器软件。
3.2 Eclipse 配置
3.2.1 为 DevKit 设置 Eclipse
在 Eclipse 中配置开发环境,以便对 DevKit 固件进行开发和调试。
3.2.2 在 C 文件中替换 PSD-lib
在相应的 C 文件中替换 PSD-lib,以集成 PROFIsafe 驱动程序的库文件。
3.2.3 调试器配置
配置调试器连接,确保可以通过 J-Link 等调试工具对目标设备进行调试。
3.2.4 USB 终端连接配置
配置 USB 终端连接,以便通过串行终端查看设备输出信息。
3.2.5 构建应用固件 "App_05.bin"
完成配置后,构建应用固件 App_05.bin,生成可加载的固件映像文件。
3.2.6 加载并启动 PSD F 应用
将构建好的固件加载到设备中,并启动 PROFIsafe F 应用。
3.3 将应用固件加载到闪存
3.3.1 准备
在将固件写入闪存之前,需要准备好应用固件文件以及闪存加载工具。
3.3.1.1 应用固件
确认 App_05.bin 固件文件已正确生成。
3.3.1.2 配置 TcpFwLoader_EB200P.bat
配置 TcpFwLoader_EB200P.bat 脚本,设置正确的网络参数以便通过 TCP 加载固件。
3.3.2 加载过程
按照加载流程将应用固件写入设备的闪存中。
3.4 读取固件版本数据
加载完成后,可以读取固件版本信息,以确认当前运行的固件版本。
3.5 F 地址分配(初始化)
3.5.1 写入 F 源地址和 F 目标地址
在进行 PROFIsafe 通信之前,需要写入 F 源地址和 F 目标地址,确保 F 主机与 F 设备之间能够正确建立通信。
4. 标准源文件的准备/配置
4.1 标准源文件的准备
在集成 PROFIsafe 驱动程序之前,需要对标准源文件进行准备。
4.2 设置 EXAMPL_DEV_CONFIG_VERSION
在源文件中设置 EXAMPL_DEV_CONFIG_VERSION,以匹配当前应用示例的配置版本。
4.3 源文件 usriod_main.c 中的更改
在 usriod_main.c 源文件中进行必要的更改,以支持 PROFIsafe F 应用的调用。
5. PROFIsafe 驱动程序的配置
5.1 头文件 p_c_config.h
5.1.1 NOF_INSTANCES
NOF_INSTANCES 用于定义 F 设备实例的数量。本应用示例中配置为一个实例。
5.1.2 REDUNDANT
REDUNDANT 用于配置冗余模式,即是否启用双通道硬件架构。
5.1.3 长度配置
在此处配置 PROFIsafe 报文中用户数据的长度。
5.1.4 源/目标地址;SIL 等级
配置 F 源地址、F 目标地址以及 SIL 等级等参数。
5.1.5 报文属性
配置 PROFIsafe 报文的属性,例如 F_CRC_Length 等。
5.2 头文件 psd_interface.h
5.2.1 槽和子槽
定义 PROFIsafe 模块对应的槽和子槽编号。
5.2.2 报文属性参数
定义与报文属性相关的参数。
5.2.3 BusEvents 接口
定义用于总线事件处理的接口。
5.2.4 诊断定义
定义诊断相关的常量和标识符。
5.2.5 诊断类型 DiagType
定义诊断类型 DiagType,用于区分不同类型的诊断信息。
6. 状态机
6.1 状态机结构
PROFIsafe 驱动程序的核心是一个状态机,用于管理 F 设备的通信状态。状态机的结构包括参数化、数据交换和安全状态等多个状态。
6.2 状态图
状态图展示了状态之间的转换关系,包括从配置状态到循环数据交换状态的各个转换路径。
6.3 转换表
转换表详细列出了状态机中各个状态之间的转换条件以及相应的处理动作。
7. 将 PROFIsafe 驱动嵌入 F 设备
7.1 将 PROFIsafe 驱动嵌入 F 设备
本节说明了如何将 PROFIsafe 驱动程序嵌入到 F 设备的固件中,包括初始化、接口调用以及与 DevKit 软件的集成方式。
8. 时序图
8.1 无错误时序
8.1.1 配置/参数分配启动
该时序图展示了设备上电后配置和参数分配的启动过程。
8.1.2 从 STOP 到 RUN 的转换
展示了 PROFIsafe 通信从 STOP 状态转换到 RUN 状态的过程。
8.1.3 循环数据交换
展示了 F 主机与 F 设备之间建立通信后循环数据交换的过程。
8.1.4 停止 PROFIsafe 通信
展示了正常停止 PROFIsafe 通信的时序过程。
8.2 错误场景
8.2.1 参数分配期间的错误
展示了参数分配过程中发生错误时的时序,例如 F 参数校验失败。
8.2.2 状态 "CYCLIC_DATAEX; DATAEX_OUT_RCV" 下的报文错误
展示了在循环数据交换状态下接收 F 输出报文时发生错误的情况,例如 CRC2 校验失败或超时。
9. 程序流程图
9.1 PnUsr_DeviceSetup()
该函数在设备上电时由 DevKit 调用,负责初始化 PROFIsafe 驱动、诊断管理器和 F 应用。
9.2 PNIO_cbf_rec_write()
当收到数据记录时调用该回调函数,根据数据记录号设置控制事件并将数据复制到 F 应用的相应缓冲区。
9.3 PNIO_cbf_data_read()
收到过程数据时调用,设置事件 procDatReceived,并根据 IOPS 设置 processDataOutputIsDisabled 事件。
9.4 PNIO_cbf_data_write()
过程输入数据成功发送到 F 主机后调用,复位事件 procDatSendRequ。
9.5 PNIO_cbf_ar_connect_ind()
初始化期间调用,设置 F 应用的过程数据指针,使其指向 DevKit 的相应缓冲区。
9.6 DG_update()
作为任务循环调用,处理诊断缓冲区中登记的诊断事件。
10. PROFIsafe 函数
10.1 psd_InitInstance()
初始化 PROFIsafe 驱动程序实例,为后续的配置和运行做准备。
10.2 psd_FParBuild()
构建并校验 F 参数,检查 F 源地址、F 目标地址、看门狗时间和 SIL 等级等参数的有效性。
10.3 psd_Config()
对 PROFIsafe 驱动程序实例进行配置。
10.4 psd_Run()
启动 PROFIsafe 驱动的运行状态。
10.5 psd_Stop()
停止 PROFIsafe 驱动的运行状态。
10.6 psd_RecvFOutTele()
接收并检查来自 F 主机的输出报文,包括时间戳检查和超时检测。
10.7 psd_GetFOutData()
获取经过校验的输出数据以及控制字节的位信息,用于过程数据输出。
11. 将 PROFIsafe 驱动源文件集成到应用示例中
11.3 p_c_pseudo.c
Fapp_Read_FOutput_Telegram()
该函数检查从 F 主机接收的输出报文。对于时间戳 time1 和 time2(超时检查),读取由 DevKit 操作系统提供的相同定时器。相关流程见循环数据交换时序图以及 psd_RecvFOutTele() 函数说明。
Fapp_GetFoutData()
该函数获取经校验的输出数据以及控制字节的位信息,用于过程数据输出。根据所调用的 psd_GetFOutData() 的返回值,如果检测到错误,则使用 DG_setEvent(event ID) 发送"到来"诊断事件。事件 ID 会映射到 GSDML 的错误号。如果检查无错误,则 com_state = DATAEX_IN_SET(为 F 主机输入报文准备过程输入数据和状态字节)。
Fapp_Set_FInput_Data()
该函数通过函数调用 psd_SetFInData() 为 F 主机分配过程输入数据和 PSD 状态字节。如果 psd_SetFInData() 的返回值不是 SET_FIN_DATA_OK,则 F 应用通过 FApp_Hard_Error() 切换到安全状态。如果未检测到错误,则状态 com_state = DATAEX_IN_SEND(向 F 主机发送过程输入数据)。
Fapp_Send_FInput_Telegram()
该函数通过函数 psd_SendFInTele() 为 F 主机准备 F 输入报文。如果 psd_SendFInTele() 的返回值不是 SEND_FIN_TELE_OK,则 F 应用通过 FApp_Hard_Error() 切换到安全状态。如果未检测到错误,则状态 com_state = DATAEX_OUT_RCV(从 F 主机接收 F 输出数据)。
11.4 DiagnosticManager.c
DG_setEvent()
该函数将诊断事件号作为"到来"记录到诊断缓冲区中。需要将在 GSDML 中连同诊断文本一起定义的错误号作为传递参数。
DG_clearEvent()
该函数从诊断缓冲区中移除诊断事件号,即"离开诊断事件"。需要将在 GSDML 中连同诊断文本一起定义的错误号作为传递参数。
DG_update()
该函数作为任务循环调用;它处理缓冲区中登记的所有诊断信息。参见 DG_update() 任务流程图。
11.5 Psd_interface.c
Psd_interface.c 文件中实现的所有函数都用作 ERTEC 200P DevKit 软件与 PROFIsafe F 应用之间的接口。DevKit 与 F 应用周期异步运行,因此程序流程通过事件进行控制。
psdInterfaceInit()
该函数在 Power On 期间由 DevKit 的 PnUser_DeviceSetup() 调用,初始化 PROFIsafe 驱动程序、诊断管理器和 F 应用。返回值为 PNIO_OK,如果检测到错误则返回 PNIO_NOT_OK。
psdInterfaceSetLED()
该函数在 F 应用 Fapp_Process_Dat_Out() 中调用,将过程输出数据(如果检测到错误则为 0)切换到 DevKit 的 LED 上。
psdInterfaceF_App_Cycle()
该函数由 DevKit 的 MainAppl() 调用,实现 F 应用,周期性地处理相关逻辑。
psdInterfaceReceiveRecord()
该函数在收到数据记录时由 DevKit 的 PNIO_cbf_rec_write() 调用。根据数据记录号,为 F 应用设置控制事件(如 hasNewFParameter、faultInsertionTest 等),并将数据复制到 F 应用的相应缓冲区。返回值为 PNIO_OK,如果检测到错误则返回 PNIO_NOT_OK。
psdInterfaceSendRecord()
该函数在发生读数据记录请求(F 参数、Trace、故障插入测试)后由 DevKit 的 PNIO_cbf_rec_read() 调用。根据数据记录号,将 F 应用的数据复制到 DevKit 的传输缓冲区。返回值为 PNIO_OK,如果检测到错误则返回 PNIO_NOT_OK。
psdInterfaceSetProcessData()
该函数在 Power On 后的初始化期间由 DevKit 的 PNIO_cbf_ar_connect_ind() 调用;它将 F 应用的过程数据指针设置为 DevKit 的相应缓冲区。
psdInterfaceProcessDataReceived()
该函数在收到过程数据时由 DevKit 的 PNIO_cbf_data_read() 调用,设置事件 procDatReceived,并根据 IOPS 设置事件 processDataOutputIsDisabled。
psdInterfaceReceiveProcessData()
该函数在事件 procDatReceived 之后由 F 应用的 Fapp_Cycle() 调用,将过程输出数据从 DevKit 的缓冲区复制到 F 应用的过程数据缓冲区。
psdInterfaceProcessDataSend()
该函数在过程输入数据成功发送到 F 主机后由 DevKit 的 PNIO_cbf_data_write 调用,复位事件 procDatSendRequ,从而释放 DevKit 传输缓冲区以供 F 应用新的过程输入数据使用。
11.6 DevKit PnUsr_Api.c
PnUsr_DeviceSetup()
在此处调用 F 应用接口的初始化函数 psdInterfaceInit()。
PNIO_cbf_rec_read()
该函数扩展了记录索引 240(Fatal Error Report)和 201(PSD Trace Report);它会调用接口函数 psdInterfaceSendRecord()。
PNIO_cbf_rec_write()
该函数扩展了记录索引 128、129 和 240;它会调用接口函数 psdInterfaceReceiveRecord()。
11.7 DevKit iodapi_event.c
PNIO_cbf_data_write()
调用接口函数 psdInterfaceProcessDataSend()。
PNIO_cbf_data_read()
调用接口函数 psdInterfaceProcessDataReceived()。
PNIO_cbf_ar_connect_ind()
调用接口函数 psdInterfaceSetProcessData()。
11.8 DevKit usriod_main.c
MainAppl()
调用接口函数 psdInterfaceF_App_Cycle()。
12. 错误号映射
由于 psd_FParBuild() 和 psd_GetFOutData() 的返回值与 GSDML 中连同错误文本一起定义的错误号不一致,因此需要将返回值映射到 PROFIsafe 特定的错误号。
诊断文本已标准化,包含在 PROFIsafe 配置文件中("PROFIsafe-Profile_3192_V261_Aug14.pdf",第 39 页)。
下表给出了转换后错误号的概览:
| 十六进制错误号 | 十进制 | PSD 返回值(十六进制) | 说明 | psd_FParBuild() | psd_GetFOutData() |
|---|---|---|---|---|---|
| 0x40 | 64 | 0x4A | 安全目标地址不匹配(F_Dest_Add) | X | |
| 0x41 | 65 | 0x41 | 安全目标地址无效(F_Dest_Add) | X | |
| 0x42 | 66 | 0x54 / 0x2C | 安全源地址无效或不匹配(F_Source_Add) | X | |
| 0x43 | 67 | 0x79 | 安全看门狗时间值为 0 ms(F_WD_Time、F_WD_Time_2) | X | |
| 0x44 | 68 | 0x86 | 参数 "F_SIL" 超过特定设备应用的 SIL | X | |
| 0x45 | 69 | 0x98 | 参数 "F_CRC_Length" 与生成值不匹配 | X | |
| 0x46 | 70 | 0xAB | F 参数集版本不正确 | X | |
| 0x47 | 71 | 0xB5 | 接收的 F 参数块中数据不一致(CRC1 错误) | X | |
| 0x48 | 72 | 0xCD / 0x72 | 设备特定或未指定的诊断信息,参见手册 | X | |
| 0x4B | 75 | 0xE0 | iParameter 不一致(iParCRC 错误) | X | |
| 0x4C | 76 | 0x1F | 不支持 F_Block_ID | X | |
| 0x4D | 77 | 0x67 | 传输错误:数据不一致(CRC2 错误) | X | |
| 0x4E | 78 | 0x79 | 传输错误:超时(F_WD_Time 或 F_WD_Time_2 已耗尽) | X |
表格右侧表明哪个函数发送哪种诊断。
13. DevKit 的 LED 状态
本实现中控制了多个 LED,以便更好地识别错误来源。
| LED | 含义 | 处理方法 | ||
|---|---|---|---|---|
| 闪烁 | 亮 | 闪烁 | 硬错误情况 | 断电/上电 |
| 灭 | 闪烁 | 灭 | 有到来的诊断事件 | 评估诊断并处理错误 |
| 闪烁 | 灭 | 灭 | 没有参数分配 | 如果持续闪烁,请检查 TIA Portal 中的参数分配 |
| 亮 | 灭 | 灭 | 循环数据交换 | ------ |
14. 用户 LED 输出
LED 位于 DevKit 的端口 X50 上方,用于表示被切换的输出。
在本应用中,只切换前 4 个 LED,或者在非冗余运行模式下切换到后 4 个 LED。切换哪个 LED 取决于过程数据的前 4 位。
最左边的 LED 是 LSB,左边第四个 LED 是 MSB。在非冗余运行模式下,后 4 个 LED 从右侧开始与左侧 4 个 LED 反向地额外切换。
- 蓝色状态 LED(GPIO 连接器已插入)
- 红色 LED 用于输出用户数据(左 LSB,右 MSB)
- 绿色 LED 用于输出用户数据(非冗余运行模式下)
**注意:**左侧第一个 LED 始终点亮,因为它仅指示用户 GPIO 的连接器是否已插入。用户 GPIO 的连接器必须已插入(端口 X42,引脚 9、10),以便 GPIO 能够由应用程序控制。
参考资料
PROFIsafe-Profile_3192_V26MU1_Aug18.pdf------PROFIsafe Starter Kit V3.5.2 的一部分profisafe_driver_v2_2_3_programming_manual_en-US.pdf------PROFIsafe Starter Kit V3.5.2 的一部分Interface_Description_PN_IO_DevKits_V4.7.0------EvalKit_ERTEC200P 的一部分Guideline_EvalKit_ERTEC200P_V4.7.0.pdf------EvalKit_ERTEC200P 的一部分Manual_ERTEC200P-2_V1_0.pdf------EvalKit_ERTEC200P 的一部分Howto use J-link JTAG Debugger_on_EB200P_V1_1.pdf------本应用示例的一部分GSDML_GettingStarted_V1_5.pdf------本应用示例的一部分GSDML-Spec_2352_V243_May22.pdf------当前版本可在 profibus.com 上获取
术语表
| 术语 | 含义 |
|---|---|
| CRC | 循环冗余校验(Cyclic Redundancy Check) |
| DevKit | 评估套件 EK-ERTEC200P PN IO V4.3 |
| Embedded Software | 固件的通俗说法,安装在 F 设备上的硬件级软件 |
| F-device | 能够执行 PROFIsafe 协议、由 F 主机提示交换数据的被动通信伙伴 |
| F-host | 能够执行 PROFIsafe 协议、提示 F 设备交换数据的数据处理单元 |
| FIT | 故障插入测试(Fault Insertion Test) |
| F-parameter | PROFIsafe 参数 |
| FW | 固件,也称"嵌入式软件" |
| GPIO | 通用输入输出(General Purpose Input Output),可用作输出或输入的引脚 |
| GSDML | 通用站描述标记语言(General Station Description Markup Language) |
| HW | 硬件 |
| PROFIsafe trailer | 由状态/控制字节和安全信息组成 |
| PSD | 用于 F 设备的 PROFIsafe 驱动程序 |
| SIL | 安全完整性等级(Safety Integrity Level) |
| WD | 用于运行时监控的看门狗 |
**注意:**本文基于西门子官方文档《Application example for implementation of the PROFIsafe driver on the Evaluation Kit EK-ERTEC 200P-2 V4.7 Getting Started》翻译整理,原始版权归 Siemens AG 所有。文中函数名、文件名及代码标识符保留英文原文,以保持技术准确性。