《连载 | 物联网框架ServerSuperIO教程》- 一7.集成戈尔德en实时数据库,高并发保存测点数据。附:3.四 宣布与版本更新表明。

1.C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

葡京在线开户,Android游戏开发实践(一)之NDK与JNI开发0四

有了前边几篇NDK与JNI开发有关基础做铺垫,再来通过代码表明下这上头具体的操作以及壹些重大的底细。那么,就继续NDK与JNI的上学计算。

作者:AlphaGL。版权全体,欢迎保留原著链接实行转载 🙂

传送门:
Android游戏开发实践(一)之NDK与JNI开发0一
Android游戏开发实践(一)之NDK与JNI开发0二
Android游戏开发执行(一)之NDK与JNI开发0三

《连载 |
物联网框架ServerSuperIO教程》一.肆种简报情势机制。

JavaVM和JNIEnv

jni.h头文件中定义了三种主要的数据结构JavaVMJNIEnv,并且在C和C++中它们的完结是不一致的(通过#if defined(__cplusplus)宏定义落成)。本质都是指向封装了JNI函数列表的指针。

《连载 |
物联网框架ServerSuperIO教程》二.劳动实例的配置参数表达

JavaVM

是java虚拟机在jni层的象征。在Android中1个JVM只同意有1个JavaVM对象。能够在线程间共享贰个JavaVM对象。

《连载 | 物联网框架ServerSuperIO教程》-
3.配备驱动介绍

JavaVM声明

在jni中针对C语言环境和C++语言环境的JavaVM完毕有所差异。

C版的JavaVM声明为:

typedef const struct JNIInvokeInterface* JavaVM;

struct JNIInvokeInterface {
    void*       reserved0;
    void*       reserved1;
    void*       reserved2;

    jint        (*DestroyJavaVM)(JavaVM*);
    jint        (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
    jint        (*DetachCurrentThread)(JavaVM*);
    jint        (*GetEnv)(JavaVM*, void**, jint);
    jint        (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
};

C++版的JavaVM声明为:

typedef _JavaVM JavaVM;

struct _JavaVM {
    const struct JNIInvokeInterface* functions;

#if defined(__cplusplus)
    jint DestroyJavaVM()
    { return functions->DestroyJavaVM(this); }
    jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
    { return functions->AttachCurrentThread(this, p_env, thr_args); }
    jint DetachCurrentThread()
    { return functions->DetachCurrentThread(this); }
    jint GetEnv(void** env, jint version)
    { return functions->GetEnv(this, env, version); }
    jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)
    { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }
#endif /*__cplusplus*/
};

《连载 |
物联网框架ServerSuperIO教程》-4.如开发一套设备驱动,同时帮助串口和互连网通信。

JavaVM得到格局

(一)jni动态注册的法门。在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM*
vm, void* reserved),并传入JavaVM指针:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {

}

(贰)在当地代码中通过调用jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*)来创建。

《连载 | 物联网框架ServerSuperIO教程》-
5.轮询通信情势开发及注意事项。

JNIEnv

简单易行来说,便是JNIEnv提供了具备JNI函数调用的接口。无法在线程间共享同1个JNIEnv变量,仅在创设它的线程有效,借使要在任何线程访问JVM,必要调用AttachCurrentThreadAttachCurrentThreadAsDaemon将近日线程与JVM绑定。再经过JavaVM对象的GetEnv来获取JNIEnv

《连载 | 物联网框架ServerSuperIO教程》-
陆.并发通信方式开发及注意事项

JNIEnv声明

JavaVM类似,JNIEnv在C和C++语言中的注明也相形见绌。

C版的JavaVM声明为:

typedef const struct JNINativeInterface* JNIEnv;

struct JNINativeInterface {
        jint        (*GetVersion)(JNIEnv *);
        ···
}

C++版的JavaVM声明为:

typedef _JNIEnv JNIEnv;

struct _JNIEnv {
    /* do not rename this; it does not seem to be entirely opaque */
    const struct JNINativeInterface* functions;

#if defined(__cplusplus)

    jint GetVersion()
    { return functions->GetVersion(this); }

    ...
}

《连载 | 物联网框架ServerSuperIO教程》-
7.约束通信情势开发及注意事项

jobject、jclass、jmethodID和jfieldID

jobject
是JNI对原始java.lang.Object的照耀。能够经过调用NewObject来取得一个jobject对象。例如:

env->NewObject(jclass clazz, jmethodID methodID, ...)

jclass
是JNI对原始java.lang.Class的映射。能够经过调用FindClass来获得jclass对象。例如:

jclass intArrayClass = env->FindClass("[I");

jmethodID
收获对应类成员方法的艺术id。可以通过调用GetMethodID来获取。例如:

jmethodID myMethodId = env->(jclass clazz, const char *name, const char *sig);

jfieldID
得到对应类成员变量的字段id。能够透过调用GetFieldID来获得。例如:

jfieldID nameFieldId = env->GetFieldID(jclass clazz, const char *name, const char *sig)

《连载 | 物联网框架ServerSuperIO教程》-
八.单例通信情势开发及注意事项

地点库调用

JNI的加载本地库中的代码,步骤简述如下(同时,也是Android推荐的做法):
(一)在java类的静态块中调用System.loadLibrary来加载动态库,若动态库的名叫libcocos2dx.so,那么,调用为:

    static {
        System.loadLibrary("cocos2dx");
    }

(二)在该地代码中落成JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved);方法。

(3)在该JNI_OnLoad方法中,调用env->RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods)登记全部地点的兑现格局。推荐将艺术注明为静态的,那样不会占用设备上的符号表的半空中。

《连载 | 物联网框架ServerSuperIO教程》- 九.
商议过滤器,消除一包多发、粘包、冗余数据

JNI通信

JNI的通讯进程,其实正是原生Java与底层C/C++数据传递的历程。那里大约归纳下,数据传递分为以下那二种:

  • 传送基本数据类型(例如:int,float等)
  • 传递对象(例如:String,Object,自定义类MyObject等)
  • 传递数组(例如:int[], String[]等)
  • 传送集合对象(例如:ArrayList
    ,HashMap等)

而调用格局有能够分成:
(1)java调用native方法
(贰)native调用java静态方法,非静态方法(成员方法),以及获得java类的分子变量。

下边根据贯彻情势的例外组合以上要点,通过叁个例证代码来表达下切实是何等达成的。
(一)静态注册的方法
工程协会如下:(那里只列举出关键表明的项)

JNISample1  
  │── build.gradle
  │── CMakeLists.txt 
  └── app 
      ├── build.gradle
      ├── CMakeLists.txt
      └── src 
          ├── cpp
          │    ├── JNIUtils.h
          │    └── JNIUtils.cpp
          └── com.alphagl.main
                    ├── JNIUtils.java
                    ├── MainActivity.Java
                    └── Person.java

代码如下:(那里做了下简化,去掉些注释以及单元测试部分的代码)
MainActivity.java

package com.alphagl.main;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

    static {
        System.loadLibrary("native-lib");
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.i("MainActivity", "getStringFromJNI ============= " + JNIUtils.getStringFromJNI());
        Log.i("MainActivity", "getIntArrayFromJNI ============= " + JNIUtils.getIntArrayFromJNI()[0] + "," + JNIUtils.getIntArrayFromJNI()[1]);
        JNIUtils.setPersonToJNI(new Person(18, "jobs"));
        Log.i("MainActivity", "getPersonFromJNI ============= " + JNIUtils.getPersonFromJNI().getAge()+ "," + JNIUtils.getPersonFromJNI().getName());
    }
}

Person.java:(封装的自定义对象)

package com.alphagl.main;

import android.util.Log;

public class Person {
    private int age;
    private String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void printPerson() {
        Log.d("MainActivity", "age ======== " + age + "," + "name ======== " + name);
    }
}

JNIUtils.java

package com.alphagl.main;

public class JNIUtils {
    public static native String getStringFromJNI();
    public static native int[] getIntArrayFromJNI();
    public static native void setPersonToJNI(Person person);
    public static native Person getPersonFromJNI();
}

JNIUtils.h

#include <jni.h>
#include <stdio.h>

#ifndef _Included_com_alphagl_main_JNIUtils
#define _Included_com_alphagl_main_JNIUtils
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL Java_com_alphagl_main_JNIUtils_getStringFromJNI
  (JNIEnv *, jclass);


JNIEXPORT jintArray JNICALL Java_com_alphagl_main_JNIUtils_getIntArrayFromJNI
  (JNIEnv *, jclass);


JNIEXPORT void JNICALL Java_com_alphagl_main_JNIUtils_setPersonToJNI
  (JNIEnv *, jclass, jobject);


JNIEXPORT jobject JNICALL Java_com_alphagl_main_JNIUtils_getPersonFromJNI
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

JNIUtils.cpp

#include "JNIUtils.h"
#include <android/log.h>

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MainActivity", __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "MainActivity", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROE, "MainActivity", __VA_ARGS__)


JNIEXPORT jstring JNICALL Java_com_alphagl_main_JNIUtils_getStringFromJNI (JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getStringFromJNI");
    // 构造一个String字符串
    return env->NewStringUTF("Hello from jni");
}


JNIEXPORT jintArray JNICALL Java_com_alphagl_main_JNIUtils_getIntArrayFromJNI (JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getIntArrayFromJNI");
    // 构造一个int[]数组
    jintArray intArray = env->NewIntArray(2);
    int size[]={640, 960};
    // 给int[]数组赋值
    env->SetIntArrayRegion(intArray, 0, 2, size);

    return intArray;
}


JNIEXPORT void JNICALL Java_com_alphagl_main_JNIUtils_setPersonToJNI (JNIEnv *env, jclass jcls, jobject jobj) {
    LOGD(" ====================== setPersonToJNI");
    jclass jperson = env->GetObjectClass(jobj);
    if (jperson != NULL) {
        // 获取Person对象的age字段id
        jfieldID ageFieldId = env->GetFieldID(jperson, "age", "I");
        // 获取Person对象的name字段id
        jfieldID nameFieldId = env->GetFieldID(jperson, "name", "Ljava/lang/String;");

        // 获取Person的age成员变量
        jint age = env->GetIntField(jobj, ageFieldId);
        // 获取Person的name成员变量
        jstring name = (jstring)env->GetObjectField(jobj, nameFieldId);

        const char *c_name = env->GetStringUTFChars(name, NULL);

        // 打印从Java传递过来的Person对象的age和name变量
        LOGD("age ===== %d, name ===== %s", age, c_name);
    }

    // 以下是从JNI构造Java对象,并调用Java类中的成员方法,仅用作演示
    // 获取Person对象的class
    jclass jstu = env->FindClass("com/alphagl/main/Person");
    // 获取Person对象的构造方法的方法id
    jmethodID personMethodId = env->GetMethodID(jperson, "<init>", "(ILjava/lang/String;)V");
    // 构造一个String字符串
    jstring name = env->NewStringUTF("bill");

    // 构造一个Person对象
    jobject  jPersonObj = env->NewObject(jstu, personMethodId, 30, name);
    // 获取Person对象的printPerson成员方法的方法id
    jmethodID jid = env->GetMethodID(jstu, "printPerson", "()V");
    // 调用java的printPerson方法
    env->CallVoidMethod(jPersonObj, jid);
}


JNIEXPORT jobject JNICALL Java_com_alphagl_main_JNIUtils_getPersonFromJNI(JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getPersonFromJNI");
    // 获取Person对象的class
    jclass jstudent = env->FindClass("com/alphagl/main/Person");
    // 获取Person对象的构造方法的方法id
    jmethodID studentMethodId = env->GetMethodID(jstudent, "<init>", "(ILjava/lang/String;)V");
    // 构造一个String字符串
    jstring name = env->NewStringUTF("john");
    // 构造一个Person对象
    jobject  jstudentObj = env->NewObject(jstudent, studentMethodId, 20, name);

    return jstudentObj;
}

此处再提一下,如上`JNIUtils.java`类中定义好了native方法,怎样依据目的的办法签名生成对应的C/C++方法的表明。那1部分故事情节在Android游戏开发执行(1)之NDK与JNI开发0一
已经关系过,我们得以依赖javah来根据编写翻译后的.class变迁对于的头文件。
1般说来做法是:
葡京在线开户 1

在AndroidStudio中可以:
Tools-> External Tools -> 添加
葡京在线开户 2
(1)javah所在的途径
(2)命令行参数
(3)头文件生成的门道

葡京在线开户 3
在宣称了native方法的类,右键执行javah即可。

(2)动态注册的办法
工程结构如下:(那里只列举出关键表明的项)

JNISample2  
  │── build.gradle
  │── CMakeLists.txt 
  └── app 
      ├── build.gradle
      ├── CMakeLists.txt
      └── src 
          ├── cpp
          │   └── JNIUtils.cpp
          │    
          └── com.alphagl.main
                    ├── JNIUtils.java
                    ├── MainActivity.Java
                    └── Person.java

此间根本看下区别的代码部分,即JNIUtils.cpp
JNIUtils.cpp

#include <jni.h>
#include <string>
#include <android/log.h>

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MainActivity", __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "MainActivity", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROE, "MainActivity", __VA_ARGS__)

#define CLASSNAME "com/alphagl/main/JNIUtils"

static jstring getStringFromJNI_native(JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getStringFromJNI");
    // 构造一个String字符串
    return env->NewStringUTF("Hello from jni");
}

static jarray getIntArrayFromJNI_native(JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getIntArrayFromJNI");
    // 构造一个int[]数组
    jintArray intArray = env->NewIntArray(2);
    int size[]={640, 960};
    // 给int[]数组赋值
    env->SetIntArrayRegion(intArray, 0, 2, size);

    return intArray;
}

static void setJniPerson_native(JNIEnv *env, jclass jcls, jobject jobj) {
    LOGD(" ====================== setPersonToJNI");
    jclass jperson = env->GetObjectClass(jobj);
    if (jperson != NULL) {
        // 获取Person对象的age字段id
        jfieldID ageFieldId = env->GetFieldID(jperson, "age", "I");
        // 获取Person对象的name字段id
        jfieldID nameFieldId = env->GetFieldID(jperson, "name", "Ljava/lang/String;");

        // 获取Person的age成员变量
        jint age = env->GetIntField(jobj, ageFieldId);
        // 获取Person的name成员变量
        jstring name = (jstring)env->GetObjectField(jobj, nameFieldId);

        const char *c_name = env->GetStringUTFChars(name, NULL);

        // 打印从Java传递过来的Person对象的age和name变量
        LOGD("age ===== %d, name ===== %s", age, c_name);
    }

    // 以下是从JNI构造Java对象,并调用Java类中的成员方法,仅用作演示
    // 获取Person对象的class
    jclass jstu = env->FindClass("com/alphagl/main/Person");
    // 获取Person对象的构造方法的方法id
    jmethodID personMethodId = env->GetMethodID(jperson, "<init>", "(ILjava/lang/String;)V");
    // 构造一个String字符串
    jstring name = env->NewStringUTF("bill");

    // 构造一个Person对象
    jobject  jPersonObj = env->NewObject(jstu, personMethodId, 30, name);
    // 获取Person对象的printPerson成员方法的方法id
    jmethodID jid = env->GetMethodID(jstu, "printPerson", "()V");
    // 调用java的printPerson方法
    env->CallVoidMethod(jPersonObj, jid);
}

static jobject getJniPerson_native(JNIEnv *env, jclass jcls) {
    LOGD(" ====================== getPersonFromJNI");
    // 获取Person对象的class
    jclass jstudent = env->FindClass("com/alphagl/main/Person");
    // 获取Person对象的构造方法的方法id
    jmethodID studentMethodId = env->GetMethodID(jstudent, "<init>", "(ILjava/lang/String;)V");
    // 构造一个String字符串
    jstring name = env->NewStringUTF("john");
    // 构造一个Person对象
    jobject  jstudentObj = env->NewObject(jstudent, studentMethodId, 20, name);

    return jstudentObj;
}

static JNINativeMethod gMethods[] = {
        {"getStringFromJNI", "()Ljava/lang/String;", (void*)getStringFromJNI_native},
        {"getIntArrayFromJNI", "()[I", (void*)getIntArrayFromJNI_native},
        {"setPersonToJNI", "(Lcom/alphagl/main/Person;)V", (void*)setJniPerson_native},
        {"getPersonFromJNI", "()Lcom/alphagl/main/Person;", (void*)getJniPerson_native}
};

static jint registerNativeMethods(JNIEnv *env, const char* className, JNINativeMethod *gMethods, int numMethods) {
    jclass jcls;
    jcls = env->FindClass(className);
    if (jcls == NULL) {
        return JNI_FALSE;
    }

    if (env->RegisterNatives(jcls, gMethods, numMethods) < 0) {
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

static jint registerNative(JNIEnv *env) {
    return registerNativeMethods(env, CLASSNAME, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv *env = NULL;
    if ((vm->GetEnv((void**)&env, JNI_VERSION_1_6)) != JNI_OK) {
        return JNI_ERR;
    }

    if (!registerNative(env)) {
        return JNI_ERR;
    }

    return JNI_VERSION_1_6;
}

最终的推行结果为:
葡京在线开户 4

二种达成方式比较:
(壹)动态注册中,能够不用注解形如Java_packageName_className_methodName格式的章程。
(二)动态注册中,要重写JNI_OnLoad措施,手动调用RegisterNatives来注册本地点法,以及声明在JNINativeMethod中。
(叁)动态注册,分明那种措施更加灵活,但对代码供给越来越高,推荐应用那种艺术。

以上示例代码都已上传Github,有要求的可以活动查看。
https://github.com/cnsuperx/android-jni-example

《连载 | 物联网框架ServerSuperIO教程》-
十.不息传输大块数据流的两种办法(如:文件)

JNI调试

倘若设置了LLVM环境的话,间接将Jni
Debuggable选项打开即可。环境搭建能够参见Android游戏开发实践(一)之NDK与JNI开发03
葡京在线开户 5

随即直接在C或C++代码中设置断点即可。

技术沟通QQ群:5286550贰五
作者:AlphaGL
出处:http://www.cnblogs.com/alphagl/
版权全部,欢迎保留原著链接实行转发 🙂

《连载 | 物联网框架ServerSuperIO教程》-
1一.贯彻设备(驱动)与装备(驱动)交互和级联控制。

《连载 | 物联网框架ServerSuperIO教程》-
1二.劳动接口的开发,以及与云端双向互动

《连载 | 物联网框架ServerSuperIO教程》-
一三.自定义视图展现接口开发,满意不一样的显示要求

《连载 | 物联网框架ServerSuperIO教程》-
14.配制工具介绍,以及设备驱动、视图驱动、服务实例的挂载

《连载 | 物联网框架ServerSuperIO教程》-
15.多少持久化接口的施用

《连载 | 物联网框架ServerSuperIO教程》- 16.OPC
Server的选用手续


目       录

一七.支撑实时数据库,高并发保存测点数据… 二

17.1        概述… 2

17.贰        ServerSuperIO与实时数据库对接… 四

17.二.一       继承动态接口,并设置持久化器… 四

一七.贰.二       扩展设备驱动… 伍

壹七.2.叁       配制标签属性… 陆

1七.二.4       安装实时数据库… 柒

一7.二.伍       配置实时数据库参数… 7

一柒.二.陆       运营程序… 捌

1七.叁        注意事项… 八

一七.4        录制演示… 八

一七.支撑实时数据库,高并发保存测点数据    

17.1     概述

     
实时数据库系统是支付实时间控制制连串、数据收集系统等的后台支撑软件。大批量利用实时数据库系统开始展览支配系统监察和控制,系统先进控制和优化控制,并为集团的生产管理和调度、数据解析、决策辅助及远程在线浏览提供实时数据服务和两种数额管理职能。实时数据库已经济体改成商户消息化的基本功数据平台,可一贯实时收集、获取公司运维进度中的各个数码,并将其转会为对各项作业有效的公共音信,满足公司生产管理、集团经过监督、公司COO管理之间对实时音信完整性、一致性、安全共享的须求,可为公司自动化系统与治本音讯类别间成立起音信交换的桥梁。

     
实时数据库的贰个首要特征正是实时性,包蕴数据实时性和作业实时性。数据实时性是当场IO数据的翻新周期,不能够不考虑数据的实时性。一般数量的实时性首要受现场配备的制裁,尤其是对此有些相比老的系统而言,景况进一步那样。事务实时性是指数据库对其事务处理的速度。它能够是事件触发格局或定时触发格局。事件触发是该事件1经发生可以马上得到调度,那类事件能够取得及时处理,可是正如消耗系统财富;定时触发是在自然时间范围内得到调度权。

     系统框架示意如下图:

 葡京在线开户 6

     
ServerSuperIO作为物联网通信框架,是系统种类化建设的主要节点,同时也需求后台持久化服务的支撑。实时收集传感器的点多少,用实时数据库对采集点数据进行时序存款和储蓄是最精粹的。

      通过持久化接口实行仓库储存操作,接口示意如下图:

葡京在线开户 7 

      结构示意如下图:

 葡京在线开户 8

17.二     ServerSuperIO与实时数据库联网

     
使用进程相比较容易,在三次开发设备驱动进度中,继承动态接口完成自定义属性保存实时数据;通过配制工作把装备驱动完毕自定义的品质映射成Tag标签,然后设置持久化器;设备通信后装置驱动会把实时数据更新到实时数据库中。

1柒.2.一几次三番动态接口,并设置持久化器

    
在配备驱动中落到实处目前保存数据的动态接口,能够把流量或功率信号之类的数目定义成相应的品质名称,每一回采访到多少后更新相应的性质。

     代码如下:

public class DeviceDyn:DeviceDynamic
  {
        public DeviceDyn() : base()
        {
        }
        public override string GetAlertState()
        {
            throw new NotImplementedException("无报警信息");
        }
        private float Flow  {set;get;}      
        private float Signal {set;get;}
}

      
开发好动态数据属性后,在设备驱动的开始化中设置该类持久化器,代码如下:

public DeviceDriver() : base()
        {
            _devicePara = new DevicePara();
            _deviceDyn = new DeviceDyn();

            //用实时数据库持久化动态数据
            _deviceDyn.InitDataPersistence(new RDBPersistence());

            _protocol = new DeviceProtocol();
            _contextMenuComponent=new ContextMenuComponent();

        }

       当然,设备驱动的付出不仅仅囊括那么些,具体请参见从前的教程。

一柒.二.二增添设备驱动

    
运维“ServerSuperIO.Tool.exe”工具,单击【基本配备】菜单。把开发好的装备驱动程序集在安顿工具中实行音讯配置,申明当前的设备驱动在平台上得以运作,如下图:

 葡京在线开户 9

    
上边配置的是先后集的主导音信,可供五个设施驱动实例使用。设备驱动在阳台下运作,还需求举行实例化(具体的简报实例),那么快要挂载设备驱动。挂载进程:创造服务实例,在劳务实例下挂载可运维的装置实例。如下图:

 葡京在线开户 10

一柒.二.三配制标签属性

     
运转“ServerSuperIO.Tool.exe”工具,单击【标签配置】菜单,把刚设备挂载的可运维设备驱动的动态数据接口的品质映射成Tag标签。如下图:

 葡京在线开户 11

一7.2.四设置实时数据库

     
下载“实时数据库安装包及二次开发包.rar”(下载地址)并开始展览设置,安装之后有劳动行政管理器和企管器,如下图:葡京在线开户 12

1柒.二.伍安插实时数据库参数

     运营“ServerSuperIO.Tool.exe”工具,单击【基本配备】菜单,运维OPC
Server服务。如下图:

 葡京在线开户 13

一7.贰.6运作程序

     
能够运作“ServerSuperIO.Host.exe”或“ServerSuperIO.UI.exe”的宿主程序,也能够运营自已2次开发的主程序。

一七.三     注意事项

    
ServerSuperIO服务实例的称谓便是实时数据库的点表名称,在布置服务实例名称的时候尽量利用字符和数字。

一7.4     录制演示


1.[连载]《C#通信(串口和互连网)框架的设计与实现》

2.[开源]C#跨平台物联网通信框架ServerSuperIO(SSIO)介绍

2.动用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)创设系统的总体方案

3.C#工业物联网和集成系统解决方案的技艺路线(数据源、数据收集、数据上传与吸收接纳、ActiveMQ、Mongodb、WebApi、手提式有线电话机App)

5.ServerSuperIO开源地址:https://github.com/wxzz/ServerSuperIO

物联网&集成技术(.NET) QQ群54256083 

下载地址:http://www.bmpj.net/thread-14-1-1.html