android的jni调用c的循环buf解析正确帧数据

本文介绍了一个使用Java Native Interface (JNI)实现的数据通讯案例。该案例详细展示了如何通过JNI在Java层与本地C/C++代码间传递数据,包括初始化、写入数据及读取解析的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java代码:

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		System.loadLibrary("Hello");
	
		Log.d("abc", "============test=============");
		test t = new test();
		t.init();
		
		byte[] dat = new byte[] { 
				(byte) 0xfe, (byte) 0xfd, 0x05, 0x01, (byte) 0xAC, (byte) 0xF0, 0x36, (byte) 0xFF, (byte) 0xFF, 0x00, (byte) 0xfe,
				(byte) 0xfe, (byte) 0xfd,0x03,0x02,0x00,0x01,0x03,0x09,0x07,0x05,0x03,0x01,
				(byte) 0xfe, (byte) 0xfd,0x03,0x02,0x00,0x01,0x02,0x01,(byte) 0xfc,0x01,0x02,0x01,(byte) 0xfc, };
		
		t.write(dat, dat.length);
		Log.d("abc", "org.len="+dat.length);
		
		byte[] out = {0};
		while(out.length > 0){
			out = t.read((byte)0x03);
			Log.d("abc", "out.len="+out.length);
		}
	}
}
jni:

#include <stdio.h>
#include <jni.h>
#include "com_example_jnitest_test.h"
#include <string.h>
#include <android/log.h>

#define LOG_TAG "jni_log"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

#define uint8_t 	unsigned char
#define BUF_SIZE	2048
typedef struct{
	int w_pos;
	int r_pos;
	char buf[BUF_SIZE];
}loop_t;

loop_t _uart;

void printData(char *info, char *d, int len){
	int i;
	char buf[256];
	for(i = 0; i < len; i++){
		sprintf(buf+i*3, "%02x ", *d++);
	}
	LOGI("%s %s", info, buf);
}

int loop_w(char *buf, int len){
	int i;
	LOGI("===========loop_w==============");
	for(i = 0; i < len; i++){
		if((_uart.w_pos+1)%BUF_SIZE == _uart.r_pos){
			return -1;
		}
		_uart.buf[_uart.w_pos] = buf[i];
		_uart.w_pos = (_uart.w_pos+1)%BUF_SIZE;
	}
	return 0;
}

int loop_r(char *buf, uint8_t addr){

	int sta = 0, cnt = 0;
	uint8_t tmp, type, check, payload[256]={0};
	int i, j, cmdLen = 0;
	int length = _uart.w_pos - _uart.r_pos;
	int org_pos = _uart.r_pos;
	LOGI("=======loop_r=======");
	if(length < 0)	length += BUF_SIZE;
	if(length > 0){
		for(i = 0; i < length; i++){
			tmp = (uint8_t)_uart.buf[(org_pos+i)%BUF_SIZE];
			LOGI("sta:%x=>%x, r_pos=%d",sta,tmp, _uart.r_pos);
			switch(sta){
			case 0:
				if(tmp == 0xfe){
					check = tmp;
					sta = 1;
				}
				else{
					sta = 0;
					_uart.buf[_uart.r_pos] = 0x00;
					_uart.r_pos = (_uart.r_pos+1)%BUF_SIZE;
				}
				break;
			case 1:
				if(tmp == 0xfd){
					check ^= tmp;
					sta = 2;
				}
				else{
					sta = 0;
					_uart.buf[_uart.r_pos] = 0x00;
					_uart.r_pos = (_uart.r_pos+1)%BUF_SIZE;
					return -1;
				}
				break;
			case 2:
				if((tmp == addr)||(tmp == 0xff)){
					check ^= tmp;
					sta = 3;
				}
				else{
					sta = 0;
					for(j=0; j<2; j++){
						_uart.buf[_uart.r_pos] = 0x00;
						_uart.r_pos = (_uart.r_pos+1)%BUF_SIZE;
					}
					return -1;
				}
				break;
			case 3:
				type = tmp;
				check ^= tmp;
				sta = 4;
				break;
			case 4:
				cmdLen = tmp;
				check ^= tmp;
				sta = 5;
				break;
			case 5:
				cmdLen =(cmdLen<<8)+tmp;
				check ^= tmp;
				cnt = 0;
				sta = 6;
				break;
			case 6:
				payload[cnt++] = tmp;
				check ^= tmp;
				if(cnt >= cmdLen)
					sta = 7;
				break;
			case 7:
				LOGI("    check:%x  tmp:%x",check,tmp);
				if(check == tmp){
					buf[0] = type;
					buf[1] = (cmdLen>>8)&0xff;
					buf[2] = (cmdLen)&0xff;
					memcpy(&buf[3], payload, cnt);
					for(j=0; j<(cmdLen+6+2); j++){
						_uart.buf[_uart.r_pos] = 0x00;
						_uart.r_pos = (_uart.r_pos+1)%BUF_SIZE;
					}
					printData("buf=", buf, cmdLen+3);
					return cmdLen+3;
				}
				else{
					for(j=0; j<2; j++){
						_uart.buf[_uart.r_pos] = 0x00;
						_uart.r_pos = (_uart.r_pos+1)%BUF_SIZE;
					}
					return -1;
				}
				break;
			default:
				break;
			}
		}
	}
	return 0;
}

JNIEXPORT void JNICALL Java_com_example_jnitest_test_init
  (JNIEnv *env, jobject obj){
	LOGI("=========init==========");
	memset(&_uart, 0, sizeof(loop_t));
}

JNIEXPORT void JNICALL Java_com_example_jnitest_test_write
  (JNIEnv *env, jobject obj, jbyteArray jarrByte, jint len){
	jbyte *b = (*env)->GetByteArrayElements(env, jarrByte, 0);
	if(b == NULL){
		LOGI("b is null");
		return;
	}
	loop_w(b, len);
	(*env)->ReleaseByteArrayElements(env, jarrByte, b, 0);
}

JNIEXPORT jbyteArray JNICALL Java_com_example_jnitest_test_read
  (JNIEnv *env, jobject obj, jbyte type){
	int len = -1;
	char buf[128];
	while(len < 0){
		len = loop_r(buf, type);
	}
	jbyteArray ret = (*env)->NewByteArray(env, len);
	(*env)->SetByteArrayRegion(env, ret, 0, len, buf);
	return ret;
}
结果:

10-08 22:41:15.064: I/Timeline(25623): Timeline: Activity_idle id: android.os.BinderProxy@1b649634 time:14721308
10-08 22:41:17.994: D/abc(25966): =============test============
10-08 22:41:17.994: I/jni_log(25966): =========init==========
10-08 22:41:17.994: I/jni_log(25966): ===========loop_w==============
10-08 22:41:17.994: D/abc(25966): org.len=36
10-08 22:41:17.994: I/jni_log(25966): =======loop_r=======
10-08 22:41:17.994: I/jni_log(25966): sta:0=>fe, r_pos=0
10-08 22:41:17.994: I/jni_log(25966): sta:1=>fd, r_pos=0
10-08 22:41:17.994: I/jni_log(25966): sta:2=>5, r_pos=0
10-08 22:41:17.994: I/jni_log(25966): =======loop_r=======
10-08 22:41:17.994: I/jni_log(25966): sta:0=>5, r_pos=2
10-08 22:41:17.994: I/jni_log(25966): sta:0=>1, r_pos=3
10-08 22:41:17.994: I/jni_log(25966): sta:0=>ac, r_pos=4
10-08 22:41:17.994: I/jni_log(25966): sta:0=>f0, r_pos=5
10-08 22:41:17.994: I/jni_log(25966): sta:0=>36, r_pos=6
10-08 22:41:17.994: I/jni_log(25966): sta:0=>ff, r_pos=7
10-08 22:41:17.994: I/jni_log(25966): sta:0=>ff, r_pos=8
10-08 22:41:17.994: I/jni_log(25966): sta:0=>0, r_pos=9
10-08 22:41:17.994: I/jni_log(25966): sta:0=>fe, r_pos=10
10-08 22:41:17.994: I/jni_log(25966): sta:1=>fe, r_pos=10
10-08 22:41:17.994: I/jni_log(25966): =======loop_r=======
10-08 22:41:17.994: I/jni_log(25966): sta:0=>fe, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:1=>fd, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:2=>3, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:3=>2, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:4=>0, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:5=>1, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:6=>3, r_pos=11
10-08 22:41:17.994: I/jni_log(25966): sta:7=>9, r_pos=11
10-08 22:41:17.994: I/jni_log(25966):     check:0  tmp:9
10-08 22:41:17.994: I/jni_log(25966): =======loop_r=======
10-08 22:41:17.994: I/jni_log(25966): sta:0=>3, r_pos=13
10-08 22:41:17.994: I/jni_log(25966): sta:0=>2, r_pos=14
10-08 22:41:17.994: I/jni_log(25966): sta:0=>0, r_pos=15
10-08 22:41:17.994: I/jni_log(25966): sta:0=>1, r_pos=16
10-08 22:41:17.994: I/jni_log(25966): sta:0=>3, r_pos=17
10-08 22:41:17.994: I/jni_log(25966): sta:0=>9, r_pos=18
10-08 22:41:17.994: I/jni_log(25966): sta:0=>7, r_pos=19
10-08 22:41:17.994: I/jni_log(25966): sta:0=>5, r_pos=20
10-08 22:41:17.994: I/jni_log(25966): sta:0=>3, r_pos=21
10-08 22:41:17.994: I/jni_log(25966): sta:0=>1, r_pos=22
10-08 22:41:17.994: I/jni_log(25966): sta:0=>fe, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:1=>fd, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:2=>3, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:3=>2, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:4=>0, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:5=>1, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:6=>2, r_pos=23
10-08 22:41:17.994: I/jni_log(25966): sta:7=>1, r_pos=23
10-08 22:41:17.994: I/jni_log(25966):     check:1  tmp:1
10-08 22:41:17.994: I/jni_log(25966): buf= 02 00 01 02 
10-08 22:41:17.994: D/abc(25966): out.len=4
10-08 22:41:17.994: I/jni_log(25966): =======loop_r=======
10-08 22:41:17.994: I/jni_log(25966): sta:0=>1, r_pos=30
10-08 22:41:18.004: I/jni_log(25966): sta:0=>fc, r_pos=31
10-08 22:41:18.004: I/jni_log(25966): sta:0=>1, r_pos=32
10-08 22:41:18.004: I/jni_log(25966): sta:0=>2, r_pos=33
10-08 22:41:18.004: I/jni_log(25966): sta:0=>1, r_pos=34
10-08 22:41:18.004: I/jni_log(25966): sta:0=>fc, r_pos=35
10-08 22:41:18.004: D/abc(25966): out.len=0




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值