Linux/Android系统开发 串口驱动源码,FIFO模式

该驱动适用于采用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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章