Iot framework ServerSuperIO tutorial-4. For example, you can develop a device driver that supports both serial and network communication. Appendix: support for Windows 10 IOT and win10iot in the future

Source: Internet
Author: User

Iot framework ServerSuperIO tutorial-4. For example, you can develop a device driver that supports both serial and network communication. Appendix: support for Windows 10 IOT and win10iot in the future

1. C # Introduction to cross-platform Iot communication framework ServerSuperIO (SSIO)

Serialization | Iot framework ServerSuperIO tutorial 1.4 communication modes and mechanisms.

Serialization | Iot framework ServerSuperIO tutorial 2. service instance configuration parameters

Serialization | Iot framework ServerSuperIO tutorial-3. Device Driver Introduction

 

Note: ServerSuperIO may be transplanted to Windows 10 IOT. In the future, it is possible to develop a device driver. sub-branches can form a complete solution on servers and embedded devices.

Now some code has been debugged. It may take some time, usually at night, and the time is limited. For example:

 

Contents

4. For example, develop a device driver that supports both serial and network communication... 2

4.1 overview... 2

4.2 communication agreement provision... 2

4.2.1 sending and reading real-time data command protocol... 2

4.2.2 parse Real-time Data Protocol... 3

4.2.3 sending and receiving data example... 3

4.3 develop device drivers... 3

4.3.1 construct a real-time data persistence object (not required)... 3

4.3.2 construct a parameter data Persistent object... 5

4.3.3 build the sending and parsing protocol command object... 5

4.3.4 build protocol-Driven Object... 6

4.3.5 build a device driver object... 8

4.4 build the Host Program... 12

4.5 running effect... 15

 

 

4. For example, develop a device driver that supports both serial and network communication. 4.1 Overview

As an Iot communication framework, you must support multiple communication links and complete interaction between multiple communication protocols, such as Modbus and custom protocols. However,There is a problem: for the same hardware device or sensor, do you need to write code separately to complete data collection and control for the serial port and network communication methods?From the perspective of reality, the business logic of the same hardware must be the same, so the ServerSuperIO Iot framework allows the development of a set of device drivers, both the serial port and network communication modes are supported.

Simple communication, simple interaction, and simple business ......If a lot of simple problems are combined, it will not be easy, so there must be a framework to re-Simplify the numerous problems.

4.2 communication agreement provision

Before developing a device driver, you must first know the communication protocol, just like the language in which two people communicate. For communication protocols, we define a simple interaction method, that is, sending commands to extract data information.

4.2.1 sending and reading real-time data Command Protocol

The 0x61 Command sent by the computer is a real-time data read command. A total of 6 bytes are sent, and the checksum is the sum starting from the "Slave address, does not include "Data Header", "checksum", and "protocol termination ".

The data frame of the sending command is as follows:

Frame Structure

Data Header

Slave address

Command code

Checksum

Agreement ended

0x55

0xAA

 

0x61

 

0x0D

Bytes

1

1

1

1

1

1

4.2.2 parse Real-time Data Protocol

After receiving the command for reading real-time data, the lower computer verifies the data and returns the real-time data. The sum is the sum starting from the "Slave address, does not include "Data Header", "checksum", and "protocol termination ".

The received data frame is as follows:

Frame Structure

Data Header

Slave address

Command code

Traffic

Signal

Checksum

Agreement ended

0x55

0xAA

 

0x61

Floating Point Type

Floating Point Type

 

0x0D

Bytes

1

1

1

1

4

 

4

1

1

4.2.3 sending and receiving data example

Sending (hexadecimal): 0x55 0xaa 0x00 0x61 0x61 0x0d

Receive (hexadecimal): 0x55 0xaa 0x00 0x61 0x43 0x7a 0x00 0x00 0x43 0xb4 0x15 0x0d

Traffic Data: 250.00

Signal data: 360.00

4.3 Development Device Driver 4.3.1 build real-time data persistence object (not required)

1. Through the communication protocol that returns data, there are two dynamic variables: Traffic and signal. We need to create a dynamic object entity class, which is mainly used for data interaction between Protocol drivers and device drivers. The Code is as follows:

Public class Dyn {private float _ Flow = 0.0f; // <summary> // traffic // </summary> public float Flow {get {return _ Flow ;} set {_ Flow = value ;}} private float _ Signal = 0.0f; /// <summary> // Signal // </summary> public float Signal {get {return _ Signal;} set {_ Signal = value ;}}}

2. Our main task is to create a real-time data persistence object class, cache data information in real time, and save the real-time data information to the database or other storage media. The code for the real-time data persistence object class is as follows:

Public class DeviceDyn: DeviceDynamic {public DeviceDyn (): base () {Dyn = new Dyn ();} public override string GetAlertState () {throw new NotImplementedException ("no alarm information");} public override object Repair () {return new DeviceDyn () ;}public Dyn {get; set ;}}

The DeviceDyn class inherits from DeviceDynamic. Because the alarm information of each hardware device may be different, the GetAlertState function can implement this function, but the SSIO framework does not directly reference it; this class is essentially serializable and may cause file damage without mutual exclusion. Therefore, Repair can complete the Repair function and implement this function in the DeviceDynamic base class. In addition, the DeviceDynamic base class comes with two functions. The Save function is used to persist (serialize) such information, and the Load function is used to obtain (deserialize) such information, which can be used in device drivers.

4.3.2 construct a parameter data Persistent Object

Generally, if a hardware device has a read parameter command, the returned parameters also need to be stored persistently, and the parameters of each device may be different. A Scalable interface is provided here. This Communication Protocol does not contain Protocol Descriptions related to device parameters. However, we also need to create a parameter data persistence object class without writing any extended parameter attributes, the parameter interface is referenced in the SSIO framework, which is required. The Code is as follows:

public class DevicePara:ServerSuperIO.Device.DeviceParameter{        public override object Repair()        {            return new DevicePara();        }}

DevicePara inherits from the DeviceParameter class, which is similar to the real-time data persistence object and can be a parameter.

4.3.3 build the sending and parsing protocol command object

Interacting with devices involves a lot of interactive commands or command code. These commands exist in the SSIO framework in the form of protocol command objects, which generally include three parts:Execute Command interface, package and send data interface, and parse and receive data interface.

For the above communication protocol, there is a 61 command, then we can build a protocol command object based on the 61 command name, including sending data and parsing data. If there are other command codes, let alone. The Code is as follows:

Internal class DeviceCommand: ProtocolCommand {public override string Name {get {return "61" ;}} public override void ExcuteCommand <T> (T t) {throw new NotImplementedException ();} public override byte [] Package <T> (string code, T1 t1, T2 t2) {// send: 0x55 0xaa 0x00 0x61 0x61 0x0d byte [] data = new byte [6]; data [0] = 0x55; data [1] = 0xaa; data [2] = byte. parse (code); data [3] = 0x61; data [4] = this. pr OtocolDriver. getCheckData (data) [0]; data [5] = 0x0d; return data;} public override dynamic Analysis <T> (byte [] data, T t) {Dyn dyn = new Dyn () // generally, if the lower computer is a single chip, the level and level of received data must be exchanged for normal parsing. Byte [] flow = BinaryUtil. subBytes (data, 4, 4, true); dyn. flow = BitConverter. toSingle (flow, 0); byte [] signal = BinaryUtil. subBytes (data, 8, 4, true); dyn. signal = BitConverter. toSingle (signal, 0); return dyn ;}}

Build protocol commands must all inherit from ProtocolCommand. According to the communication protocol, the Name attribute returns 61 as a keyword. Package is the data information to be sent; analysis parses the received data. So a simple protocol command driver is built.

4.3.4 build protocol-Driven Object

With the protocol commands, we need to build a protocol-Driven Object. This is also the reason why the SSIO framework supports custom protocols and is associated with the device-driven interfaces, it is also referenced in the advanced application of the SSIO framework. It is critical to construct this object. The Code is as follows:

internal class DeviceProtocol:ProtocolDriver{        public override bool CheckData(byte[] data)        {            if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)            {                return true;            }            else            {                return false;            }        }        public override byte[] GetCommand(byte[] data)        {            return new byte[] { data[3] };        }        public override int GetAddress(byte[] data)        {            return data[2];        }        public override byte[] GetHead(byte[] data)        {            return new byte[] { data[0], data[1] };        }        public override byte[] GetEnd(byte[] data)        {            return new byte[] { data[data.Length - 1] };        }        public override byte[] GetCheckData(byte[] data)        {            byte checkSum = 0;            for (int i = 2; i < data.Length - 2; i++)            {                checkSum += data[i];            }            return new byte[] { checkSum };        }        public override string GetCode(byte[] data)        {            throw new NotImplementedException();        }        public override int GetPackageLength(byte[] data, IChannel channel, ref int readTimeout)        {           throw new NotImplementedException();        }}

The DeviceProtocol driver inherits from ProtocolDriver. A device driver has only one protocol driver, and a protocol driver can have multiple protocol commands (such as 61 commands ). The CheckData function in this class is critical. The device driver base class in the SSIO framework references it, mainly to verify the completion of received data and whether it complies with the Protocol, thus determining the communication status: communication is normal, communication is interrupted, communication interference, and communication is unknown. Different communication statuses also determine which function interfaces are called in the device driver: Communicate, CommunicateInterrupt, CommunicateError, and CommunicateNone.

4.3.5 build a device driver object

After all the above basic work is done, we will now build the core part of the device driver, that is, the unique interface between the SSIO framework and the device driver for interconnection, coordination, and scheduling. After writing this interface, the device driver can directly run on SSIO and interact with the hardware device. Directly run the Code:

Public class DeviceDriver: RunDevice {private DeviceDyn _ deviceDyn; private DevicePara _ devicePara; private DeviceProtocol _ protocol; public DeviceDriver (): base () {_ devicePara = new DevicePara (); _ deviceDyn = new DeviceDyn (); _ protocol = new DeviceProtocol ();} public override void Initialize (string devid) {this. protocol. initDriver (this. getType (), null); // initialize the device parameter information _ devicePara. deviceID = devid ;/ /The device ID must be assigned a value first, because you need to find the corresponding parameter file. If (System. IO. file. exists (_ devicePara. savePath) {// If the parameter file exists, obtain the parameter instance _ devicePara = _ devicePara. load <DevicePara> ();} else {// If the parameter file does not exist, serialize the _ devicePara file. save <DevicePara> (_ devicePara);} // initialize the real-time device data information _ deviceDyn. deviceID = devid; // The device ID must be assigned a value first, because you need to find the corresponding real-time data file. If (System. IO. file. exists (_ deviceDyn. savePath) {// If the parameter file exists, the parameter instance _ deviceDyn = _ deviceDyn is obtained. load <DeviceDyn> ();} else {// If the parameter file does not exist, serialize the file _ deviceDyn. save <DeviceDyn> (_ deviceDyn) ;}} public override byte [] GetConstantCommand () {return this. protocol. driverPackage <String> ("0", "61", null);} public override void Communicate (ServerSuperIO. communicate. IRequestInfo info) {Dyn dyn = this. protocol. dri VerAnalysis <String> ("61", info. Data, null); if (dyn! = Null) {_ deviceDyn. dyn = dyn;} OnDeviceRuningLog ("normal communication");} public override void CommunicateInterrupt (ServerSuperIO. communicate. IRequestInfo info) {OnDeviceRuningLog ("Communication interruption");} public override void CommunicateError (ServerSuperIO. communicate. IRequestInfo info) {OnDeviceRuningLog ("communication interference");} public override void CommunicateNone () {OnDeviceRuningLog ("Communication unknown");} public override void Alert () {return ;} public override void Save () {try {_ deviceDyn. save <DeviceDyn> (_ deviceDyn);} catch (Exception ex) {OnDeviceRuningLog (ex. message) ;}} public override void Show () {List <string> list = new List <string> (); list. add (_ devicePara. deviceName); list. add (_ deviceDyn. dyn. flow. toString (); list. add (_ deviceDyn. dyn. signal. toString (); OnDeviceObjectChanged (list. toArray ();} public override void UnknownIO () {OnDeviceRuningLog ("unknown Communication Interface");} public override void CommunicateStateChanged (ServerSuperIO. communicate. communicateState comState) {OnDeviceRuningLog ("");} public override void ChannelStateChanged (ServerSuperIO. communicate. channelState channelState) {OnDeviceRuningLog ("channel status change");} public override void Exit () {OnDeviceRuningLog ("Exit device");} public override void Delete () {OnDeviceRuningLog ("delete device");} public override object GetObject () {throw new NotImplementedException ();} public override void ShowContextMenu () {throw new NotImplementedException ();} public override implements DeviceDynamic {get {return _ deviceDyn ;}} public override IDeviceParameter DeviceParameter {get {return _ devicePara ;}} public override IProtocolDriver Protocol {get {return _ protocol ;}} public override DeviceType {get {return DeviceType. common ;}} public override string ModelNumber {get {return "serversuperio" ;}} public override System. windows. forms. control DeviceGraphics {get {throw new NotImplementedException ();}}}

Real-time dynamic data object _ deviceDyn, parameter data object _ devicePara, and protocol-Driven Object _ Protocol are provided to interfaces: DeviceDynamic, DeviceParameter, and protocol, respectively, to provide SSIO with reference basic property parameters.

Initialize is a function interface for device driver initialization. In this interface, two main tasks are completed: Initialize protocol driver and parameter information. Using this. Protocol. InitDriver (this. GetType (), null); the Code can load all Protocol commands into the Protocol-driven cache for real-time calls. Of course, you can also do other work here, but pay attention to exception handling.

DeviceType: This is the device type. It is generally set to Common. Other function interfaces are described in detail in "Iot framework ServerSuperIO tutorial-3. Introduction to device drivers". For more information, see.

4.4 build a Host Program

A simple device driver has been developed, and the light driver is not enough. Therefore, we need to write several lines of code based on the SSIO framework to complete a Host Program and instantiate the device driver, run in the SSIO service instance to complete communication and interaction between the serial port and the network. The Code is also very simple. The Code is as follows:

Class Program {static void Main (string [] args) {DeviceDriver dev1 = new DeviceDriver (); dev1.DeviceParameter. deviceName = "serial device 1"; dev1.DeviceParameter. deviceAddr = 0; dev1.DeviceParameter. deviceID = "0"; dev1.DeviceDynamic. deviceID = "0"; dev1.DeviceParameter. COM. port = 1; dev1.DeviceParameter. COM. baud = 9600; dev1.CommunicateType = CommunicateType. COM; dev1.Initialize ("0"); DeviceDriver dev4 = new DeviceDriver (); dev4.DeviceParameter. deviceName = "network device 2"; dev4.DeviceParameter. deviceAddr = 0; dev4.DeviceParameter. deviceID = "3"; dev4.DeviceDynamic. deviceID = "3"; dev4.DeviceParameter. NET. remoteIP = "127.0.0.1"; dev4.DeviceParameter. NET. remotePort = 9600; dev4.CommunicateType = CommunicateType. NET; dev4.Initialize ("3"); IServer server = new ServerFactory (). createServer (new ServerConfig () {ServerName = "service instance 1", SocketMode = SocketMode. tcp, ControlMode = ControlMode. loop, CheckSameSocketSession = false, StartCheckPackageLength = false,}); server. addDeviceCompleted + = server_AddDeviceCompleted; server. deleteDeviceCompleted + = server_DeleteDeviceCompleted; server. socketConnected + = server_SocketConnected; server. socketClosed + = server_SocketClosed; server. start (); server. addDevice (dev1); server. addDevice (dev4); while ("exit" = Console. readLine () {server. stop () ;}} private static void server_SocketClosed (string ip, int port) {Console. writeLine (String. format ("disconnected: {0}-{1} succeeded", ip, port);} private static void server_SocketConnected (string ip, int port) {Console. writeLine (String. format ("connection: {0}-{1} succeeded", ip, port);} private static void server_AddDeviceCompleted (string devid, string devName, bool isSuccess) {Console. writeLine (devName + ", add:" + isSuccess. toString ();} private static void server_DeleteDeviceCompleted (string devid, string devName, bool isSuccess) {Console. writeLine (devName + ", delete:" + isSuccess. toString ());}}}

You can see this code. We will introduce the specific control mode one by one. When building a Host Program, do not reference the service instance as follows: server. ChannelManager, server. ControllerManager, and server. DeviceManager. Although such interfaces are provided mainly for internal use of the SSIO framework, we do not need to operate these interfaces separately. Some netizens write this way, and it becomes a pure communication I/O framework, thus losing the value of the SSIO framework itself. As a secondary developer, you only need to set the device driver parameters and add or delete devices to or from the service instance. All other operations are completed by the SSIO framework.

4.5 Running Effect

 

 

1. [serialization] C # communication (Serial Port and network) Framework Design and Implementation

2. [Open Source] C # cross-platform Iot communication framework ServerSuperIO (SSIO) Introduction

2. Overall system construction solution using SuperIO and open-source cross-platform Iot framework ServerSuperIO

3. C # technical route of industrial IoT and integrated system solutions (data sources, data collection, data upload and receiving, ActiveMQ, Mongodb, WebApi, and mobile App)

5. ServerSuperIO Open Source Address: https://github.com/wxzz/ServerSuperIO

Internet of Things & integrated technology (. NET) QQ Group:54256083

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.