Linux Serial Programming Tutorial (iii)--serial port programming detailed __HTML5

Source: Internet
Author: User
Tags assert vmin
Linux Serial Programming Tutorial (iii)--serial port programming detailed

Preface: This chapter will formally explain the serial port programming technology, uses a serial port to send and receive the data the procedure, comes step-by-step explanation.

Note: You can download my source code for reference. Open serial Port

As we all know, the device is in the form of a file in the Linux system, so we access the device in the manner of opening the file. It should be noted here that ordinary users generally can not access the device directly, need root permissions.
There are 3 ways to solve this problem: Run as root superuser. (commonly) Change the access rights of device files. Use setuid in the program to run the program as the serial device owner.

Code:

#include <stdio.h>
#include <fcntl.h>
#include <assert.h>

static int fd;

int uart_open (int fd,const char *pathname)
{
    assert (pathname);

    /* Open serial port *
    /FD = open (pathname,o_rdwr| o_noctty| O_ndelay);
    if (fd = = 1)
    {
        perror ("Open UART failed!");
        return-1;
    }

    /* Clear serial port non-blocking sign/
    if (Fcntl (fd,f_setfl,0) < 0)
    {
        fprintf (stderr, "Fcntl failed!\n");
        return-1;
    }

    return FD;
}

Description: O_noctty: means that the device is open, the program will not become the control terminal of the port. If you do not use this flag, the CTRL + C stop signal over the keyboard will affect the process. O_ndelay: Indicates that you do not care about the state of the DCD signal line (whether the other end of the port is active or stopped). Close serial Port

Turning off the serial port operation is simple, but you need to be aware that you need to do some cleanup after the shutdown.

Code:

#include <unistd.h>
#include <assert.h>

static int fd;

int uart_close (int fd)
{
    assert (FD);
    Close (FD);

    /* You can do some cleanup work here

    /* return 0;
}
Configure serial Port

Serial port initialization needs to set serial port baud rate, data flow control, frame format (that is, the number of data bits, stop bit, check bit, Data flow control).

Code:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <
assert.h> #include <termios.h> #include <string.h> static int ret;

static int fd;

    int uart_set (int fd,int baude,int c_flow,int bits,char parity,int stop) {struct options;
        /* Get Terminal properties */if (tcgetattr (fd,&options) < 0) {perror ("tcgetattr error");
    return-1;
            /* Set Input output baud rate, both remain consistent * * Switch (baude) {case 4800:cfsetispeed (&options,b4800);
            Cfsetospeed (&options,b4800);
        Break
            Case 9600:cfsetispeed (&options,b9600);
            Cfsetospeed (&options,b9600);
        Break
            Case 19200:cfsetispeed (&options,b19200);
            Cfsetospeed (&options,b19200);
        Break
            Case 38400:cfsetispeed (&options,b38400);
            Cfsetospeed (&options,b38400); Break;
            default:fprintf (stderr, "Unkown baude!\n");
    return-1; 
    /* Set control mode/* Options.c_cflag |= clocal;//Guarantee program does not occupy the serial port Options.c_cflag |= cread;//Guarantee Program can read data from the string/* Set Data flow control * *
            Switch (c_flow) {case 0://does not flow control Options.c_cflag &= ~crtscts;
        Break
            Case 1://for hardware flow control options.c_cflag |= crtscts;
        Break Case 2://for Software flow control Options.c_cflag |= ixon| Ixoff|
            Ixany;
        Break
            default:fprintf (stderr, "Unkown c_flow!\n");
    return-1; /* Set Data bit */switch (BITS) {case 5:options.c_cflag &= ~csize;//shield other flag bit op
            Tions.c_cflag |= CS5;
        Break
            Case 6:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS6;
        Break
            Case 7:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS7;Break
            Case 8:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS8;
        Break
            default:fprintf (stderr, "Unkown bits!\n");
    return-1; /* Set parity bit */switch (parity) {/* No parity bit * * case ' n ': Case ' n ': OPTIONS.C_CFL
        AG &= ~parenb;//parenb: Generating parity bit, performing parity Options.c_cflag &= ~INPCK;//INPCK: making parity function break; 
            /* Set to a space, that is, stop bit 2-bit * * case ' s ': The case ' s ': Options.c_cflag &= ~parenb;//parenb: Create parity bit, perform parity
        Options.c_cflag &= ~CSTOPB;//CSTOPB: Use two bit stop bit break; /* Set odd check/Case ' O ': Case ' o ': Options.c_cflag |= parenb;//parenb: Generate parity bit, perform parity opti Ons.c_cflag |= parodd;//parodd: If the setting is odd check, otherwise parity Options.c_cflag |= INPCK;//INPCK: Make parity work OPTIONS.C
        _cflag |= Istrip;//istrip: If set then the valid input number is stripped 7 bytes, otherwise all 8-bit break is preserved; /* SetParity/Case ' E ': Case ' e ': Options.c_cflag |= Parenb;//parenb: Generating parity bit, performing parity options . C_cflag &= ~parodd;//parodd: If set to odd check, or parity Options.c_cflag |= INPCK;//INPCK: Make parity work options
        . C_cflag |= Istrip;//istrip: If set then the valid input number is stripped 7 bytes, otherwise all 8 bit break is preserved;
            default:fprintf (stderr, "Unkown parity!\n");
    return-1;
            /* Set Stop bit */switch (stop) {case 1:options.c_cflag &= ~CSTOPB;//CSTOPB: Use two-bit stop bit
        Break
        Case 2:options.c_cflag |= CSTOPB;//CSTOPB: Use two bit stop bit break;
            default:fprintf (stderr, "Unkown stop!\n");
    return-1; /* Set the output mode to the original output/Options.c_oflag &= ~opost;//opost: If the setting is processed according to the defined output, otherwise all c_oflag fail/* Set local mode to original mode * * * optio Ns.c_lflag &= ~ (Icanon | ECHO | Echoe |
    ISIG); /* *icanon: Allow canonical mode for input processing *echo: Allow local echo of input characters *echoe: Execute Backspace,space,backspa when receiving EpaseCe combination *isig: Allow signal/* Set wait time and minimum accept character/options.c_cc[vtime] = 0;//can be set in select options.c_cc[vmin] = 1;

    Read at least one character/* If a data overflow occurs, only the data is accepted, but no read operation is performed * * Tcflush (Fd,tciflush);
        /* Activation configuration */if (tcsetattr (fd,tcsanow,&options) < 0) {perror ("tcsetattr failed");
    return-1;

return 0; }
Read and write serial port

Code:

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include < assert.h> #include <termios.h> #include <string.h> #include <sys/time.h> #include <sys/types.h
> #include <errno.h> static int ret;

static int fd;
    * * Secure Read/write function * * ssize_t safe_write (int fd, const void *vptr, size_t n) {size_t nleft;
    ssize_t Nwritten;

    const char *ptr;
    ptr = vptr;

    Nleft = n; while (Nleft > 0) {if (Nwritten = write (FD, PTR, nleft)) <= 0) {if (Nwritten < 0&
            &errno = = eintr) Nwritten = 0;
        else return-1;
        } nleft-= Nwritten;
    PTR + = Nwritten;
return (n);
    } ssize_t safe_read (int fd,void *vptr,size_t n) {size_t nleft;
    ssize_t nread;

    Char *ptr;
    Ptr=vptr;

    Nleft=n; while (Nleft > 0) {if (nread = Read (fd,ptr,nleft)) < 0) {if (errNo = = Eintr)/interrupted by signal nread = 0;
        else return-1;
        else if (nread = 0) break;
        Nleft-= nread;
    PTR + = nread;
return (N-nleft);
    int uart_read (int fd,char *r_buf,size_t len) {ssize_t cnt = 0;
    Fd_set RfDs;

    struct Timeval time;
    /* Add the file descriptor to the read descriptor set/Fd_zero (&AMP;RFDS);

    Fd_set (Fd,&rfds);
    /* Set Timeout to 15s*/time.tv_sec = 15;

    time.tv_usec = 0;
    /* Implementation of the serial port i/o*/ret = select (Fd+1,&rfds,null,null,&time);
            Switch (ret) {case-1: fprintf (stderr, "select error!\n");
        return-1;
            Case 0:fprintf (stderr, "Time over!\n");
        return-1;
            default:cnt = Safe_read (Fd,r_buf,len);
                if (cnt = = 1) {fprintf (stderr, "read error!\n");
            return-1;
    } return CNT; int uart_write (int fd,const Char *w_buf,size_t len) {ssize_t cnt = 0;
    CNT = Safe_write (Fd,w_buf,len);
        if (cnt = = 1) {fprintf (stderr, "Write error!\n");
    return-1;
} return CNT; }
Full program

readers are requested to write the specific reading and writing commands.

/************************************************************************* > File name:uart_operation.c > A Uthor:answer > Mail:1045837697@qq.com > Created time:2015 year September 02 Wednesday 12:45 48 sec ************************* /#include <stdio.h> #include <stdlib.h> #include < fcntl.h> #include <unistd.h> #include <assert.h> #include <termios.h> #include <string.h> #
include<sys/time.h> #include <sys/types.h> #include <errno.h> static int ret;

static int fd;
    * * Secure Read/write function * * ssize_t safe_write (int fd, const void *vptr, size_t n) {size_t nleft;
    ssize_t Nwritten;

    const char *ptr;
    ptr = vptr;

    Nleft = n; while (Nleft > 0) {if (Nwritten = write (FD, PTR, nleft)) <= 0) {if (Nwritten < 0&
            &errno = = eintr) Nwritten = 0;
        else return-1; } nleft-= NWRitten;
    PTR + = Nwritten;
return (n);
    } ssize_t safe_read (int fd,void *vptr,size_t n) {size_t nleft;
    ssize_t nread;

    Char *ptr;
    Ptr=vptr;

    Nleft=n;
                while (Nleft > 0) {if (nread = Read (fd,ptr,nleft)) < 0) {if (errno = = eintr)/interrupted by signal
            nread = 0;
        else return-1;
        else if (nread = 0) break;
        Nleft-= nread;
    PTR + = nread;
return (N-nleft);

    int uart_open (int fd,const char *pathname) {assert (pathname); /* Open serial port */FD = open (pathname,o_rdwr| o_noctty|
    O_ndelay);
        if (fd = = 1) {perror ("Open UART failed!");
    return-1;
        /* Clear serial port non-blocking flag/if (FCNTL (fd,f_setfl,0) < 0) {fprintf (stderr, "Fcntl failed!\n");
    return-1;
} return FD;

    int uart_set (int fd,int baude,int c_flow,int bits,char parity,int stop) {struct options; /* ObtainedTake the terminal attribute/if (tcgetattr (fd,&options) < 0) {perror ("tcgetattr error");
    return-1;
            /* Set Input output baud rate, both remain consistent * * Switch (baude) {case 4800:cfsetispeed (&options,b4800);
            Cfsetospeed (&options,b4800);
        Break
            Case 9600:cfsetispeed (&options,b9600);
            Cfsetospeed (&options,b9600);
        Break
            Case 19200:cfsetispeed (&options,b19200);
            Cfsetospeed (&options,b19200);
        Break
            Case 38400:cfsetispeed (&options,b38400);
            Cfsetospeed (&options,b38400);
        Break
            default:fprintf (stderr, "Unkown baude!\n");
    return-1; 
    /* Set control mode/* Options.c_cflag |= clocal;//Guarantee program does not occupy the serial port Options.c_cflag |= cread;//Guarantee Program can read data from the string/* Set Data flow control * *
       Switch (c_flow) {case 0://does not flow control Options.c_cflag &= ~crtscts;     Break
            Case 1://for hardware flow control options.c_cflag |= crtscts;
        Break Case 2://for Software flow control Options.c_cflag |= ixon| Ixoff|
            Ixany;
        Break
            default:fprintf (stderr, "Unkown c_flow!\n");
    return-1; /* Set Data bit */switch (BITS) {case 5:options.c_cflag &= ~csize;//shield other flag bit op
            Tions.c_cflag |= CS5;
        Break
            Case 6:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS6;
        Break
            Case 7:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS7;
        Break
            Case 8:options.c_cflag &= ~csize;//shielding other sign bit options.c_cflag |= CS8;
        Break
            default:fprintf (stderr, "Unkown bits!\n");
    return-1;
/* Set parity bit */switch (parity) {/* No parity bit * * case ' n ': Case ' n ':            Options.c_cflag &= ~parenb;//parenb: Create parity bit, perform parity Options.c_cflag &= ~INPCK;//INPCK: Make parity
        With a break;
            /* Set to a space, that is, stop bit 2-bit * * case ' s ': The case ' s ': Options.c_cflag &= ~parenb;//parenb: Create parity bit, perform parity
        Options.c_cflag &= ~CSTOPB;//CSTOPB: Use two bit stop bit break; /* Set odd check/Case ' O ': Case ' o ': Options.c_cflag |= parenb;//parenb: Generate parity bit, perform parity opti Ons.c_cflag |= parodd;//parodd: If the setting is odd check, otherwise parity Options.c_cflag |= INPCK;//INPCK: Make parity work OPTIONS.C
        _cflag |= Istrip;//istrip: If set then the valid input number is stripped 7 bytes, otherwise all 8-bit break is preserved; /* Set parity/Case ' E ': Case ' e ': Options.c_cflag |= parenb;//parenb: Generate parity bit, perform parity opti Ons.c_cflag &= ~parodd;//parodd: If the setting is odd check, otherwise parity Options.c_cflag |= INPCK;//INPCK: Make parity work Opti Ons.c_cflag |= Istrip;//istrip: If set then the valid input number is stripped 7 bytes, otherwise all 8-bit break is preserved;
        default:fprintf (stderr, "Unkown parity!\n");
    return-1;
            /* Set Stop bit */switch (stop) {case 1:options.c_cflag &= ~CSTOPB;//CSTOPB: Use two-bit stop bit
        Break
        Case 2:options.c_cflag |= CSTOPB;//CSTOPB: Use two bit stop bit break;
            default:fprintf (stderr, "Unkown stop!\n");
    return-1; /* Set the output mode to the original output/Options.c_oflag &= ~opost;//opost: If the setting is processed according to the defined output, otherwise all c_oflag fail/* Set local mode to original mode * * * optio Ns.c_lflag &= ~ (Icanon | ECHO | Echoe |
    ISIG);
     /* *icanon: Allow canonical mode for input processing *echo: Allow local echo of input characters *echoe: Execute backspace,space,backspace combination *isig when receiving epase: Allow signal * * Set wait time and minimum accept character/options.c_cc[vtime] = 0;//can set options.c_cc[vmin in select = 1;//read at least one character/* If data occurs

    Overflow, only accept data, but do not read operation * * Tcflush (Fd,tciflush);
        /* Activation configuration */if (tcsetattr (fd,tcsanow,&options) < 0) {perror ("tcsetattr failed");
return-1;    return 0;
    int uart_read (int fd,char *r_buf,size_t len) {ssize_t cnt = 0;
    Fd_set RfDs;

    struct Timeval time; /* Add the file descriptor to the Read Descriptor collection/* Fd_

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.