该驱动适用于采用linux和android系统平台的C/C++串口开发。
FIFO发送模式:创建数据发送FIFO队列,在多任务数据发送情境下,既能保证数据发送任务能够得到执行,又可解决数据发送冲突问题。
select接收数据:有效监听串口接收数据,提高执行效率,减少出错概率。
串口参数配置驱动,参考:https://blog.csdn.net/weixin_40779546/article/details/81703482
select监听串口数据,参考:https://blog.csdn.net/weixin_40779546/article/details/81449852
源代码如下:
uart.h
//
// Created by taxiang&xuezi on 2018/4/2.
//
#ifndef NDKAPPECG_UART_H
#define NDKAPPECG_UART_H
#include "typedef.h"
#ifdef UART_GLOBALS
#define UART_EXT
#else
#define UART_EXT extern
#endif
#define UART_DBG 1
#define UART_TX_EVENT_FIFO (32)
#define UART_BUF_SIZE (1024)
enum UART_EVENT_SET{
UART_EVENT_IDLE = 0,
//event
UART_EVENT_VERION,
UART_EVENT_DATA_START,
UART_EVENT_DATA_STOP,
UART_EVENT_DEFAULT,
};
struct S_UART_TX_EVENT_SET{
s32 fifo[UART_TX_EVENT_FIFO];
s32 head;
s32 tail;
};
struct S_UART_RX {
s32 fd;
u8 buf[UART_BUF_SIZE];
s32 len;
};
struct S_UART_TX {
s32 fd;
u8 buf[UART_BUF_SIZE];
s32 len;
};
UART_EXT struct S_UART_RX s_uart3_rx;
UART_EXT struct S_UART_TX s_uart3_tx;
UART_EXT struct S_UART_TX_EVENT_SET s_uart_tx_event;
UART_EXT s32 uart_insert_tx_event(int txevent);
UART_EXT s32 uart_tx_task(struct S_UART_TX *uart_ptr);
UART_EXT s32 uart_rx_task(s32 fd,s32 recv_len,s8 *recv_data);
#endif //NDKAPPECG_UART_H
uart.c/uart.cpp
//
// Created by taxiang&xuezi on 2018/4/2.
//
#define UART_GLOBALS
#include "includes.h"
#ifdef UART_DBG
#define UART_PRINT0(X) printf(X);
#define UART_PRINT1(X,A) printf (X,A);
#define UART_PRINT2(X,A,B) printf (X,A,B);
#define UART_PRINT3(X,A,B,C) printf (X,A,B,C);
#else
#define UART_PRINT0(X)
#define UART_PRINT1(X,A)
#define UART_PRINT2(X,A,B)
#define UART_PRINT3(X,A,B,C)
#endif
/*******************************************************************************
* 函数名称: s32 uart_insert_tx_event(s32 tx_event)
* 函数功能: 串口添加发送事件到fifo
* 输入参数:
* 输出参数:
* 返回值 :
*******************************************************************************/
s32 uart_insert_tx_event(s32 tx_event)
{
s_uart_tx_event.fifo[s_uart_tx_event.head] = tx_event;
s_uart_tx_event.head++;
if (s_uart_tx_event.head >= UART_TX_EVENT_FIFO) {
s_uart_tx_event.head = 0;
}
return 0;
}
/*******************************************************************************
* 函数名称: s32 uart_tx_task(struct S_UART_TX *uart_ptr)
* 函数功能: 串口fifo发送任务
* 输入参数:
* 输出参数:
* 返回值 :
*******************************************************************************/
s32 uart_tx_task(struct S_UART_TX *uart_ptr)
{
if(s_uart_tx_event.head == s_uart_tx_event.tail){
return 1;
}
switch(s_uart_tx_event.fifo[s_uart_tx_event.tail]){
case UART_EVENT_VERION:
sprintf((char*)uart_ptr->buf, "Verion0.0.1\n");
uart_ptr->len = strlen((char*)uart_ptr->buf);
break;
case UART_EVENT_DATA_START:
sprintf((char*)uart_ptr->buf, "data_start");
uart_ptr->len = strlen((char*)uart_ptr->buf);
run_log("uart tx:%s",uart_ptr->buf);
break;
case UART_EVENT_DATA_STOP:
sprintf((char*)uart_ptr->buf, "data_stop");
uart_ptr->len = strlen((char*)uart_ptr->buf);
run_log("uart tx:%s",uart_ptr->buf);
break;
default:
break;
}
s_uart_tx_event.fifo[s_uart_tx_event.tail] = UART_EVENT_IDLE;
s_uart_tx_event.tail++;
if(s_uart_tx_event.tail >= UART_TX_EVENT_FIFO) {
s_uart_tx_event.tail = 0;
}
if(uart_ptr->len != 0) {
int write_len = write(uart_ptr->fd,uart_ptr->buf,uart_ptr->len);
if(write_len == uart_ptr->len){
run_log("uart send done");
return 0;
}else if(write_len <= 0){
err_log("uart send failed");
return -1;
}
}
return 0;
}
/*******************************************************************************
* 函数名称: s32 uart_rx_task(s32 fd,s32 recv_len,s8 *recv_data)
* 函数功能:
* 输入参数:
* 输出参数:
* 返回值 :
***************************************************************s****************/
s32 uart_rx_task(s32 fd,s32 recv_len,s8 *recv_data)
{
s8 in_buf[recv_len];
s8 buf[recv_len];
memset(in_buf,'\0',recv_len);
memset(buf,'\0',recv_len);
fd_set read_set;
struct timeval tv;
s32 max_fd = 0;
s32 tmp_len = 0;
s32 ret_val = 0;
s32 read_size;
do{
FD_ZERO(&read_set);
if(fd >= 0){
FD_SET(fd,&read_set);
}
max_fd = fd + 1;
tv.tv_sec = 0;
tv.tv_usec = 300000;
do{
ret_val = select(max_fd,&read_set,0,0,&tv);
}while((ret_val == -1) && (errno == EINTR));
if(ret_val == -1){
run_log("select(2)");
}else if(ret_val == 0){//timeout
fd = -1;
}
if((fd>=0) && FD_ISSET(fd,&read_set)){
read_size = read(fd,buf,(recv_len-tmp_len));
tmp_len += read_size;
if(read_size == -1){
fd = -1;
}
if(read_size > 0){
buf[(read_size+1)] = '\0';
strcat(in_buf,buf);
memset(buf,0x00,recv_len);
}else{
fd = -1;
}
}
}while(fd >= 0);
memcpy(recv_data,in_buf,tmp_len);
return tmp_len;
}