代码生成

示例:DF1 MSpec

qianmoQqianmoQ· 更新于 2026-10-01· 阅读 5 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

DF1 协议有三种基本消息:命令消息、确认消息和否认消息。0x10 用作分隔符,用于区分这些消息以及命令消息的各个部分。

ACKNAK
10 0610 15

以下是全双工模式下、使用 CRC 作为校验和的读命令消息的完整形式:

NameDLESTXDSTSRCCMDSTSTNSADDRSIZEDLEETXCRC
Value1002XXXX0100XX XXXX XX021003XX XX

与之对应的、包含所请求字节数据的响应:

NameDLESTXDSTSRCCMDSTSTNSDATASIZEDLEETXCRC
Value1002XXXX4100XX XXXX XX021003XX XX

每条消息都以 DLE = 0x10 开头。第二个字节用于表明随后的消息类型,在命令消息的情况下它是 0x02。DST 和 SRC 分别指定消息的目标和来源。CMD = 0x01 表示请求的是一次非保护读取,命令响应码总是通过加上 0x40 得到。STS 是状态字节,TNS 是由主站递增的事务计数器,用于识别特定的消息响应。ADDR 是被请求的内存地址,SIZE 指定要读取的字节数。DLE + ETX 标记消息的结束,最后两个字节是基于之前发送的字节计算得出的 CRC。

以下是用于建模该行为的 MSpec:

[discriminatedType DF1Symbol
    [const            uint 8       messageStart 0x10]
    [discriminator    uint 8       symbolType]
    [typeSwitch 'symbolType'
        ['0x02' DF1SymbolMessageFrame
            [simple   uint 8       destinationAddress]
            [simple   uint 8       sourceAddress]
            [simple   DF1Command   command]
            [const    uint 8       messageEnd 0x10]
            [const    uint 8       endTransaction 0x03]
            [checksum uint 16      'crc' 'STATIC_CALL("org.apache.plc4x.java.df1.readwrite.utils.StaticHelper.crcCheck", destinationAddress, sourceAddress, command)']
        ]
        ['0x06' DF1SymbolMessageFrameACK
        ]
        ['0x15' DF1SymbolMessageFrameNAK
        ]
    ]
]

[discriminatedType DF1Command
    [discriminator uint 8  commandCode]
    [simple    uint 8       status]
    [simple    uint 16      transactionCounter]
    [typeSwitch 'commandCode'
        ['0x01' DF1UnprotectedReadRequest
            [simple uint 16    address]
            [simple uint 8     size]
        ]
        ['0x41' DF1UnprotectedReadResponse
            [manualArray  uint 8 'data' terminated 'STATIC_CALL("org.apache.plc4x.java.df1.readwrite.utils.StaticHelper.dataTerminate", io)' 'STATIC_CALL("org.apache.plc4x.java.df1.readwrite.utils.StaticHelper.readData", io)' 'STATIC_CALL("org.apache.plc4x.java.df1.readwrite.utils.StaticHelper.writeData", io, element)' 'STATIC_CALL("org.apache.plc4x.java.df1.readwrite.utils.StaticHelper.dataLength", data)']
        ]
    ]
]

基本对象是 DF1Symbol,其第二个字节用于通过 typeSwitch 区分不同的消息类型。对于命令消息,消息帧中包含 DF1Command,以便进一步区分命令类型。目前仅实现了非保护读取及其响应。

评论

登录后参与评论

正在加载评论…