- 浏览: 81793 次
- 性别:
- 来自: 西安
文章分类
最新评论
-
_lsliang:
直接使用Query的addEntity方法?
获取多表中的数据 -
zhangkehbg:
待续~~~~
几种常用的排序算法
实现目标:Android Virtual Device与串口调试助手间进行收发数据通信
1、代码分析
AVD串口通信程序主要参考google的开源串口类android-serialport-api,关于串口操作主要有:(1)打开串口;(2)读串口;(3)写串口;(4)关闭串口。在本demo中,只有一个Activity,其中包含了打开串口,读写串口的操作,打开串口等操作用到了JNI,使得Java可以调用C语言写成的库。
1.1 MainActivity.java,主要包含打开串口按钮,返回文件输入输出流,发送和接收按钮,并将接收和发送的内容在EditText显示
1.2 SerialPort.java类,主要调用JNI打开串口,返回文件输入输出流
1.3 调用JNI打开串口
1.3.1 调用JNI时,请确保NDK已经配置好,在local.properties中有SDK和NDK的配置路径
1.3.2 注意:
SerialPort中添加的native open方法:此处会有Cannot resolve corresponding JNI function java_com_charles_uart_SerialPort_open,可以先不用理会
1.3.3 编译生成字节码文件
Build->Make Project,执行这一步为了验证工程中无其他错误,并生成.class字节码文件,生成的字节码文件位于工程目录下的
build\\intermediates\\classes\\debug文件夹下
1.3.4 使用Javah生成头文件
打开cmd进入工程main目录下:
D:\\AndroidProjet\\HelloJni01\\app\\src\\main>javah -d jni -classpath D:\\Users\\charle
s.wang_cp\\AppData\\Local\\Android\\sdk\\platforms\\android-25\\android.jar;..\\..\\build
\\intermediates\\classes\\debug com.charles.uart.SerialPort
注意:此处的android-25根据工程的compile SDK API来选择,执行此命令后会生成jni文件夹以及对应有包名的头文件.h
1.3.5在jni文件夹下创建jni.c文件,并编辑c源代码,注意要区分创建.c还是.cpp文件,如果创建成.cpp,而编辑的是.c源代码,那么可能编译时会有语法错误,C源代码中的方法来自com_charles_uart_SerialPort.h中的定义
jni.c源代码
1.3.6 配置gradle.properties文件以及build.gradle文件
首先在gradle.properties中末尾添加:android.useDeprecatedNdk=true
然后在build.gradle中添加如下配置
1.3.7 Build->Rebuild Project
这一步编译代码将生成.so文件,生成路径在\build\intermediates\ndk\lib文件夹下
2、创建AVD
2.1 Tools->Android->AVD Manager->Create Virtual Device 创建Android Virtual Device
注意:Nexus 在Marshmallow模式的system image下,每次Activity启动和退出时,log都会打印出未知错误
如图为创建成功的avd1和avd2
2.2 启动AVD,并且为AVD设置串口COM,本demo中为AVD设置COM2
2.3 获取节点权限,否则将不能对串口进行读写操作
//获取root权限
>adb root
//查看串口节点
>ls -l ttyS*
//修改系统属性
>chown root:root ttyS*
//节点获得读写可执行权限
>chmod 777 ttyS*
//关闭Selinux
>setenforce 0
3、AVD与串口调试助手进行串口通信
3.1 将串口通信程序apk安装到avd2
3.2 打开串口调试助手,并将串口设置为COM1,波特率为9600(串口程序设置为9600)
3.3 AVD点击“打开串口”
3.4 输入发送数据,例如:Zesusis,点击“发送”,在串口调试助手接收端可以看到接收的数据
3.5 点击“接收”,再在串口调试助手端写好要发送的数据,例如:2016,在AVD端可以看到接收的数据
至此,说明Android与串口调试助手间的串口通信调试成功。
1、代码分析
AVD串口通信程序主要参考google的开源串口类android-serialport-api,关于串口操作主要有:(1)打开串口;(2)读串口;(3)写串口;(4)关闭串口。在本demo中,只有一个Activity,其中包含了打开串口,读写串口的操作,打开串口等操作用到了JNI,使得Java可以调用C语言写成的库。
1.1 MainActivity.java,主要包含打开串口按钮,返回文件输入输出流,发送和接收按钮,并将接收和发送的内容在EditText显示
package com.charles.uart; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class MainActivity extends AppCompatActivity { private static final String TAG=MainActivity.class.getSimpleName(); //log信息 private Button btOpen; private Button btSend; private Button btRec; private EditText mSend; private EditText mReception; SerialPort sp; FileInputStream mInputStream; FileOutputStream mOutputStream; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化钮以及文本显示 btOpen= (Button) findViewById(R.id.button); btSend= (Button) findViewById(R.id.button2); btRec= (Button) findViewById(R.id.button3); mSend= (EditText) findViewById(R.id.editText); mReception= (EditText) findViewById(R.id.editText2); Log.i(TAG,"钮以及文本显示初始化完成"); //点击打开串口 btOpen.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.i(TAG,"点击了打开按钮"); /* * 打开串口,返回文件输入输出流 * */ sp=new SerialPort(new File("/dev/ttyS1"),9600); mInputStream= (FileInputStream) sp.getInputStream(); mOutputStream= (FileOutputStream) sp.getOutputStream(); Toast.makeText(getApplicationContext(),"open",Toast.LENGTH_SHORT).show(); } }); //点击发送 btSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.i(TAG,"点击了发送钮"); try { //获取发送数据 String send=mSend.getText().toString(); //将获取的数据发出 mOutputStream.write(send.getBytes()); mOutputStream.write('\\n'); } catch (IOException e) { e.printStackTrace(); return; } Toast.makeText(getApplicationContext(),"send",Toast.LENGTH_SHORT).show(); } }); //点击接收 btRec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.i(TAG,"点击了接收钮"); int size; //存储接收数据 byte[] buffer=new byte[64]; if (mInputStream==null){ Log.i(TAG,"没接收到数据,返回"); return; } //如果接收到数据 try { size=mInputStream.read(buffer); //读取接收数据 if (size>0){ onDataReceived(buffer,size); //如果读取的数据不为空,将读取的数据显示在EditText } } catch (IOException e) { e.printStackTrace(); return; } } }); } void onDataReceived(final byte[] buffer,final int size){ runOnUiThread(new Runnable() { @Override public void run() { if (mReception!=null){ mReception.append(new String(buffer,0,size)); } } }); } }
1.2 SerialPort.java类,主要调用JNI打开串口,返回文件输入输出流
package com.charles.uart; import android.util.Log; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; /** * Created by charles.wang_cp on 2016/11/29. */ public class SerialPort { static { System.loadLibrary("serialport"); } private FileInputStream mFileInputStream; private FileOutputStream mFileOutputStream; private FileDescriptor mFd; public SerialPort(File device,int baudrate){ if (!device.canWrite()||!device.canWrite()){ return; //如果节点无读写权限 } //打开串口,并获取文件输入输出流 mFd=open(device.getAbsolutePath(),baudrate); mFileInputStream=new FileInputStream(mFd); mFileOutputStream=new FileOutputStream(mFd); } //获取文件输入输出流 public InputStream getInputStream(){return mFileInputStream;} public OutputStream getOutputStream(){return mFileOutputStream;} //调用JNI打开串口 private native static FileDescriptor open(String path,int baudrate); }
1.3 调用JNI打开串口
1.3.1 调用JNI时,请确保NDK已经配置好,在local.properties中有SDK和NDK的配置路径
1.3.2 注意:
SerialPort中添加的native open方法:此处会有Cannot resolve corresponding JNI function java_com_charles_uart_SerialPort_open,可以先不用理会
1.3.3 编译生成字节码文件
Build->Make Project,执行这一步为了验证工程中无其他错误,并生成.class字节码文件,生成的字节码文件位于工程目录下的
build\\intermediates\\classes\\debug文件夹下
1.3.4 使用Javah生成头文件
打开cmd进入工程main目录下:
D:\\AndroidProjet\\HelloJni01\\app\\src\\main>javah -d jni -classpath D:\\Users\\charle
s.wang_cp\\AppData\\Local\\Android\\sdk\\platforms\\android-25\\android.jar;..\\..\\build
\\intermediates\\classes\\debug com.charles.uart.SerialPort
注意:此处的android-25根据工程的compile SDK API来选择,执行此命令后会生成jni文件夹以及对应有包名的头文件.h
1.3.5在jni文件夹下创建jni.c文件,并编辑c源代码,注意要区分创建.c还是.cpp文件,如果创建成.cpp,而编辑的是.c源代码,那么可能编译时会有语法错误,C源代码中的方法来自com_charles_uart_SerialPort.h中的定义
jni.c源代码
// // Created by charles.wang_cp on 2016/11/29. // #include <termios.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <jni.h> #include "android/log.h" static const char *TAG="serial_port"; #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args) #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args) #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args) static speed_t getBaudrate(jint baudrate){ switch(baudrate) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400; case 460800: return B460800; case 500000: return B500000; case 576000: return B576000; case 921600: return B921600; case 1000000: return B1000000; case 1152000: return B1152000; case 1500000: return B1500000; case 2000000: return B2000000; case 2500000: return B2500000; case 3000000: return B3000000; case 3500000: return B3500000; case 4000000: return B4000000; default: return -1; } } /* *Class:com_charles_uart_SerialPort *Method:open *Signature: (Ljava/lang/String;I)Ljava/io/FileDescriptor */ JNIEXPORT jobject JNICALL Java_com_charles_uart_SerialPort_open (JNIEnv *env, jclass thiz, jstring path, jint baudrate){ int fd; speed_t speed; jobject mFileDescriptor; /*check arguments*/ { speed=getBaudrate(baudrate); if (speed == -1) { /* TODO: throw an exception */ LOGE("Invalid baudrate"); return NULL; } } /*opening device*/ { jboolean iscopy; const char *path_utf=(*env)->GetStringUTFChars(env,path,&iscopy); LOGD("Opening serial port %s", path_utf); fd = open(path_utf, O_RDWR); LOGD("open() fd = %d", fd); (*env)->ReleaseStringUTFChars(env, path, path_utf); if (fd == -1) { /* Throw an exception */ LOGE("Cannot open port"); /* TODO: throw an exception */ return NULL; } } /*configure device*/ { struct termios cfg; LOGD("Configuring serial port"); if (tcgetattr(fd, &cfg)) { LOGE("tcgetattr() failed"); close(fd); /* TODO: throw an exception */ return NULL; } cfmakeraw(&cfg); cfsetispeed(&cfg, speed); cfsetospeed(&cfg, speed); if (tcsetattr(fd, TCSANOW, &cfg)) { LOGE("tcsetattr() failed"); close(fd); /* TODO: throw an exception */ return NULL; } } /*create a corresponding file descriptor*/ { jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor"); jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V"); jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I"); mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor); (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd); } return mFileDescriptor; }
1.3.6 配置gradle.properties文件以及build.gradle文件
首先在gradle.properties中末尾添加:android.useDeprecatedNdk=true
然后在build.gradle中添加如下配置
1.3.7 Build->Rebuild Project
这一步编译代码将生成.so文件,生成路径在\build\intermediates\ndk\lib文件夹下
2、创建AVD
2.1 Tools->Android->AVD Manager->Create Virtual Device 创建Android Virtual Device
注意:Nexus 在Marshmallow模式的system image下,每次Activity启动和退出时,log都会打印出未知错误
如图为创建成功的avd1和avd2
2.2 启动AVD,并且为AVD设置串口COM,本demo中为AVD设置COM2
2.3 获取节点权限,否则将不能对串口进行读写操作
//获取root权限
>adb root
//查看串口节点
>ls -l ttyS*
//修改系统属性
>chown root:root ttyS*
//节点获得读写可执行权限
>chmod 777 ttyS*
//关闭Selinux
>setenforce 0
3、AVD与串口调试助手进行串口通信
3.1 将串口通信程序apk安装到avd2
3.2 打开串口调试助手,并将串口设置为COM1,波特率为9600(串口程序设置为9600)
3.3 AVD点击“打开串口”
3.4 输入发送数据,例如:Zesusis,点击“发送”,在串口调试助手接收端可以看到接收的数据
3.5 点击“接收”,再在串口调试助手端写好要发送的数据,例如:2016,在AVD端可以看到接收的数据
至此,说明Android与串口调试助手间的串口通信调试成功。
发表评论
-
高通平台Performance机制学习总结
2018-02-07 15:13 5312高通平台Performance机制学习总结 利用在高通平台中的 ... -
实现返回键(back)和任务管理键(app_switch)功能的调换
2018-01-18 16:01 1642近期有一个需求在不同的国家操作习惯不一样,需要将back键和a ... -
Makefile里PHONY的相关介绍
2017-08-04 15:28 719Phony Targets PHONY 目标并非实际的文件名 ... -
如何抓取 framework input 事件相关 log
2017-02-04 16:31 3159[DESCRIPTION] 出现事件输入相关的问题时, 建议 ... -
如何用getevent查看C-TouchPanel上报数据?
2017-02-04 16:28 2341[DESCRIPTION] 如何用getevent查看 ... -
Android语言定制(二)
2017-01-11 10:52 537android 语言定制 本文是主要对android定制多语言 ... -
Android语言定制(二)
2017-01-11 10:47 0android 语言定制 本文是主要对android定制多语言 ... -
Android 语言定制(一)
2017-01-11 10:38 1657Android多语言支持以及各国语言Values文件夹命名规则 ... -
Android 各国语言码
2017-01-11 10:24 1743在做海外项目的时候往往需要添加各种海外语言,比如 越南语、印尼 ... -
Native堆栈解析addr2line
2016-12-08 15:34 4797Native堆栈解析addr2line 命令: aarch6 ... -
git clone Android 源码
2016-11-30 10:48 1484git clone https://github.com/ ... -
Android init.rc语法总结
2016-11-18 11:29 1271本文转载自:http://blog.csdn.net/cham ...
相关推荐
LabVIEW串口调试助手的亮点在于它提供了一个直观的图形界面,使得用户能够方便地进行串口配置、数据收发及数据解析。用户可以设置波特率、数据位、停止位、校验位等参数,进行串口的打开和关闭,并实时查看接收到的...
串口调试助手是一种用于通信设备调试的工具,它允许用户通过串行接口(如RS-232)与外部设备进行数据交换。在本案例中,这个串口调试助手是利用编程软件LabVIEW 2018开发的,具备了高级功能,如十六进制数据处理和...
通过串口助手,用户可以发送和接收ASCII或二进制数据,监控波特率、数据位、停止位、校验位等参数,进行错误检测和通信诊断。 **Easy_RS232_Terminal.vi解析** `Easy_RS232_Terminal.vi`是这个串口调试助手的核心...
在这个“Labview 下的串口调试助手”项目中,我们可以深入理解Labview如何与硬件设备进行串行通信,以及如何进行有效的数据调试。 串口通信,也称为UART(通用异步收发传输器),是计算机通信的一种常见方式,尤其...
首先,"串口调试助手"是用于测试和调试串行通信的一种工具,它能够帮助开发者收发串口数据,查看和分析串口通信的实时状态。在LabVIEW中,通过使用串口驱动,我们可以创建一个用户友好的图形界面,实现对串口的读写...
串口通信是计算机与其他设备之间进行数据传输的一种常见方式,通常包括RS-232、RS-485等标准。LabVIEW串口调试助手能帮助用户轻松地配置和测试串口连接,以便在硬件设备之间建立有效的通信链路。以下将从几个关键...
串口通信,也称为UART(通用异步收发传输器),是一种常见的设备间通信方式。它通过串行数据传输,一次只发送一位数据,通常采用RS-232、RS-485或USB转串口等接口标准。串口通信的基本参数包括波特率、数据位、停止...
2. **数据发送与接收**:通过界面的输入框,用户可以输入想要发送的数据,并选择不同的字符编码方式(ASCII或十六进制)。同时,工具会实时显示接收到的数据,便于观察和分析通信过程。 3. **数据流控制**:串口...
串口调试助手就是用来监控和控制这种通信过程的工具,通过模拟发送和接收数据,帮助开发者检测设备连接、波特率设置、数据格式等问题。 二、C++ Builder介绍 C++ Builder是Embarcadero公司开发的一款集成开发环境...
串口调试助手与串口仿真软件VSPD是IT领域中进行串行通信调试和测试的重要工具。在嵌入式系统、物联网设备、工业自动化、数据通信等领域,串口(Serial Port)扮演着不可或缺的角色,因为它们提供了一种简单、低速但...
串口通信,也称为UART(通用异步收发传输器),是设备间常用的一种通信方式,常用于调试、数据交换等。在Labview中,我们可以使用内置的串口VIs(虚拟仪器)来实现串口的打开、关闭、读写等功能。串口调试助手会提供...
它涉及到通过串行端口(如RS-232)与设备进行通信,以发送和接收数据,确保设备正常工作。 描述中提到的“LSCOMM”和“USR-TCP232-Test”是两个不同的串口调试软件。LSCOMM可能是一个通用的串口通信程序,提供串口...
在IT领域,串口通信是计算机通信的一种常见方式,尤其在嵌入式系统、工业控制以及设备间的数据传输中广泛应用。C#作为一种强大的.NET编程语言,提供了丰富的库和API来支持串口通信。本资源"**C#代码实现串口通信+...
用C#开发的串口调试助手,代码部分大多数已经注释;测试串口可以通过安装Configure Virtual Serial Port Driver来虚拟串口号测试。
在实际应用中,我们可能需要与多种设备进行通信,因此串口调试助手应具备多串口支持功能。通过添加下拉菜单或组合框,让用户选择要操作的串口号,然后在程序中根据选择的串口进行相应的配置和操作。 此外,LabVIEW...
首先,要进行MATLAB与串口通信,我们需要借助一些辅助工具。在没有硬件设备时,可以使用Virtual Serial Port Driver创建虚拟串口来模拟实际的硬件通信。另一个实用工具是串口调试助手,它可以帮助我们调试串口发送和...
虚拟串口软件如COM Port Redirector、Virtual Serial Port Driver等,它们在操作系统层面模拟物理串口,使得不具有物理串口的设备(如USB转串口模块)能够像使用真实串口一样进行通信。虚拟串口软件通过驱动程序将...
"labview编写的串口调试助手"是一个强大的工具,它结合了LabVIEW的图形化编程优势和串口通信的实用功能,提供了便捷的串口配置、数据收发、CRC校验以及事件驱动的高效运行机制,适用于多种串行通信场景的调试与测试...
这个“串口调试助手”项目就是一个实用工具,用于测试和调试串口设备,它可以帮助我们轻松地发送数据到串口,并接收来自串口的回应。 1. **串口配置**:在LabVIEW中,我们需要首先配置串口参数,包括波特率(例如...
Virtual Serial Port Driver 6.9 串口调试助手