嵌入式Linux串口操作接口

来源:互联网 发布:网络歌手叶子 编辑:程序博客网 时间:2024/04/29 08:00

摘要

鉴于串口在嵌入式系统中广泛应用于操作GPRS模块、读卡器模块和GPS北斗模块等,串口操作成为嵌入式系统开发中必备工作,但是目前web中并没有提供一个封装良好的串口初始化和读写接口函数,因此本文基于工程实践提供了操作串口的接口函数和测试程序,为嵌入式Linux的串口操作提供了较大的便利。本文中提供的串口操作接口函数并未将常用串口参数如波特率、数据位、停止位和校验方式进行参数化,因此也有待进一步封装。

背景

由于智慧泊车工程项目中开发的硬件设备需要通过串口和AT命令访问GPRS模块,自己的工作环境也从涉密事业单位变成了能够随时能够访问Internet的公司,因此打算逐步将这些操作进行抽象和封装,以备不时之需。受到开发周期的限制,目前还未来得及将常用串口参数如波特率、数据位、停止位和校验方式进行参数化,在后续工作中会逐步完善和提高,也希望从业同行能够对其中不足进行批评指正,实现共同进步。

技术方案

串口操作涉及的文件主要是termios.h头文件中的struct termios结构,该结构的定义如下:

#define NCC 8struct termio { unsigned short c_iflag; unsigned short c_oflag; unsigned short c_cflag; unsigned short c_lflag; unsigned char c_line; unsigned char c_cc[NCC];};

详细参数定义内核代码中有较详细的解释,后续再博客修改时会陆续加上。
串口操作接口函数头文件uart.h文件

/**@brief:uart operation interface*@author:*@email:*@date:30th Oct 2015*/#ifndef __UART_H__#define __UART_H__#include <termios.h>#include <unistd.h>#include <fcntl.h>#define DATA_BUFF_SIZE  256int open_serial(char pchSerialName[], int nSerialNameLen);int config_serial(int nFdSerial);void signal_serial_data_prepared_handler(int nFdSerial);int write_serial(int nFdSerial, char pchDataBuf[], int nDataBufLen);int close_serial(int nFdSerial);#endif

串口操作接口函数源文件uart.c文件

/**@brief:uart operation interface*@author:*@email:*@date:30th Oct 2015*/#include <string.h>#include "uart.h"char g_serial_data_buffer[DATA_BUFF_SIZE] = { 0 };int open_serial(char pchSerialName[], int nSerialNameLen){    int nFdSerial;    if(pchSerialName == NULL || nSerialNameLen <= 0)        return -1;    nFdSerial = open(pchSerialName, O_RDWR|O_NOCTTY);    if(nFdSerial < 0)        return -1;    return nFdSerial;}/**@brief:configure serial port as 115200bps | 8 databits | 1 stopbit | no parity check*@param:    nFdSerial:handle of serial port*@return:*@author:*@date:31th Oct 2015*@todo:parameterize uart parameters*/int config_serial(int nFdSerial){    struct termios tio;    tcgetattr(nFdSerial, &tio);    tcflush(nFdSerial, TCIFLUSH);    cfsetispeed(&tio, B115200);//115200bps    cfsetospeed(&tio, B115200);    tio.c_cflag |= CS8;//8 data bits    tio.c_cflag &= ~PARENB;//no parity check    tio.c_oflag &= ~OPOST;    tio.c_cflag &= ~CSTOPB;//1 stop bit    tio.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN);    tio.c_iflag &= ~(INPCK | BRKINT | ICRNL | ISTRIP | IXON);      tio.c_cc[VMIN] = 64;    tio.c_cc[VTIME] = 1;    if(tcsetattr(nFdSerial, TCSANOW, &tio) != 0)    {        perror("%s,L%d,in %s, configure serial failed.\n", __FILE__, __LINE__, __func__);        return -1;    }    return 0;}void signal_serial_data_prepared_handler(int nFdSerial){    int nReadBufLen = 0;    memset(g_serial_data_buffer, 0, sizeof(g_serial_data_buffer));    read(nFdSerial, g_serial_data_buffer, DATA_BUFF_SIZE);}int write_serial(int nFdSerial, char pchDataBuf[], int nDataBufLen){    int nWriteBufLen = 0;    nWriteBufLen = write(nFdSerial, pchDataBuf, nDataBufLen);    return nWriteBufLen;}int close_serial(int nFdSerial){    if(nFdSerial < 0)    {        perror("%s,L%d,in %s, close serial failed.\n", __FILE__, __LINE__, __func__);        return -1;    }    close(nFdSerial);    return 0;}

串口测试主程序main.c文件如下。

#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>#include "uart.h"#define UART_DEVICE_NAME    "/dev/ttySAC0"int nFdSerial = -1;void system_exit(int nExitCode){    if(nFdSerial > 0)        close(nFdSerial);    exit(nExitCode);}int main(int argc, char * * argv, char * * env){    char chDataTest[16] = { 0 };    int nIndex = 0;    nFdSerial = open_serial(UART_DEVICE_NAME, strlen(UART_DEVICE_NAME));    if(nFdSerial < 0)    {        printf("%s,L%d,in %s, open %s failed.\n", __FILE__, __LINE__, __func__, UART_DEVICE_NAME);        return;    }       config_serial(nFdSerial);    signal(SIGINT, system_exit);    for(nIndex = 0; nIndex < sizeof(chDataTest); nIndex++)    {        chDataTest[nIndex] = nIndex + 1;    }       while(1)    {        write_serial(nFdSerial, chDataTest, sizeof(chDataTest));        usleep(1000000);        }    return 0;}

在linux上交叉编译的Makefile文件如下。

#!/bin/shCROSS=arm-linux-CC=$(CROSS)gccFLAGS=-lpthread -wallobjects = main.o uart.o uart_test:$(objects)    $(CC) -o uart_test $(objects)      cp uart_test /mnt/hgfs/vmware_shared/imagesclean:    rm  -f uart_test *.o

测试结果如下图所示。
串口测试结果图
上文中的源码链接如下:
http://www.pudn.com/downloads711/sourcecode/embedded/detail2854204.html

结语

目前提供的接口简化了串口操作,但是串口的主要参数还有待进一步参数化,另外还需要采用软中断用户自定义signal方式实现串口接收数据处理,在后续的工程开发中会进一步完善。

0 0
原创粉丝点击