该驱动适用于采用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,//eventUART_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 &#61;&#61; 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 &#61; strlen((char*)uart_ptr->buf);break;case UART_EVENT_DATA_START:sprintf((char*)uart_ptr->buf, "data_start");uart_ptr->len &#61; 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 &#61; 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] &#61; UART_EVENT_IDLE;s_uart_tx_event.tail&#43;&#43;;if(s_uart_tx_event.tail >&#61; UART_TX_EVENT_FIFO) {s_uart_tx_event.tail &#61; 0;}if(uart_ptr->len !&#61; 0) {int write_len &#61; write(uart_ptr->fd,uart_ptr->buf,uart_ptr->len);if(write_len &#61;&#61; uart_ptr->len){run_log("uart send done");return 0;}else if(write_len <&#61; 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,&#39;\0&#39;,recv_len);memset(buf,&#39;\0&#39;,recv_len);fd_set read_set;struct timeval tv;s32 max_fd &#61; 0;s32 tmp_len &#61; 0;s32 ret_val &#61; 0;s32 read_size;do{FD_ZERO(&read_set);if(fd >&#61; 0){FD_SET(fd,&read_set);}max_fd &#61; fd &#43; 1;tv.tv_sec &#61; 0;tv.tv_usec &#61; 300000;do{ret_val &#61; select(max_fd,&read_set,0,0,&tv);}while((ret_val &#61;&#61; -1) && (errno &#61;&#61; EINTR));if(ret_val &#61;&#61; -1){run_log("select(2)");}else if(ret_val &#61;&#61; 0){//timeoutfd &#61; -1;}if((fd>&#61;0) && FD_ISSET(fd,&read_set)){read_size &#61; read(fd,buf,(recv_len-tmp_len));tmp_len &#43;&#61; read_size;if(read_size &#61;&#61; -1){fd &#61; -1;}if(read_size > 0){buf[(read_size&#43;1)] &#61; &#39;\0&#39;;strcat(in_buf,buf);memset(buf,0x00,recv_len);}else{fd &#61; -1;}}}while(fd >&#61; 0);memcpy(recv_data,in_buf,tmp_len);return tmp_len;
}