IEC61499 編程(1)-UDP Publish/Subscribe 與Golang 通信

        通過IEC61499 功能塊和外部軟件通信,同樣能夠擴展應用程序的性能。比如使用其它語言實現與雲端數據庫的通信。不需要實現特殊的功能塊,而是通過其它程序來實現訪問數據庫的功能,功能塊通過Publish/subscribe 機制與其它程序通信。如果IEC61499 運行時forte和其它應用程序在同一個計算機中運行,相信傳輸效率還是比較高的,畢竟只是內存之間的數據傳輸。這一方式使IEC 61499 標準與物聯網,邊緣計算,雲計算,人工智能等新技術相融合。是非常令人激動的事情。爲此,我先做了一些實驗。

測試方法

  1. 使用Eclipse 4DIAC 開發環境編寫IEC 功能塊。
  2. 使用golang 編寫了一個UDPTest 程序。該程序接收publish 功能塊發送的數據,顯示在控制終端上,並且轉發到Subscribe 的端口。注意,Publsh/subscribe 不能使用同一個端口。

 

IEC61499 功能塊網

Golang程序

package main

import (
        "fmt"
        "math/rand"
        "net"
        "os"
     //   "strconv"
     //   "strings"
        "time"
)

func random(min, max int) int {
        return rand.Intn(max-min) + min
}

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)
		
        rand.Seed(time.Now().Unix())
	serveraddr, _ := net.ResolveUDPAddr("udp", "192.168.43.52: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
                } 
        }
}

結果

首先運行udptest程序。

>./udptest 8888

在udptest 顯示的結果:

從中可以看出,4DIAC 的Publish /subscribe 的UDP 格式爲:

數據類型ID/數據/數據類型ID/數據。。。

在這個應用中,0x43 表示 INT ,而0x4a 表示是ULINT 

在Forte 的源代碼src/core/datatypes/forte.any.h 中,有DataTypeID 定義,好像INT 爲0x03,ULINT 爲0x0a 是相互對應的。至於前面的4 是什麼意思還不清楚。

 enum EDataTypeID{
      e_ANY, e_BOOL, e_SINT, e_INT, e_DINT, e_LINT, e_USINT, e_UINT, e_UDINT, e_ULINT, e_BYTE, e_WORD, e_DWORD, e_LWORD, e_DATE, e_TIME_OF_DAY, e_DATE_AND_TIME, e_TIME, //until here simple Datatypes
      e_REAL,
      e_LREAL,
      e_STRING,
      e_WSTRING,
      e_DerivedData,
      e_DirectlyDerivedData,
      e_EnumeratedData,
      e_SubrangeData,
      e_ARRAY, //according to the compliance profile
      e_STRUCT,
      e_External = 256, // Base for CIEC_ANY based types outside of the forte base
      e_Max = 65535 // Guarantees at least 16 bits - otherwise gcc will optimizes on some platforms
    };

4DIAC 監控的結果

下面這個是發送和接收數組

運行的結果:

看來 76 是代表數組 ,0x00,0x02 是長度,0x4b 是LREAL 類型。後面是兩個LREAL (每個64位,8 個字節)。

可惜,目前只支持3 個值的數組 (嗨!),背景資料可以參考我的博文:

當物聯網遇見 IEC61499

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章