简体   繁体   English

使用BeagleBone Black读取两个串行端口时出现分段错误错误

[英]Segmentation Fault Error When Reading Two Serial Port with BeagleBone Black

I am getting Segmentation fault error while reading two diffentent serial communication line with using Debian GNU/Linux 7.4 on Beaglebone Black. 在Beaglebone Black上使用Debian GNU / Linux 7.4读取两条不同的串行通信线路时,出现了分段错误错误。 One of them is CAN-BUS data. 其中之一是CAN-BUS数据。 I am using Waveshares RS485/CAN CAPE module for this with using can-utils package. 我正在使用can-utils软件包来使用Waveshares RS485 / CAN CAPE模块。 " https://github.com/linux-can/can-utils/blob/master/candump.c " https://github.com/linux-can/can-utils/blob/master/candump.c

CAN log file CAN日志文件

And the other one is UART data by a GPS module called uBlox GY-NEO6MV2 module. 另一个是通过称为uBlox GY-NEO6MV2模块的GPS模块的UART数据。 For the GPS I have this code which works perfectly; 对于GPS,我有此代码,可以很好地工作。

    #include <stdio.h>
    #include <fcntl.h>   /* File Control Definitions           */
    #include <termios.h> /* POSIX Terminal Control Definitions */
    #include <unistd.h>  /* UNIX Standard Definitions      */ 
    #include <errno.h>   /* ERROR Number Definitions           */
    #include <string.h>  /* Array to String                   */ 

void main(void){
        int fd;/*File Descriptor*/


    /*------------------------------- Opening the Serial Port -------------------------------*/

    /* Change /dev/ttyUSB0 to the one corresponding to your system */
    while(1){
        fd = open("/dev/ttyO2",O_RDWR | O_NOCTTY);  /* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
                            /* O_RDWR   - Read/Write access to serial port       */
                            /* O_NOCTTY - No terminal will control the process   */
                            /* Open in blocking mode,read will wait              */



        if(fd == -1)                        /* Error Checking */
               printf("\n  Error! in Opening ttyO2  ");
        else
               printf("\n  ttyO2 Opened Successfully ");


        /*---------- Setting the Attributes of the serial port using termios structure --------- */

        struct termios SerialPortSettings;  /* Create the structure                          */

        tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */

        /* Setting the Baud rate */
        cfsetispeed(&SerialPortSettings,B9600); /* Set Read  Speed as 9600                       */
        cfsetospeed(&SerialPortSettings,B9600); /* Set Write Speed as 9600                       */

        /* 8N1 Mode */
        SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
        SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
        SerialPortSettings.c_cflag &= ~CSIZE;    /* Clears the mask for setting the data size             */
        SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */

        SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow Control                         */
        SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines       */ 


        SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /* Disable XON/XOFF flow control both i/p and o/p */
        SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* Non Cannonical mode                            */

        SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/

        /* Setting Time outs */
        SerialPortSettings.c_cc[VMIN] = 42; /* Read at least 51 characters */
        SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly   */


        if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
            printf("\n  ERROR ! in Setting attributes");
        else
            printf("\n  BaudRate = 9600 \n  StopBits = 1 \n  Parity   = none  \n\n");

        /*------------------------------- Read data from serial port -----------------------------*/

        tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer            */

        char read_buffer[42];   /* Buffer to store the data received              */
        int  bytes_read = 0;    /* Number of bytes read by the read() system call */
        int ia = 0; int a;
        int test = 0;
        char new_read[38];
        char curr_read[33];
        a = 0;
        do{
            bytes_read = read(fd,&read_buffer,42); /* Read the data                   */

            if(read_buffer[0] == '$')
                if(read_buffer[1] == 'G')
                    if(read_buffer[2] == 'P')
                        if(read_buffer[3] == 'G')
                            if(read_buffer[4] == 'G'){
                                for(ia=7;ia<bytes_read;ia++){    /*printing only the received characters*/
                                    new_read[a] = read_buffer[ia];
                                    printf("%c",read_buffer[ia]);
                                    a = a+1;
                                    test = 1;
                                }
                                strcpy(curr_read, new_read);
                                printf("\n%s \n", curr_read);
                            }
                            else
                                test = 0;
                        else
                            test = 0;
                    else
                        test = 0;
                else
                    test = 0;
            else
                test = 0;
        }while(test == 0);
        close(fd); /* Close the serial port */
    }

}

And for the CAN logging I am using the code in the link above. 对于CAN记录,我正在使用上面链接中的代码。 What I try to achive is logging two data in to same log file. 我试图达到的目标是将两个数据记录到同一日志文件中。 I modified the code above a little to get the datas only that I need; 我对上面的代码进行了一些修改,以仅获取所需的数据。 which is timestamp and location coordinates. 这是时间戳和位置坐标。

GPS edited data GPS编辑的数据

GPS module gives data every second so I am triyng to get one data from GPS and attach it to the next 1000 CAN data then write in to a .log file then read a new value from GPS. GPS模块每秒发送一次数据,因此我想从GPS中获取一个数据并将其附加到下一个1000 CAN数据中,然后写入.log文件,然后从GPS读取新值。 GPS modules communication bitrate is 9600kbps and CAN bitrate is 125000 kbps. GPS模块的通信比特率为9600kbps,CAN比特率为125000 kbps。 GPS is connected to UART2 pin, CAN to UART1. GPS连接到UART2引脚,CAN连接到UART1。 When I try to combine two code into one I get the Segmentation fault error. 当我尝试将两个代码合并为一个时,出现细分错误错误。 I made a little research its UNIX error code while violeting the restiricted memory space. 我对紫色的已恢复内存空间进行了一些研究,研究了它的UNIX错误代码。 But these two codes works perfectly when working seperatly. 但是,当单独工作时,这两个代码可以完美地工作。 This is where I got stucked. 这就是我卡住的地方。 The code I tried to merge is like; 我试图合并的代码就像;

/* for hardware timestamps - since Linux 2.6.30 */
#ifndef SO_TIMESTAMPING
#define SO_TIMESTAMPING 37
#endif

/* from #include <linux/net_tstamp.h> - since Linux 2.6.30 */
#define SOF_TIMESTAMPING_SOFTWARE (1<<4)
#define SOF_TIMESTAMPING_RX_SOFTWARE (1<<3)
#define SOF_TIMESTAMPING_RAW_HARDWARE (1<<6)

#define MAXSOCK 16    /* max. number of CAN interfaces given on the cmdline */
#define MAXIFNAMES 30 /* size of receive name index to omit ioctls */
#define MAXCOL 6      /* number of different colors for colorized output */
#define ANYDEV "any"  /* name of interface to receive from any CAN interface */
#define ANL "\r\n"    /* newline in ASC mode */

#define SILENT_INI 42 /* detect user setting on commandline */
#define SILENT_OFF 0  /* no silent mode */
#define SILENT_ANI 1  /* silent mode with animation */
#define SILENT_ON  2  /* silent mode (completely silent) */

static char *cmdlinename[MAXSOCK];
static __u32 dropcnt[MAXSOCK];
static __u32 last_dropcnt[MAXSOCK];
static char devname[MAXIFNAMES][IFNAMSIZ+1];
static int  dindex[MAXIFNAMES];
static int  max_devname_len; /* to prevent frazzled device name output */ 
const int canfd_on = 1;

#define MAXANI 4
const char anichar[MAXANI] = {'|', '/', '-', '\\'};
const char extra_m_info[4][4] = {"- -", "B -", "- E", "B E"};

extern int optind, opterr, optopt;

static volatile int running = 1;

void sigterm(int signo)
{
    running = 0;
}

int idx2dindex(int ifidx, int socket) {

    int i;
    struct ifreq ifr;

    for (i=0; i < MAXIFNAMES; i++) {
        if (dindex[i] == ifidx)
            return i;
    }

    /* create new interface index cache entry */

    /* remove index cache zombies first */
    for (i=0; i < MAXIFNAMES; i++) {
        if (dindex[i]) {
            ifr.ifr_ifindex = dindex[i];
            if (ioctl(socket, SIOCGIFNAME, &ifr) < 0)
                dindex[i] = 0;
        }
    }

    for (i=0; i < MAXIFNAMES; i++)
        if (!dindex[i]) /* free entry */
            break;

    if (i == MAXIFNAMES) {
        fprintf(stderr, "Interface index cache only supports %d interfaces.\n",
               MAXIFNAMES);
        exit(1);
    }

    dindex[i] = ifidx;

    ifr.ifr_ifindex = ifidx;
    if (ioctl(socket, SIOCGIFNAME, &ifr) < 0)
        perror("SIOCGIFNAME");

    if (max_devname_len < strlen(ifr.ifr_name))
        max_devname_len = strlen(ifr.ifr_name);

    strcpy(devname[i], ifr.ifr_name);

#ifdef DEBUG
    printf("new index %d (%s)\n", i, devname[i]);
#endif

    return i;
}

int main(int argc, char **argv)
{
    fd_set rdfs;
    int s[MAXSOCK];
    int bridge = 0;
    useconds_t bridge_delay = 0;
    unsigned char timestamp = 0;
    unsigned char hwtimestamp = 0;
    unsigned char down_causes_exit = 1;
    unsigned char dropmonitor = 0;
    unsigned char extra_msg_info = 0;
    unsigned char silent = SILENT_INI;
    unsigned char silentani = 0;
    unsigned char color = 0;
    unsigned char view = 0;
    unsigned char log = 0;
    unsigned char logfrmt = 0;
    int count = 0;
    int rcvbuf_size = 0;
    int opt, ret;
    int currmax, numfilter;
    int join_filter;
    char *ptr, *nptr;
    struct sockaddr_can addr;
    char ctrlmsg[CMSG_SPACE(sizeof(struct timeval) + 3*sizeof(struct timespec) + sizeof(__u32))];
    struct iovec iov;
    struct msghdr msg;
    struct cmsghdr *cmsg;
    struct can_filter *rfilter;
    can_err_mask_t err_mask;
    struct canfd_frame frame;
    int nbytes, i, maxdlen;
    struct ifreq ifr;
    struct timeval tv, last_tv;
    struct timeval timeout, timeout_config = { 0, 0 }, *timeout_current = NULL;
    FILE *logfile = NULL;

    int fd;/*File Descriptor*/
    struct termios SerialPortSettings;  /* Create the structure                          */


    signal(SIGTERM, sigterm);
    signal(SIGHUP, sigterm);
    signal(SIGINT, sigterm);

    last_tv.tv_sec  = 0;
    last_tv.tv_usec = 0;

    if (optind == argc) {
        print_usage(basename(argv[0]));
        exit(0);
    }

    if (logfrmt && view) {
        fprintf(stderr, "Log file format selected: Please disable ASCII/BINARY/SWAP options!\n");
        exit(0);
    }

    if (silent == SILENT_INI) {
        if (log) {
            fprintf(stderr, "Disabled standard output while logging.\n");
            silent = SILENT_ON; /* disable output on stdout */
        } else
            silent = SILENT_OFF; /* default output */
    }

    currmax = argc - optind; /* find real number of CAN devices */

    if (currmax > MAXSOCK) {
        fprintf(stderr, "More than %d CAN devices given on commandline!\n", MAXSOCK);
        return 1;
    }

    for (i=0; i < currmax; i++) {

        ptr = argv[optind+i];
        nptr = strchr(ptr, ',');

#ifdef DEBUG
        printf("open %d '%s'.\n", i, ptr);
#endif

        s[i] = socket(PF_CAN, SOCK_RAW, CAN_RAW);
        if (s[i] < 0) {
            perror("socket");
            return 1;
        }

        cmdlinename[i] = ptr; /* save pointer to cmdline name of this socket */

        if (nptr)
            nbytes = nptr - ptr;  /* interface name is up the first ',' */
        else
            nbytes = strlen(ptr); /* no ',' found => no filter definitions */

        if (nbytes >= IFNAMSIZ) {
            fprintf(stderr, "name of CAN device '%s' is too long!\n", ptr);
            return 1;
        }

        if (nbytes > max_devname_len)
            max_devname_len = nbytes; /* for nice printing */

        addr.can_family = AF_CAN;

        memset(&ifr.ifr_name, 0, sizeof(ifr.ifr_name));
        strncpy(ifr.ifr_name, ptr, nbytes);

#ifdef DEBUG
        printf("using interface name '%s'.\n", ifr.ifr_name);
#endif

        if (strcmp(ANYDEV, ifr.ifr_name)) {
            if (ioctl(s[i], SIOCGIFINDEX, &ifr) < 0) {
                perror("SIOCGIFINDEX");
                exit(1);
            }
            addr.can_ifindex = ifr.ifr_ifindex;
        } else
            addr.can_ifindex = 0; /* any can interface */

        if (nptr) {

            /* found a ',' after the interface name => check for filters */

            /* determine number of filters to alloc the filter space */
            numfilter = 0;
            ptr = nptr;
            while (ptr) {
                numfilter++;
                ptr++; /* hop behind the ',' */
                ptr = strchr(ptr, ','); /* exit condition */
            }

            rfilter = malloc(sizeof(struct can_filter) * numfilter);
            if (!rfilter) {
                fprintf(stderr, "Failed to create filter space!\n");
                return 1;
            }

            numfilter = 0;
            err_mask = 0;
            join_filter = 0;

            while (nptr) {

                ptr = nptr+1; /* hop behind the ',' */
                nptr = strchr(ptr, ','); /* update exit condition */

                if (sscanf(ptr, "%x:%x",
                       &rfilter[numfilter].can_id, 
                       &rfilter[numfilter].can_mask) == 2) {
                    rfilter[numfilter].can_mask &= ~CAN_ERR_FLAG;
                    numfilter++;
                } else if (sscanf(ptr, "%x~%x",
                          &rfilter[numfilter].can_id, 
                          &rfilter[numfilter].can_mask) == 2) {
                    rfilter[numfilter].can_id |= CAN_INV_FILTER;
                    rfilter[numfilter].can_mask &= ~CAN_ERR_FLAG;
                    numfilter++;
                } else if (*ptr == 'j' || *ptr == 'J') {
                    join_filter = 1;
                } else if (sscanf(ptr, "#%x", &err_mask) != 1) { 
                    fprintf(stderr, "Error in filter option parsing: '%s'\n", ptr);
                    return 1;
                }
            }

            if (err_mask)
                setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
                       &err_mask, sizeof(err_mask));

            if (join_filter && setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS,
                              &join_filter, sizeof(join_filter)) < 0) {
                perror("setsockopt CAN_RAW_JOIN_FILTERS not supported by your Linux Kernel");
                return 1;
            }

            if (numfilter)
                setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FILTER,
                       rfilter, numfilter * sizeof(struct can_filter));

            free(rfilter);

        } /* if (nptr) */

        /* try to switch the socket into CAN FD mode */
        setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));

        if (rcvbuf_size) {

            int curr_rcvbuf_size;
            socklen_t curr_rcvbuf_size_len = sizeof(curr_rcvbuf_size);

            /* try SO_RCVBUFFORCE first, if we run with CAP_NET_ADMIN */
            if (setsockopt(s[i], SOL_SOCKET, SO_RCVBUFFORCE,
                       &rcvbuf_size, sizeof(rcvbuf_size)) < 0) {
#ifdef DEBUG
                printf("SO_RCVBUFFORCE failed so try SO_RCVBUF ...\n");
#endif
                if (setsockopt(s[i], SOL_SOCKET, SO_RCVBUF,
                           &rcvbuf_size, sizeof(rcvbuf_size)) < 0) {
                    perror("setsockopt SO_RCVBUF");
                    return 1;
                }

                if (getsockopt(s[i], SOL_SOCKET, SO_RCVBUF,
                           &curr_rcvbuf_size, &curr_rcvbuf_size_len) < 0) {
                    perror("getsockopt SO_RCVBUF");
                    return 1;
                }

                /* Only print a warning the first time we detect the adjustment */
                /* n.b.: The wanted size is doubled in Linux in net/sore/sock.c */
                if (!i && curr_rcvbuf_size < rcvbuf_size*2)
                    fprintf(stderr, "The socket receive buffer size was "
                        "adjusted due to /proc/sys/net/core/rmem_max.\n");
            }
        }

        if (timestamp || log || logfrmt) {

            if (hwtimestamp) {
                const int timestamping_flags = (SOF_TIMESTAMPING_SOFTWARE | \
                                SOF_TIMESTAMPING_RX_SOFTWARE | \
                                SOF_TIMESTAMPING_RAW_HARDWARE);

                if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMPING,
                        &timestamping_flags, sizeof(timestamping_flags)) < 0) {
                    perror("setsockopt SO_TIMESTAMPING is not supported by your Linux kernel");
                    return 1;
                }
            } else {
                const int timestamp_on = 1;

                if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
                           &timestamp_on, sizeof(timestamp_on)) < 0) {
                    perror("setsockopt SO_TIMESTAMP");
                    return 1;
                }
            }
        }

        if (dropmonitor) {

            const int dropmonitor_on = 1;

            if (setsockopt(s[i], SOL_SOCKET, SO_RXQ_OVFL,
                       &dropmonitor_on, sizeof(dropmonitor_on)) < 0) {
                perror("setsockopt SO_RXQ_OVFL not supported by your Linux Kernel");
                return 1;
            }
        }

        if (bind(s[i], (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            perror("bind");
            return 1;
        }
    }

    if (log) {
        time_t currtime;
        struct tm now;
        char fname[sizeof("candump-2006-11-20_202026.log")+1];

        if (time(&currtime) == (time_t)-1) {
            perror("time");
            return 1;
        }

        localtime_r(&currtime, &now);

        sprintf(fname, "candump-%04d-%02d-%02d_%02d%02d%02d.log",
            now.tm_year + 1900,
            now.tm_mon + 1,
            now.tm_mday,
            now.tm_hour,
            now.tm_min,
            now.tm_sec);

        if (silent != SILENT_ON)
            printf("\nWarning: console output active while logging!");

        fprintf(stderr, "\nEnabling Logfile '%s'\n\n", fname);

        logfile = fopen(fname, "w");
        if (!logfile) {
            perror("logfile");
            return 1;
        }
    }

    /* these settings are static and can be held out of the hot path */
    iov.iov_base = &frame;
    msg.msg_name = &addr;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = &ctrlmsg;

    while (running) {

        /*------------------------------- Opening the Serial Port -------------------------------*/

        /* Change /dev/ttyUSB0 to the one corresponding to your system */

        fd = open("/dev/ttyO2",O_RDWR | O_NOCTTY);  /* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
                            /* O_RDWR   - Read/Write access to serial port       */
                            /* O_NOCTTY - No terminal will control the process   */
                            /* Open in blocking mode,read will wait              */


                                    /* Error Checking */
        if(fd == -1)                        
               printf("\n  Error! in Opening ttyO2  ");
        else
               printf("\n  ttyO2 Opened Successfully ");


        /*---------- Setting the Attributes of the serial port using termios structure --------- */

        //struct termios SerialPortSettings;    /* Create the structure                          */

        tcgetattr(fd, &SerialPortSettings); /* Get the current attributes of the Serial port */

        /* Setting the Baud rate */
        cfsetispeed(&SerialPortSettings,B9600); /* Set Read  Speed as 9600                       */
        cfsetospeed(&SerialPortSettings,B9600); /* Set Write Speed as 9600                       */

        /* 8N1 Mode */
        SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
        SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
        SerialPortSettings.c_cflag &= ~CSIZE;    /* Clears the mask for setting the data size             */
        SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */

        SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow Control                         */
        SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines       */ 


        SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /* Disable XON/XOFF flow control both i/p and o/p */
        SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* Non Cannonical mode                            */

        SerialPortSettings.c_oflag &= ~OPOST;/*No Output Processing*/

        /* Setting Time outs */
        SerialPortSettings.c_cc[VMIN] = 42; /* Read at least 42 characters */
        SerialPortSettings.c_cc[VTIME] = 0; /* Wait indefinetly   */


        if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0) /* Set the attributes to the termios structure*/
            printf("\n  ERROR ! in Setting attributes");
        else
            printf("\n  BaudRate = 9600 \n  StopBits = 1 \n  Parity   = none  \n\n");

        /*------------------------------- Read data from serial port -----------------------------*/

        tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer */

        char read_buffer[42];   /* Buffer to store the data received              */
        int  bytes_read = 0;    /* Number of bytes read by the read() system call */
        int ia = 0; int a;
        int test = 0;
        char new_read[38];
        char curr_read[33];
        int countc = 0;
        a = 0;
        do{
            bytes_read = read(fd,&read_buffer,42); /* Read the data                   */

            if(read_buffer[0] == '$')
                if(read_buffer[1] == 'G')
                    if(read_buffer[2] == 'P')
                        if(read_buffer[3] == 'G')
                            if(read_buffer[4] == 'G'){
                                for(ia=7;ia<bytes_read;ia++){    /*printing only the received characters*/
                                    new_read[a] = read_buffer[ia];
                                    //printf("%c",read_buffer[ia]);
                                    a = a+1;
                                    test = 1;
                                }
                                strcpy(curr_read, new_read);
                                //printf("\n%s \n", curr_read);
                            }
                            else
                                test = 0;
                        else
                            test = 0;
                    else
                        test = 0;
                else
                    test = 0;
            else
                test = 0;
        }while(test == 0);

        //tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer */

        close(fd); /* Close the serial port */

        while(countc < 1000){
            FD_ZERO(&rdfs);
            for (i=0; i<currmax; i++)
                FD_SET(s[i], &rdfs);

            if (timeout_current)
                *timeout_current = timeout_config;

            if ((ret = select(s[currmax-1]+1, &rdfs, NULL, NULL, timeout_current)) <= 0) {
                //perror("select");
                running = 0;
                continue;
            }

            for (i=0; i<currmax; i++) {  /* check all CAN RAW sockets */

                if (FD_ISSET(s[i], &rdfs)) {

                    int idx;

                    /* these settings may be modified by recvmsg() */
                    iov.iov_len = sizeof(frame);
                    msg.msg_namelen = sizeof(addr);
                    msg.msg_controllen = sizeof(ctrlmsg);  
                    msg.msg_flags = 0;

                    nbytes = recvmsg(s[i], &msg, 0);
                    idx = idx2dindex(addr.can_ifindex, s[i]);

                    if (nbytes < 0) {
                        if ((errno == ENETDOWN) && !down_causes_exit) {
                            fprintf(stderr, "%s: interface down\n", devname[idx]);
                            continue;
                        }
                        perror("read");
                        return 1;
                    }

                    if ((size_t)nbytes == CAN_MTU)
                        maxdlen = CAN_MAX_DLEN;
                    else if ((size_t)nbytes == CANFD_MTU)
                        maxdlen = CANFD_MAX_DLEN;
                    else {
                        fprintf(stderr, "read: incomplete CAN frame\n");
                        return 1;
                    }

                    if (count && (--count == 0))
                        running = 0;

                    if (bridge) {
                        if (bridge_delay)
                            usleep(bridge_delay);

                        nbytes = write(bridge, &frame, nbytes);
                        if (nbytes < 0) {
                            perror("bridge write");
                            return 1;
                        } else if ((size_t)nbytes != CAN_MTU && (size_t)nbytes != CANFD_MTU) {
                            fprintf(stderr,"bridge write: incomplete CAN frame\n");
                            return 1;
                        }
                    }

                    for (cmsg = CMSG_FIRSTHDR(&msg);
                        cmsg && (cmsg->cmsg_level == SOL_SOCKET);
                        cmsg = CMSG_NXTHDR(&msg,cmsg)) {
                        if (cmsg->cmsg_type == SO_TIMESTAMP) {
                            memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
                        } else if (cmsg->cmsg_type == SO_TIMESTAMPING) {

                            struct timespec *stamp = (struct timespec *)CMSG_DATA(cmsg);

                            /*
                            * stamp[0] is the software timestamp
                            * stamp[1] is deprecated
                            * stamp[2] is the raw hardware timestamp
                            * See chapter 2.1.2 Receive timestamps in
                            * linux/Documentation/networking/timestamping.txt
                            */
                            tv.tv_sec = stamp[2].tv_sec;
                            tv.tv_usec = stamp[2].tv_nsec/1000;
                        } else if (cmsg->cmsg_type == SO_RXQ_OVFL)
                            memcpy(&dropcnt[i], CMSG_DATA(cmsg), sizeof(__u32));
                    }

                    /* check for (unlikely) dropped frames on this specific socket */
                    if (dropcnt[i] != last_dropcnt[i]) {

                        __u32 frames = dropcnt[i] - last_dropcnt[i];

                        if (silent != SILENT_ON)
                            printf("DROPCOUNT: dropped %d CAN frame%s on '%s' socket (total drops %d)\n",
                                frames, (frames > 1)?"s":"", devname[idx], dropcnt[i]);

                        if (log)
                            fprintf(logfile, "DROPCOUNT: dropped %d CAN frame%s on '%s' socket (total drops %d)\n",
                                frames, (frames > 1)?"s":"", devname[idx], dropcnt[i]);

                        last_dropcnt[i] = dropcnt[i];
                    }

                    /* once we detected a EFF frame indent SFF frames accordingly */
                    if (frame.can_id & CAN_EFF_FLAG)
                        view |= CANLIB_VIEW_INDENT_SFF;

                    if (log) {                                                  /*   CODE GETS IN TO THIS PART  */
                        char buf[CL_CFSZ]; /* max length */                     /*   WHEN PRINTING INTO FILE    */
                                                                                /*                              */
                        /* log CAN frame with absolute timestamp & device */    /*                              */
                        sprint_canframe(buf, &frame, 0, maxdlen);               /*                              */
                        fprintf(logfile, "%s %*s %s\n",                         /*                              */
                            curr_read,                                          /*                              */
                            max_devname_len, devname[idx], buf);                /*                              */
                    }                                                           /*                              */

                    if (logfrmt) {
                        char buf[CL_CFSZ]; /* max length */

                        /* print CAN frame in log file style to stdout */
                        sprint_canframe(buf, &frame, 0, maxdlen);
                        printf("(%010ld.%06ld) %*s %s\n",
                            tv.tv_sec, tv.tv_usec,
                            max_devname_len, devname[idx], buf);
                        goto out_fflush; /* no other output to stdout */
                    }

                    if (silent != SILENT_OFF){
                        if (silent == SILENT_ANI) {
                            printf("%c\b", anichar[silentani%=MAXANI]);
                            silentani++;
                        }
                        goto out_fflush; /* no other output to stdout */
                    }

                    printf(" %s", (color>2)?col_on[idx%MAXCOL]:"");

                    switch (timestamp) {

                    case 'a': /* absolute with timestamp */
                        printf("(%010ld.%06ld) ", tv.tv_sec, tv.tv_usec);
                        break;

                    case 'A': /* absolute with date */
                    {
                        struct tm tm;
                        char timestring[25];

                        tm = *localtime(&tv.tv_sec);
                        strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", &tm);
                        printf("(%s.%06ld) ", timestring, tv.tv_usec);
                    }
                    break;

                    case 'd': /* delta */
                    case 'z': /* starting with zero */
                    {
                        struct timeval diff;

                        if (last_tv.tv_sec == 0)   /* first init */
                            last_tv = tv;
                        diff.tv_sec  = tv.tv_sec  - last_tv.tv_sec;
                        diff.tv_usec = tv.tv_usec - last_tv.tv_usec;
                        if (diff.tv_usec < 0)
                            diff.tv_sec--, diff.tv_usec += 1000000;
                        if (diff.tv_sec < 0)
                            diff.tv_sec = diff.tv_usec = 0;
                        printf("(%03ld.%06ld) ", diff.tv_sec, diff.tv_usec);

                        if (timestamp == 'd')
                            last_tv = tv; /* update for delta calculation */
                    }
                    break;

                    default: /* no timestamp output */
                        break;
                    }

                    printf(" %s", (color && (color<3))?col_on[idx%MAXCOL]:"");
                    printf("%*s", max_devname_len, devname[idx]);

                    if (extra_msg_info) {

                        if (msg.msg_flags & MSG_DONTROUTE)
                            printf ("  TX %s", extra_m_info[frame.flags & 3]);
                        else
                            printf ("  RX %s", extra_m_info[frame.flags & 3]);
                    }

                    printf("%s  ", (color==1)?col_off:"");

                    fprint_long_canframe(stdout, &frame, NULL, view, maxdlen);

                    printf("%s", (color>1)?col_off:"");
                    printf("\n");
                }

            out_fflush:
                fflush(stdout);
            }
            countc = countc +1;
        }   
    }


    for (i=0; i<currmax; i++)
        close(s[i]);

    if (bridge)
        close(bridge);

    if (log)
        fclose(logfile);

    return 0;
}

Actually everything matters works in while(running) block. 实际上,所有重要的事情都在while(running)块中起作用。 Inside this block when I make the bytes_read = read(fd,&read_buffer,42); 当我使bytes_read = read(fd,&read_buffer,42);时在此块内 as comment, it didn't write anything but also doesn't give the Segmentation fault error. 作为评论,它什么也没写,但也没有给出细分错误错误。 Same also happens when I connect the GPS' TX pin in to BBB. 当我将GPS的TX引脚连接到BBB时,也会发生同样的情况。 So the problem starts to occur when the data is coming from the GPS and read by the BBB. 因此,当数据来自GPS并由BBB读取时,就会开始出现问题。

Segmentation Fault Err 分段错误错误

What should I do about it? 我该怎么办?

Thanks. 谢谢。

Your GPS reading code 您的GPS读取代码

char new_read[38];
char curr_read[33];

strcpy(curr_read, new_read);

is copying a 38 char buffer into a 33 char buffer, which can result in bad things. 将38个char缓冲区复制到33个char缓冲区中,这可能会导致不良后果。

Strcpy will copy the contents of the source buffer into the destination buffer until it reads NULL from the source buffer. Strcpy会将源缓冲区的内容复制到目标缓冲区,直到它从源缓冲区读取NULL。 If the NULL char is at the 36th position in new_read, strcpy will be writing in random memory which can cause the segmentation fault. 如果NULL字符位于new_read的第36位,则strcpy将在随机存储器中写入,这可能会导致分段错误。

I am guessing that when you run your GPS reading code as stand-alone, the writing into random memory goes un-noticed, but when you combine it with the CAN bus reading, it writes into allocated space and the error happens. 我猜想,当您以独立方式运行GPS读取代码时,写入随机存储器的操作不会引起注意,但是当将其与CAN总线读取结合使用时,它将写入分配的空间,并且会发生错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM