我遇到了BeagleboneBlack Uart的大麻烦

时间:2016-12-26 07:17:18

标签: c embedded-linux beagleboneblack uart

我的beagleboneblack(让我们称之为" BBB")运行3.8.13-bone47,我被一个错误困扰了2周。

我的问题是:当我的BBB获得一个字符串时,我的BBB会将相同的字符串发送到另一个终端。

例如:我的带有Uart2USB桥接器的笔记本电脑发送了一个字符串" asd"然后BBB将得到" asd"但同时,BBB将发送" asd&#34 ;到我的笔记本电脑.BBB上的所有Uart模块(Uart1,Uart2,Uart4)都做了同样的事情。

顺便说一句,我试图通过使用两个Uart(一个用于TX,另一个用于RX)来避免这个错误。幸运的是,我做到了,但我仍然想知道原因和解决方案。

这是我的Uart.c,Uart.h和test.c:

/*====================Uart.c================*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#include "Uart.h"

#define TRUE 1
#define FALSE -1

int fd_uart;

void set_speed(void)
{
        int i;
        int status;
        int speed_arr = B38400;

        struct termios Opt;
        tcgetattr(fd_uart,&Opt);

        tcflush(fd_uart, TCIOFLUSH);

        cfsetispeed(&Opt, speed_arr);
        cfsetospeed(&Opt, speed_arr);

        status = tcsetattr(fd_uart, TCSANOW, &Opt);

        if(status != 0)
                perror("tcsetattr fd1");
}

int set_Parity(void)
{
        struct termios options;
        if( tcgetattr( fd_uart,&options)!= 0)
        {
            perror("SetupSerial 1");
            return(FALSE);
        }

        options.c_cflag &= ~CSIZE;

        options.c_cflag |= CS8;

        options.c_cflag &= ~PARENB;    /* Clear parity enable */
        options.c_iflag &= ~INPCK;     /* Enable parity checking */
        options.c_iflag &= ~(ICRNL|IGNCR);
        options.c_lflag &= ~(ICANON );

        options.c_cflag &= ~CSTOPB;

        options.c_iflag |= INPCK;

        options.c_cc[VTIME] = 150; // 15 seconds
        options.c_cc[VMIN] = 0;

        tcflush(fd_uart,TCIFLUSH); /* Update the options and do it NOW */

        if(tcsetattr(fd_uart,TCSANOW,&options) != 0)
        {
                perror("SetupSerial 3");
                return (FALSE);
        }
        return (TRUE);
}

void initUart(int argc, char **argv)
{
        char devname_head[10] = "/dev/";
        char dev_name[20];

        if(argc < 2)
        {
                printf("Please input './test_uart ttyOx'\n");
                exit(1);
        } else {

                strcpy(dev_name, devname_head);
                strcat(dev_name, argv[1]);

                fd_uart = open(dev_name, O_RDWR);
                if(fd_uart < 0)
                {
                        perror("error to open /dev/ttyOx\n");
                        exit(1);
                } else if (fd_uart == 0) {
                        printf("Can't Open Serial Port!\n");
                        exit(0);
                } else {
                        //Setup
                        set_speed();                   //baud:38400
                        if (set_Parity() == FALSE)      //8,1,n
                        {
                                printf("Set Parity Error\n");
                                exit(1);
                        }
                }
        }
}

void writeUartString(char *buf)
{
        if ( write(fd_uart,buf,strlen(buf)) < 0)
        {
                printf("write error\n");
        }
}

void writeUartMsg(char *buf,int num)
{
        if ( write(fd_uart,buf,num) < 0)
        {
                printf("write error\n");
        }
}

int readUart(char *buf)
{
        int num = 0, i = 0;
        num = read(fd_uart,buf,sizeof(buf));
        if(num < 0){
                printf("read error\n");
        }
        return num;
}

void closeUart(void)
{
        close(fd_uart);
}
/*======================================================*/

/*==================Uart.h===================*/
#ifndef UART_H
#define UART_H

void set_speed(void);
int set_Parity(void);
void initUart(int argc, char **argv);
void writeUartString(char *buf);
void writeUartMsg(char *buf,int num);
void closeUart(void);

extern int fd_uart;

#endif
/*=======================================*/

/*================test.c=================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Uart.h"

int main(int argc, char **argv)
{
        int i = 0,temp = 0;
        char buf[64] = {0};
        initUart(argc,argv);
        while(1){
                writeUartString("waiting\n");
                printf("waiting\n");
                memset(buf,0,64);
                temp = readUart(buf);
                printf("readUart's return value = %d\n",temp);
                if (temp > 0){
                        printf("get something\n");
                        printf("%s\n",buf);
                }
                sleep(1);
        }
        return 0;
}
/*====================================*/

有人也得到了这种情况吗?

1 个答案:

答案 0 :(得分:0)

您使用

启用了回显功能
options.c_lflag &= ~(ICANON );

至少将其更改为

options.c_lflag &= ~(ICANON | ECHO );

当你将原始状态保留为所有标志,而不是ICANON