Guo Wenxue
2020-06-29 fea9eefde499e94fccd248cb40b347c44a8fd5e8
update comport program
3 files modified
303 ■■■■ changed files
apue/5.Comport/comport.c 189 ●●●● patch | view | raw | blame | history
apue/5.Comport/comport.h 100 ●●●● patch | view | raw | blame | history
apue/5.Comport/comport_main.c 14 ●●●● patch | view | raw | blame | history
apue/5.Comport/comport.c
@@ -1,39 +1,40 @@
/*  ********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *      Copyright:  (C) 2020 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  cp_comport.c
 *    Description:  It's the comport operate library.
 *                  
 *        Version:  2.0.0(10/17/2018~)
 *        Version:  1.0.0(6/29/2018~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/17/2018 03:33:25 PM"
 *      ChangeLog:  1, Release initial version on "6/29/2018 03:33:25 PM"
 *                  
 ********************************************************************************/
#include    "comport.h"
#ifdef  COM_DEBUG
void disp_settings(comport_t *comport);
#endif
void set_settings(comport_t * comport, const char *settings);
/**************************************************************************************
 *  Description: Set the comport structure
 *   Input Args: dev_name:  The comport device name path, such as '/dev/ttyS3'
 *  Description: initialise the comport structure
 *
 *   Input Args:
 *                comport:  The comport work context pointer
 *               dev_name:  The comport device name path, such as '/dev/ttyS3'
 *               baudrate:  The baudrate, such as 115200
 *               settings:  The databit,parity,stopbit,flowctrl settings, such as '8N1N'
 *  Output Args: NONE
 * Return Value: The comport_t structure pointer.
 *
 * Return Value: 0: Successfully      <0: Failure
 *
 *************************************************************************************/
comport_t *comport_init(const char *dev_name, int baudrate, const char *settings)
int comport_init(comport_t *comport, const char *dev_name, int baudrate, const char *settings)
{
    comport_t *comport = NULL;
    if (NULL == (comport = (comport_t *) malloc(sizeof(comport_t))))
    if( !comport )
    {
        return NULL;
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        return -1;
    }
    memset(comport, 0, sizeof(comport_t));
    comport->frag_size = 128;
@@ -41,16 +42,27 @@
    comport->baudrate = baudrate;
    set_settings(comport, settings);
#ifdef  COM_DEBUG
    disp_settings(comport);
#endif
    return comport;
    return 0;
}
/*+-----------------------------------------------------------------------------------------+
 *  description: display current comport settings such as databit,parity,stopbit,flowctrl
 *   input args: $comport:  corresponding comport point
 *+-----------------------------------------------------------------------------------------+*/
#ifdef  COM_DEBUG
void disp_settings(comport_t *comport)
{
    if( !comport)
    {
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        return ;
    }
    COM_PRINT("Device:\t\t\t\"%s\"\n", comport->dev_name);
    COM_PRINT("Baudrate:\t\t%ld\n", comport->baudrate);
    COM_PRINT("DataBit:\t\t\'%d\'\n", comport->databit);
@@ -100,8 +112,11 @@
 *************************************************************************************/
void set_settings(comport_t * comport, const char *settings)
{
    if(NULL==settings || NULL==comport)
    if( !settings || !comport)
    {
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        return ;
    }
    switch (settings[0])        /* data bit */
    {
@@ -179,31 +194,18 @@
    comport->fd = -1;
}
void comport_term(comport_t * comport)
{
    if(NULL == comport)
        return;
    if ( comport->fd > 0 )
    {
        comport_close(comport);
    }
    memset(comport, 0x00, sizeof(comport_t));
    free(comport);
    return;
}
int comport_open(comport_t * comport)
{
    int retval = -1;
    int rv = -1;
    struct termios old_cfg, new_cfg;
    int old_flags;
    long tmp;
    if(NULL==comport)
    if( !comport )
    {
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        return -1;
    }
    comport_close(comport);
@@ -212,14 +214,14 @@
    {
        COM_PRINT("Open Not tty device \"%s\"\n", comport->dev_name);
        comport->fd = open(comport->dev_name, O_RDWR);
        retval = comport->fd<0 ? -2 : comport->fd;
        rv = comport->fd<0 ? -2 : comport->fd;
        goto CleanUp;
    }
    comport->fd = open(comport->dev_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (comport->fd < 0)
    {
        retval = -3;
        rv = -3;
        goto CleanUp;
    }
    COM_PRINT("Open device \"%s\"\n", comport->dev_name);
@@ -230,19 +232,19 @@
        // Flush input and output
        if (-1 == tcflush(comport->fd, TCIOFLUSH))
        {
            retval = -4;
            rv = -4;
            goto CleanUp;
        }
    }
    else                        // Failure
    {
        retval = -5;
        rv = -5;
        goto CleanUp;
    }
    if (0 != tcgetattr(comport->fd, &old_cfg))
    {
        retval = -6;          // Failed to get Com settings
        rv = -6;          // Failed to get Com settings
        goto CleanUp;
    }
@@ -389,38 +391,38 @@
    tcflush(comport->fd, TCIFLUSH);
    if (0 != tcsetattr(comport->fd, TCSANOW, &new_cfg))
    {
        retval = -7;          // Failed to set device com port settings
        rv = -7;          // Failed to set device com port settings
        goto CleanUp;
    }
    COM_PRINT("Connected device \"%s\".\n", comport->dev_name);
    retval = comport->fd;
    rv = comport->fd;
CleanUp:
    COM_PRINT("Open device \"%s\" %s.\n", comport->dev_name, retval>0 ? "successfully" : "failure");
    return retval;
    COM_PRINT("Open device \"%s\" %s.\n", comport->dev_name, rv>0 ? "successfully" : "failure");
    return rv;
}
int comport_recv(comport_t * comport, char *buf, int buf_size, unsigned long timeout)
{
    int retval = 0;             // Function return value
    int rv = 0;             // Function return value
    int iRet;
    fd_set stReadFds, stExcpFds;
    struct timeval stTime;
    if (NULL == buf || 0 >= buf_size)
    if ( !buf || buf_size<0 )
    {
        COM_PRINT("%s() usage error.\n", __FUNCTION__);
        retval = -1;
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        rv = -1;
        goto CleanUp;
    }
    if ( comport->fd < 0 )
    {
        COM_PRINT("%s() comport not connected.\n", __FUNCTION__);
        retval = -2;
        rv = -2;
        goto CleanUp;
    }
@@ -439,21 +441,21 @@
        iRet = select(comport->fd + 1, &stReadFds, 0, &stExcpFds, &stTime);
        if (0 == iRet)
        {
            retval = 0;         // No data in Com port buffer
            rv = 0;         // No data in Com port buffer
            goto CleanUp;
        }
        else if (0 < iRet)
        {
            if (0 != FD_ISSET(comport->fd, &stExcpFds))
            {
                retval = -6;  // Error during checking recv status
                rv = -6;  // Error during checking recv status
                COM_PRINT("Error checking recv status.\n");
                goto CleanUp;
            }
            if (0 == FD_ISSET(comport->fd, &stReadFds))
            {
                retval = 0;  // No incoming data
                rv = 0;  // No incoming data
                COM_PRINT("No incoming data.\n");
                goto CleanUp;
            }
@@ -463,12 +465,12 @@
            if (EINTR == errno)
            {
                COM_PRINT("catch interrupt signal.\n");
                retval = 0;  // Interrupted signal catched
                rv = 0;  // Interrupted signal catched
            }
            else
            {
                COM_PRINT("Check recv status failure.\n");
                retval = -7;  // Error during checking recv status
                rv = -7;  // Error during checking recv status
            }
            goto CleanUp;
@@ -482,9 +484,9 @@
    if (0 > iRet)
    {
        if (EINTR == errno)
            retval = 0;      // Interrupted signal catched
            rv = 0;      // Interrupted signal catched
        else
            retval = -3;      // Failed to read Com port
            rv = -3;      // Failed to read Com port
        goto CleanUp;
    }
@@ -501,78 +503,69 @@
    }
#endif
    retval = iRet;
    rv = iRet;
  CleanUp:
    return retval;
    return rv;
}
int comport_send(comport_t * comport, char *buf, int send_bytes)
int comport_send(comport_t * comport, char *buf, int bytes)
{
    char *ptr, *end;
    int retval = 0;
    int send = 0;
    int             i;
    int             left_bytes;
    int             rv = 0;
    if (NULL == buf || 0 >= send_bytes)
    if( !buf || bytes<=0 )
    {
        COM_PRINT("%s() Usage error.\n", __FUNCTION__);
        retval = -1;
        COM_PRINT("Invalid input arugments in %s().\n", __FUNCTION__);
        rv = -1;
        goto CleanUp;
    }
    if ( comport->fd < 0 )    // Comport not opened ?
    {
        retval = -3;
        COM_PRINT("Serail not connected.\n");
        rv = -3;
        COM_PRINT("Serail port not connected.\n");
        goto CleanUp;
    }
    //printf("Send %s with %d bytes.\n", buf, send_bytes);
    //printf("Send %s with %d bytes.\n", buf, bytes);
    // Large data, then slice them and send
    if (comport->frag_size < send_bytes)
    if (bytes > comport->frag_size )
    {
        ptr = buf;
        end = buf + send_bytes;
        i = 0;
        left_bytes = bytes;
        do
        while( left_bytes >= 0 )
        {
            // Large than frag_size
            if (comport->frag_size < (end - ptr))
            if( left_bytes > comport->frag_size )
                rv = write(comport->fd, &buf[i], comport->frag_size);
            else
                rv = write(comport->fd, &buf[i], left_bytes);
            if( rv < 0 )
            {
                send = write(comport->fd, ptr, comport->frag_size);
                if (0 >= send || comport->frag_size != send)
                {
                    retval = -4;
                rv = -4;
                    goto CleanUp;
                }
                ptr += comport->frag_size;
            i += rv;
            left_bytes -= rv;
            }
            else                // Less than frag_size, maybe last fragmention.
    }
    /* The send data is not large than a fragmention, send in one time. */
    else
            {
                send = write(comport->fd, ptr, (end - ptr));
                if (0 >= send || (end - ptr) != send)
        rv = write(comport->fd, buf, bytes);
        if ( rv<=0 || rv!=bytes )
                {
                    retval = -4;
                    goto CleanUp;
                }
                ptr += (end - ptr);
            }
        }
        while (ptr < end);
    }
    else                        // The send data is not large than a fragmention.
    {
        send = write(comport->fd, buf, send_bytes);
        if (0 >= send || send_bytes != send)
        {
            retval = -5;
            rv = -5;
            goto CleanUp;
        }
    }
  CleanUp:
    return retval;
    return rv;
}
apue/5.Comport/comport.h
@@ -1,13 +1,13 @@
/*********************************************************************************
 *      Copyright:  (C) 2018 LingYun IoT System Studio
 *      Copyright:  (C) 2020 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  comport.h
 *    Description:  This head file is for the common TTY/Serial port operator library 
 *                   
 *        Version:  1.0.0(10/17/2018~)
 *        Version:  1.0.0(06/29/2020~)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "10/17/2018 03:33:25 PM"
 *      ChangeLog:  1, Release initial version on "06/29/2020 03:33:25 PM"
 *                     
 ********************************************************************************/
#ifndef  __COMPORT_H_
@@ -27,8 +27,6 @@
#include  <sys/stat.h>
#include  <sys/select.h>
#define BUF_64  64
#ifndef DEVNAME_LEN
#define DEVNAME_LEN          64
#endif
@@ -40,67 +38,77 @@
#define COM_PRINT(format,args...) do{} while(0);
#endif
//#define msleep(m)               {struct timespec cSleep; cSleep.tv_sec = 0; cSleep.tv_nsec = m * 1000; nanosleep(&cSleep, 0);}
typedef struct comport_s
{
    char           dev_name[DEVNAME_LEN];
    unsigned char  databit, parity, stopbit, flowctrl;
    long           baudrate;
    int            fd;
    char           dev_name[DEVNAME_LEN];
    long           baudrate;
    unsigned char  databit;
    unsigned char  parity;
    unsigned char  stopbit;
    unsigned char  flowctrl;
    int            frag_size;
} comport_t;
/*
 *  description: initialise the comport structure
/*+-----------------------------------------------------------------------------------------+
 *  description: Initialise the comport structure
 *
 *   input args: $dev_name:  The comport device name path, such as '/dev/ttyS3'
 *   input args:
 *                $comport:  The comport work context pointer
 *               $dev_name:  The comport device name path, such as '/dev/ttyS3'
 *               $baudrate:  The baudrate, such as 115200
 *               $settings:  The databit,parity,stopbit,flowctrl settings, such as '8N1N'
 *
 * return value: The comport_t structure pointer, NULL means failure.
 */
comport_t *comport_init(const char *dev_name, int baudrate, const char *settings);
 * return value: 0: Successfully      <0: Failure
 *+-----------------------------------------------------------------------------------------+*/
int comport_init(comport_t *comport, const char *dev_name, int baudrate, const char *settings);
/*
 *  description: Open the comport specified by $comport
 *   input args: $comport:  corresponding comport point
 * return value: The comport opened file description, <0 means failure
 */
extern int  comport_open(comport_t * comport);
/*
 *  description: read data from $comport in $timeout <ms> to $buf no more than $buf_size bytes
 * return value: the actual read data bytes, <0: read failure
 */
extern int  comport_recv(comport_t * comport, char *buf, int buf_size, unsigned long timeout);
/*
 *  description: write $send_bytes bytes data from $buf to $comport
 * return value: 0: write ok  <0: write failure
 */
extern int  comport_send(comport_t * comport, char *buf, int send_bytes);
/*
/*+-----------------------------------------------------------------------------------------+
 *  description: display current comport settings such as databit,parity,stopbit,flowctrl
 *   input args: $comport:  corresponding comport point 
 */
//extern void disp_settings(comport_t * comport);
 *+-----------------------------------------------------------------------------------------+*/
#ifdef COM_DEBUG
extern void disp_settings(comport_t * comport);
#endif
/*
/*+-----------------------------------------------------------------------------------------+
 *  description: Open the comport specified by $comport
 *   input args: $comport: comport work context
 * return value: >0: The comport opened file description, <0: Failure
 *+-----------------------------------------------------------------------------------------+*/
extern int comport_open(comport_t * comport);
/*+-----------------------------------------------------------------------------------------+
 *  description: close comport 
 *   input args: $comport:  corresponding comport point 
 */
 *+-----------------------------------------------------------------------------------------+*/
extern void comport_close(comport_t * comport);
/*
 *  description: terminat comport, close and free it
 *   input args: $comport:  corresponding comport point
 */
extern void comport_term(comport_t * comport);
/*+-----------------------------------------------------------------------------------------+
 *  description: write $send_bytes bytes data from $buf to $comport
 * return value: 0: write ok  <0: write failure
 *+-----------------------------------------------------------------------------------------+*/
extern int  comport_send(comport_t * comport, char *buf, int send_bytes);
/*+-----------------------------------------------------------------------------------------+
 *  description: read data from $comport in $timeout <ms> to $buf, no more than $buf_size bytes
 * return value: the actual read data bytes, <0: read failure
 *+-----------------------------------------------------------------------------------------+*/
extern int  comport_recv(comport_t * comport, char *buf, int buf_size, unsigned long timeout);
#endif
apue/5.Comport/comport_main.c
@@ -38,7 +38,7 @@
    char *settings = "8N1N";
    char buf[512];
    unsigned char disp_mode = 0x00;
    comport_t *comport = NULL;
    comport_t     comport;
    struct sigaction sigact;
@@ -96,13 +96,13 @@
        return 0;
    }
    if (NULL == (comport = comport_init(dev_name, baudrate, settings)))
    if ( comport_init(&comport, dev_name, baudrate, settings) < 0 )
    {
        printf("Comport initialize failure.\n");
        return -1;
    }
    if ( (retval=comport_open(comport)) < 0)
    if ( (retval=comport_open(&comport)) < 0)
    {
        printf("Failed to open %s with baudrate %d, %s. RetCode [%d]\n", dev_name, baudrate,
               settings, retval);
@@ -124,7 +124,7 @@
    while (0x01 == g_ucProcToken)
    {
        recv_size = comport_recv(comport, buf, sizeof(buf) - 1, 10);
        recv_size = comport_recv(&comport, buf, sizeof(buf) - 1, 10);
        if (recv_size > 0)
        {
            for (i = 0; i < recv_size; i++)
@@ -149,17 +149,17 @@
                buf[0] = retval;
            }
            comport_send(comport, buf, 1);
            comport_send(&comport, buf, 1);
        }
        else if (0x00 != g_ucCtrlZ)
        {
            g_ucCtrlZ = 0x00;
            buf[0] = 0x1A;
            comport_send(comport, buf, 1);
            comport_send(&comport, buf, 1);
        }
    }
    comport_term(comport);
    comport_close(&comport);
    return 0;
}                               /* ----- End of main() ----- */