前言:
试想着有一天,你坐在电脑前,你家里的空调、冰箱、洗衣机、电视…等在你屏幕前受你掌控时,这便是物联网的时代。现在我们就尝试在dragonboard410c上使用ZICM2410模块。
一、模块简介
模块可以使用7号 3.7V锂电池通过LDO 进行稳压供电,此时可以由学习板变身为移动节点,学习使用2不误。 该设计大大提高了节点的工作时间和节约用户开支
二、代码
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <dirent.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#define LOG_TAG "ZigBee_JNI_log"
#include <utils/Log.h>
#include "jni.h"
#define AT_O8K_UART_DEVICE_NAME "/dev/ttyUSB0"
static int fd;
static int at_open_dev(char *dev_name)
{
int fd = -1;
ALOGI("-----------open device--------\n");
struct termios newtio;
fd = open(dev_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
{
perror("open");
return fd;
}
bzero(&newtio, sizeof(struct termios)); /* clear struct for new port settings */
tcgetattr(fd, &newtio);//取得终端介质(fd)初始值,并把其值赋给newtio;函数可以从后台进程中调用; 01
/* step 1 : control mode flags */
// No parity (8N1): 8bit word length, no parity, 1bit stop bit
newtio.c_cflag = 0; /* This is neccessary opt.c_cflag |= (CLOCAL | CREAD); 04 */
newtio.c_cflag &= ~CSIZE; // opt.c_cflag &= ~CSIZE; 05
newtio.c_cflag |= CS8; /* uart word length : 8bit opt.c_cflag |= CS8; 07 */
newtio.c_cflag &= ~CSTOPB; /* stop bit : 1 bit opt.c_cflag &= ~CSTOPB; 09 */
newtio.c_cflag &= ~PARENB; /* no parity */
// 115200 baudrate :
newtio.c_cflag |= B115200; /* 115200 baud rate cfsetospeed(&opt, B9600); cfsetispeed(&opt, B9600); 02 03*/
newtio.c_cflag |= CREAD; /* care all characters => ignore all characters if CREAD is not set */
/* If non-blocking mode is set, or CLOCAL mode is set,
* we don't want to wait for the modem status lines to
* indicate that the port is ready.
*/
// special set when one uart is used as a modem connector :
newtio.c_cflag &= ~CLOCAL; /* 不忽略MODEM控制线 */
newtio.c_cflag |= HUPCL; /* 在最后一个进程关闭设备后,降低MODEM控制线(挂断) */
newtio.c_cflag &= ~CRTSCTS; /* enable hardware flow control when the uart is used as a modem connector opt.c_cflag &= ~CRTSCTS; 06 */
/* step 2 : input mode flags */
newtio.c_iflag &= ~IGNPAR; /* ignore Parity error and Frame error opt.c_iflag |= IGNPAR; 08 */
newtio.c_iflag &= ~IGNBRK; /* ignore Break interrupt */
newtio.c_iflag &= ~IGNPAR; /* ignore overrun error */
/* step 3 : output mode flags */
newtio.c_oflag &= ~OPOST; /* raw output : 不要对输出做任何预处理 opt.c_oflag = 0; 10 */
/* step 4 : local mode flags */
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* raw input opt.c_lflag = 0; 11 */
/* step 5 : line discipline */
newtio.c_line = 0; /* use line dicipline 0 */
tcflush(fd, TCIFLUSH); /* clear input buffer */
tcsetattr(fd, TCSANOW, &newtio); //ok
LOGI("-----------open device fd = %d--------\n",fd);
return fd;
#if 0
//初始化串口
tcgetattr(fd, &opt);
//tcflush(fd, TCIOFLUSH);
cfsetispeed(&opt, B9600);
cfsetospeed(&opt, B9600);
//tcflush(fd, TCIOFLUSH);
opt.c_cflag |= (CLOCAL | CREAD);
opt.c_cflag &= ~CSIZE;
opt.c_cflag &= ~CRTSCTS;
opt.c_cflag |= CS8;
opt.c_cflag |= PARENB; // enable; 允许输入奇偶校验
opt.c_cflag |= PARODD; // J check 对输入使用奇校验
opt.c_iflag |= (INPCK | ISTRIP); //
opt.c_iflag |= IGNPAR;
opt.c_cflag &= ~CSTOPB;
opt.c_oflag = 0;
opt.c_lflag = 0;
tcsetattr(fd, TCSANOW, &opt);
LOGD("%s X", __func__);
return 0;
#endif
}
// 参数2--调用该方法的对象,实际就是java中myNative
jint open_seril(JNIEnv *env, jobject *thiz)
{
//调用驱动--系统调用
ALOGI("----------%s---------------", __FUNCTION__);
fd = at_open_dev(AT_O8K_UART_DEVICE_NAME);
if(fd < 0)
{
ALOGE("open error %d: %s\n", errno, strerror(errno));
//perror("open");
return -1;
}
return 0;
}
jstring read_seril(JNIEnv *env, jobject thiz)
{
ALOGI("----------%s---------------", __FUNCTION__);
char buf[1024];
char* temp = buf;
buf[1023] = '\0';
bzero (buf,1024);
int ret = -1;
ALOGI("=======before read buf = %s========\n", buf);
ret= read(fd, buf, 1024);
ALOGI("=======after read buf = %s========\n", buf);
if(ret< 0)
{
LOGE("read on error %d: %s\n", errno, strerror(errno));
}
buf[strlen(buf)] = '\0';
return env->NewStringUTF(buf);
#if 0
ALOGI("----------%s---------------", __FUNCTION__);
int len = 0;
char buf[1024];
// 在本地空间得到Java对象元素
buf = (char *)env->GetByteArrayElements(data,NULL);//获取app传来的data字符串
len = read(fd, buf, count);
if(len < 0)
{
ALOGE("read on error : %s\n", strerror(errno));
return -1;
}
#endif
}
static int write_seril(JNIEnv *env, jobject *thiz, jstring str)//法二改jbyteArray str
{
// 获取java中的字串
// 将string转换成char *
//参数1 被转换的string, 参数2, 一般都是填NULL
ALOGI("----------%s---------------", __FUNCTION__);
const char *temp ;
temp = env->GetStringUTFChars(str, NULL);
LOGI("----%s", temp);
jint len = write(fd, temp, strlen(temp));
if(len < 0)
{
LOGE("write off error : %s\n", strerror(errno));
return -1;
}
// 成对出现--释放内部的空间
env->ReleaseStringUTFChars(str, temp);
return len;
#if 0
ALOGI("----------%s---------------", __FUNCTION__);
const char *temp ;
// 在本地空间得到Java对象元素
temp = (char *)env->GetByteArrayElements(str,NULL);
int size = env->GetArrayLength(str);
jint len = write(fd, temp, size);
if(len < 0)
{
LOGE("write off error : %s\n", strerror(errno));
return -1;
}
//Java对象使用完后,释放掉
env->ReleaseByteArrayElements(str, (jbyte*)temp, 0);
ALOGD("%s X", __func__);
return len;
#endif
}
jint close_seril(JNIEnv *env, jobject *thiz)
{
ALOGI("----------%s---------------", __FUNCTION__);
close(fd);
return 0;
}
//映射表:
static const JNINativeMethod myMethod[] = {
{"openDev", "()I", (void *)open_seril},
{"devRead", "()Ljava/lang/String;", (void *)read_seril},
{"devWrite", "(Ljava/lang/String;)I", (void *)write_seril},
{"closeDev", "()I", (void *)close_seril},
};
// 只需要实现一个函数 JNI_Onload()
// 因为在应用中,System.loadLibrary("led_jni"), 会自动调用so中JNI_Onload()
jint JNI_OnLoad(JavaVM * vm,void * reserved) //ok
{
ALOGI("----------JNI_OnLoad---------------");
jint ret = -1;
JNIEnv *env = NULL;
// 1--获取当前VM的环境,保存到env变量中
ret = vm->GetEnv((void * * )&env, JNI_VERSION_1_4);
if(ret != 0)
{
ALOGE("vm->GetEnv error\n");
return -1;
}
// 2 --注册映射表, 需要一个环境变量对象
static const char* const kClassName = "com/zz/mynative/MyNative";
jclass cls = env->FindClass(kClassName);//查找被注册的类
if(cls == NULL)
{
ALOGE(" env->FindClass error\n");
return -1;
}
//向类中注册本SO中Native的接口,接口定义在myMethod数组中
ret = env->RegisterNatives(cls, myMethod, sizeof(myMethod)/sizeof(myMethod[0]));
if(ret < 0)
{
ALOGE(" env->RegisterNatives error\n");
return -1;
}
return JNI_VERSION_1_4;
}