該驅動適用於採用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;
}