android 직렬 통신 실례
작성 자: Xandy
최근 에 안 드 로 이 드 에서 직렬 통신 을 하 는 동쪽 에 있 었 습 니 다. 아마 기능 은 안 드 로 이 드 시스템 의 ARM 과 시스템 밖의 MCU 통신 일 것 입 니 다. 안 드 로 이 드 인터페이스 를 통 해 MCU 에 걸 려 있 는 장 치 를 제어 하 는 것 입 니 다. 예 를 들 어 radio, TV, BT 등 입 니 다. 다음은 이 과정 에 대해 간단명료 하 게 논술 하고 잘못된 점 이 있 으 면 여러분 이 수정 하 시기 바 랍 니 다.
저 는 HAL 층 에서 직렬 포트 의 장치 노드/dev/ttymxc 1 을 두 개의 스 레 드 로 직접 읽 고 썼 습 니 다. 해당 코드 는 다음 과 같 습 니 다.
1、init
/***************************************************************
** fun: init uart(/dev/ttymxc1);
** in:
** out: fd sucess, -1 false;
** init_mcuuart
***************************************************************/
static int init_mcuuart(void)
{
int fd,var;
portinfo pPort_info;
int err;
dbg(DBG_DEBUG," init_mcuuart in");
//clear message buf
memset(&pPort_info,0,sizeof(portinfo));
//alloc sent and receive buf
pSentMessagePackage = malloc(sizeof(msgpkg));
pReceiveMessagePackage = malloc(sizeof(msgpkg));
fd=open_mcuport();
pSentMessagePackage->fd= fd;
pReceiveMessagePackage->fd= fd;
if(fd == -1)
{
LOGE("init_mcuuart open port error!");
return -1;
}
pPort_info.baud_rate=COM1MCU_BAUD;
pPort_info.data_bits=COM1MCU_DATABIT;
pPort_info.flow_ctrl=COM1MCU_CTRL;
pPort_info.stop_bit=COM1MCU_STOPBIT;
pPort_info.parity=COM1MCU_PARITY;
pPort_info.port_fd=fd;
//pthread_mutex_lock(&pPort_info.portlock);
var = set_portLocked(&pPort_info);
//pthread_mutex_unlock(&pPort_info.portlock);
if(var < 0)
{
LOGE("set_portLocked error!");
return -1;
}
//handshake message
//messagePackage(&PowerOnHandShakeCmd,NULL);
//messagePackage(&TestCmd,"************com1mcu.c mode for test*********");
//uart send message thread
sem_init(&pSentMessagePackage->uart_begin, 0, 0);
sem_init(&pSentMessagePackage->uart_end, 0, 0);
pSentMessagePackage->uart_inited = true;
err = pthread_create(&pSentMessagePackage->thread_id, NULL, &uartUploadData, (void *)pSentMessagePackage);
if(err != 0)
LOGE("init_mcuuart pthread_create pSentMessagePackage error %s!",strerror(err));
//uart receive message thread and analyze it
//sem_init(&pReceiveMessagePackage->uart_begin, 0, 0);
sem_init(&pReceiveMessagePackage->uart_end, 0, 0);
pReceiveMessagePackage->uart_inited = true;
err = pthread_create(&pReceiveMessagePackage->thread_id, NULL, &uartDownloadData, (void *)pReceiveMessagePackage);
if(err != 0)
LOGE("init_mcuuart pthread_create pReceiveMessagePackage error %s!",strerror(err));
return 0;
}
2、
/***************************************************************
** fun: uart send handle
** in: arg pSentMessagePackage
**out:
** uartUploadData
****************************************************************/
static void * uartUploadData(void * arg)
{
pMsgPkg upData = (pMsgPkg)arg;
while(1)
{
sem_wait(&upData->uart_begin);
if(!upData->uart_inited)
{
sem_post(&upData->uart_end);
break;
}
//No message to upload
if(upData->messageCnt <= 0)
sem_wait(&upData->uart_begin);
upData->SYNCCode = SYNCDATA1;
#if 1
if(!CRCCheck((uuint8*)upData,Send)) //CRC
{
LOGE("uartUploadData CRC Error!");
sem_wait(&upData->uart_begin);
}
#endif
//sent message len = SYNCCodeLen(2)+CmdCnt(1)+CmdLen(1)+messageLen(N)+CRCLen(1)
send_mcuuart(upData->fd,upData,upData->messageLen+5);
sem_post(&upData->uart_end);
upData->messageCnt = 0;
upData->messageLen = 0;
}
return true;
}
3、
/***************************************************************
** fun: uart receive handle
** in: arg pReceiveMessagePackage
** out:
** uartDownloadData
****************************************************************/
static void * uartDownloadData(void * arg)
{
uuint8 buffer[RECMSGONCELEN];
pMsgPkg pmsg = (pMsgPkg)arg;
int len,i;
while(1)
{
if(!pmsg->uart_inited)
{
sem_post(&pmsg->uart_end);
break;
}
recv_mcuuart(pmsg->fd,buffer,&len,RECMSGONCELEN,RECMSGTIMEOUT);
if(len > 0)
{
//copy the receive data to the big buf
for(i=0;i<len;i++)
{
if(pmsg->pRecPoint >= RECMSGBUFLEN)
pmsg->pRecPoint = 0;
receiveBuf[pmsg->pRecPoint] = buffer[i];
pmsg->pRecPoint++;
}
memset(buffer,0,RECMSGONCELEN);
}
LOGI("pAnalyzePoint=%d,pRecPoint=%d",pmsg->pAnalyzePoint,pmsg->pRecPoint);
//have new message and prev message have handout to app, analyze from the analyze Point
if((pmsg->pAnalyzePoint != pmsg->pRecPoint)&&(!pmsg->handOutFlag))
analyzeMsgPackage(pmsg, &(receiveBuf[pmsg->pAnalyzePoint]));
}
return true;
}
JNI 의 코드 는 매우 간단 합 니 다. init, upload, download 세 HAL 층 의 함수 인 터 페 이 스 를 통 해 문자열 을 초기 화하 고 데 이 터 를 쓰 며 데 이 터 를 읽 습 니 다.
데 이 터 를 쓸 때 자바 가 보 내 온 데 이 터 를 upload 를 통 해 HAL 에 데이터 헤더 와 CRC 위 치 를 추가 한 다음 스 레 드 에 직렬 장치 노드 를 기록 합 니 다.
데 이 터 를 읽 을 때 HAL 에서 데 이 터 를 읽 는 스 레 드 를 통 해 직렬 장치 노드 에서 데 이 터 를 읽 은 후 분석 과 CRC 검 사 를 하고, CRC 검사 가 정상 이면 분 석 된 데 이 터 를 JNI 층 을 통 해 자바 에 전송 하여 사용 합 니 다.
특히 데 이 터 를 수신 하고 분석 할 때 해당 하 는 buffer 의 제어 입 니 다. 저 는 데 이 터 를 받 을 때 링 buffer 를 사용 하고 용량 은 1KByte 입 니 다. 이렇게 하 는 목적 은 수신 데이터 의 분실 을 방지 하 는 것 입 니 다.
JAVA 의 코드 는 주로 두 부분 이 고 일 부 는 데 이 터 를 쓰 는 방법 입 니 다. 이것 은 비교적 간단 합 니 다. JNI 의 로 컬 함수 urt 를 잘 닫 습 니 다.업로드 하면 돼.다른 부분 은 데 이 터 를 읽 는 방법 을 실현 하 는 것 입 니 다. 이것 은 좀 번 거 롭 습 니 다. 제 시스템 에서 데 이 터 를 읽 을 때 자발적으로 보고 한 데이터 가 있 을 수 있 기 때 문 입 니 다. 즉, ARM 쪽 에 요청 이 없 기 때 문 입 니 다. MCU 쪽 에 데이터 가 있 을 때 자발적으로 ARM 에 보고 합 니 다. 예 를 들 어 MCU 쪽 의 버튼 정보 등 입 니 다.제 가 읽 는 방법 에서 하나의 스 레 드 로 이런 것들 을 처 리 했 습 니 다. 데 이 터 를 분석 하 는 buffer 를 계속 스 캔 했 습 니 다. 정확 한 데 이 터 를 분석 하고 buffer 에 존재 할 때 이 스 레 드 에서 방송 방식 으로 메 시 지 를 방송 한 다음 에 APP 에서 이 방송 을 감청 하면 됩 니 다. 해당 하 는 코드 가 비교적 많 기 때문에 여기 서 보 내지 않 습 니 다!마지막 으로 강조 하고 자 하 는 것 은 장치 노드 를 조작 할 때 system 사용자 의 권한 이 필요 하기 때문에 저 는 해당 app 설정 파일 에 android: shared UserId = "android. uid. system"을 추 가 했 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.