欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于IEC61499 的数据交换信息抽象语法ASN.1

程序员文章站 2022-03-12 15:25:16
...

前言

 IEC61499 是一个分布式控制系统功能块标准。多个设备之间,和其它外部设备之间都有信息交换。这种信息交换通过通信功能块来实现。通信功能块包括:

  单向通信功能块:Publish/Subscribe

关于IEC61499 的数据交换信息抽象语法ASN.1

  双向通信功能块:Client/Server

关于IEC61499 的数据交换信息抽象语法ASN.1

     设备之间的消息是功能块的数据(IEC61499-FBDATA),它们由类型和值构成。通信功能块可能涉及多个数据的输入输出。每个输入输出数据可以是简单的单值数据类型,也可以是数组类型(Constructed)。所以它们要交换多个数据。多个数据的信息抽象标识采用了ASN.1 的编解码方式。

ASN.1

ASN.1抽象语法标记(Abstract Syntax Notation One)是国际标准ISO 8825-1。使用紧凑的方式抽象标识计算机内部的数据,比如 整型数,布尔数,浮点数等等。正是由于ASN.1 是一个通用的语言,所以采用了描述的语法。初学起来感觉十分的复杂。在IEC61499 标准中只是采用了ISO8825-1 中的基本编码规则。并且在IEC61499-1 标准的附录E 信息交换 中做了进一步的规范和描述。结合起来学习就比较清晰了。

ASN.1 基本编码规则

一个数据值的编码由四个部分构成

标识八比特组(identifier octets)

长度八比特组(length octets)

内容八比特组(contents octets)

内容结束八比特组(end of content octets)

内容结束八比特组是可以缺省的。所以大多数情况下是三段式标识

|  identifier octets | length octets | contents octets |

有时也称为TLV三元组<Type,Length, Value>

identifier 标识的定义

 

关于IEC61499 的数据交换信息抽象语法ASN.1

 

第8,第7位代表了tag 的类

关于IEC61499 的数据交换信息抽象语法ASN.1

 

在IEC61499-1 附录E 中,对FBDATA 的ASN.1 编码规则做了进一步的规范

-tag 的类为Application。所有8,7 为0,1

-基本数据类型的tag number

BOOL0                0

BOOL1               1

SINT                2

INT                    3

DINT                  4

LINT                         5

USINT                7

UDINT                8

ULINT                9

REAL                 10

LREAL                11

TIME                12

DATE                13

TIME_OF_DAY    14

DATE_AND_TIME        15

BYTE                   17

WORD                 18

DWORD              19

LWORD              20

WSTRING            21

 

数组

ArrayVariable     22

IEC61499 FBDATA 的ASN.1 编码

(IEC61499-1 附录E)中说可以是两种:

-基本(BASIC) 编码

 符合ISO/IEC 8825-1 的基本编码规则

-紧凑(COMPACT)编码

4DIAC 中使用的是ComPACT 编码。

  对于上面的数据类型省却了长度(length octets),不同数据类型的长度是默认的。

关于IEC61499 的数据交换信息抽象语法ASN.1

 简单类型数据编码

采用compact 编码,多个数据连续排列。

例如 4个 INT

tag=01000011=0x43 其中class=01,P/Construct=0,tag number=3=00011

最后的编码

0x43 0x00,0x00, 0x43 0x00,0x00, 0x43 0x00,0x00, 0x43 0x00,0x00

数组类型的编码

   -tag 第6位为 1 Constructed

   - length 编码成为 UINT ,16位无符号数

   - 数组的第一个元素带有tag (COMPACT Encoding),后面的元素缺省了tag

例如 LREAL[2] 的编码为

  tag = 0x76=011 10110 其中

 class=01,P/Constructed =1 ,tag number=22=10110

length=x0002

contents=8 octetX2

第一个元素(LREAL)的tag为

 tag=01001011=0x4b 其中 class =01 /Construct=0,tag number=11=0x0b=01011

0x4b 是LREAL 类型。后面是两个LREAL,每个64位,8 个字节)。

最后的编码为

0x76,0x00,0x02,0x4b,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00  

 

程序实例

使用这个简单软件,可以显示出Client 功能块发送的ASN.1 编码的FBDATA

package main

import (
        "fmt"
        "net"
        "os"
)
func main() {
        arguments := os.Args
        if len(arguments) == 1 {
                fmt.Println("Please provide a port number!")
                return
        }
        PORT := ":" + arguments[1]

        s, err := net.ResolveUDPAddr("udp4", PORT)
        if err != nil {
                fmt.Println(err)
                return
        }

        connection, err := net.ListenUDP("udp4", s)
        if err != nil {
                fmt.Println(err)
                return
        }
       
        defer connection.Close()
		buffer := make([]byte, 1024)

	serveraddr, _ := net.ResolveUDPAddr("udp", "192.168.31.108:8881")
	client, _ := net.DialUDP("udp4", nil, serveraddr)
        for {
			 //   n, addr, err := connection.ReadFromUDP(buffer)
                 n, _, _ := connection.ReadFromUDP(buffer)
                 txbuf := make([]byte, n)
                for i:=0;i<n;i++ {
                                        fmt.Printf("0x%02x ",buffer[i])
                                        txbuf[i]=buffer[i]
				}
		 fmt.Printf("length=%d\n",n)  
                _, err := client.Write(txbuf)
                if err != nil {
                        fmt.Println(err)
                        return
                } 
        }
}

     相信我将IEC61499 标准的FBDATA ASN.1 编解码解释清楚了。没有去大幅介绍ASN.1 的抽象概念。当然,为了写清楚这些,我还特意化了点小钱,下载了ISO8825-1 2008 版标准。

          写博客,深入简出非常重要。

相关标签: 4DIAC IEC61499