Linux/Android系統開發 串列埠驅動原始碼,FIFO模式
阿新 • • 發佈:2018-12-31
該驅動適用於採用linux和android系統平臺的C/C++串列埠開發。
FIFO傳送模式:建立資料傳送FIFO佇列,在多工資料傳送情境下,既能保證資料傳送任務能夠得到執行,又可解決資料傳送衝突問題。
select接收資料:有效監聽串列埠接收資料,提高執行效率,減少出錯概率。
原始碼如下:
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; }