0

显然是 Linux 串行编程的新手。

如果我使用 minicom 或 termie 的 /dev/ttyS4,我可以通过零调制解调器电缆与另一台 PC 通信。使用此处的代码,当我运行程序时,我没有收到来自远程 pc 的字符,而是看到来自本地键盘的输入。我猜这是一个简单的配置错误,但我没有看到。

见解赞赏!

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */



//const char NAK = 0x15;
char THE_PORT[] =  "/dev/ttyS4";
unsigned char m_messagebuf[255] ;

int main()
{
    int retval, fd, bwritten;   
    unsigned char m_recbuf[4];
    unsigned char m_sendbuf[73] ;       
    unsigned char haltchar = 0x1d;
    unsigned char c;
    char* p = 0;

    m_sendbuf[0] =  0x15;

    strcpy(m_messagebuf, "testing ");
    strcat(m_messagebuf, THE_PORT);
    printf("%s\n", m_messagebuf);
    sleep(1);

    //return(0);
    if (fd = open_port() < 0)
    {
        printf("oops...\n");
        return(0);
    }

    printf( "opened %s\n", THE_PORT);
    sleep(1);

    if (ConfigurePort(fd) < 0)
    {
        printf("oops...\n");
        return 0;
    }
    printf("configured %s\n", THE_PORT);
    sleep(1);

    while( 1)
    {
        printf("waiting for %s\n", THE_PORT);
        if ((retval = read(fd, &c, 1)) > 0)
        {
            printf("read %d from port : \n", retval);
            //m_recbuf[retval] = '0';
            printf("%c\n", c);

        }
        else
        {
            printf("Read 0 or  -1 from port (%d)\n", retval);
        }
        sleep(1);

        //bwritten = write(fd, (void *)&m_sendbuf, 1);
        //printf("wrote %d to port\n", bwritten);
    }       
    printf("Done.\n");
    close(fd);
    return 0;   

}


int ConfigurePort(int fd)
{   
    struct termios options;

    if ( tcgetattr(fd, &options) < 0)
    {

        perror(strcat("config_port: Unable to get attribs for ", THE_PORT));
        return -1;      
    }
    if (memset(&options, 0, sizeof(options)) < 0)
    {
        sprintf(m_messagebuf, "config_port: Unable to clear settings %s\n", THE_PORT);
        perror(m_messagebuf);
        return -1;
    }

    // 9600
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    // N81
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    // flow control OFF
    //options.c_cflag &= ~CNEW_RTSCTS;    
    // enable resd, keep owner
    options.c_cflag |= (CLOCAL | CREAD);

    // local options for raw input    
   options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    // raw output
    options.c_oflag &= ~OPOST;

    // raw input    
    options.c_iflag = INPCK | ISTRIP | IGNCR | IGNBRK;
    options.c_iflag &=  ~(IXON | IXOFF | IXANY);

    options.c_cc[VINTR]    = 0;     /* Ctrl-c */ 
    options.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
    options.c_cc[VERASE]   = 0;     /* del */
    options.c_cc[VKILL]    = 0;     /* @ */
    options.c_cc[VEOF]     = 0;     /* Ctrl-d */
    options.c_cc[VSWTC]    = 0;     /* '\0' */
    options.c_cc[VSTART]   = 0;     /* Ctrl-q */ 
    options.c_cc[VSTOP]    = 0;     /* Ctrl-s */
    options.c_cc[VSUSP]    = 0;     /* Ctrl-z */
    options.c_cc[VEOL]     = 0;     /* '\0' */
    options.c_cc[VREPRINT] = 0;     /* Ctrl-r */
    options.c_cc[VDISCARD] = 0;     /* Ctrl-u */
    options.c_cc[VWERASE]  = 0;     /* Ctrl-w */
    options.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
    options.c_cc[VEOL2]    = 0;     /* '\0' */

    options.c_cc[VMIN] = 1;     /* blocking read until 1 character arrives */
    options.c_cc[VTIME] = 0;        /* inter-character timer unused */

    //Set the new options for the port...      
    if (tcsetattr(fd, TCSAFLUSH, &options) < 0)
    {
        sprintf(m_messagebuf, "config_port: Unable to configure %s\n", THE_PORT);
        perror(m_messagebuf);
        return -1;
    }       
}

/*
 * Returns the file descriptor on success or -1 on error.
 */
int open_port(void)
{
      int fd; /* File descriptor for the port */

      fd = open(THE_PORT, O_RDWR | O_NOCTTY  | O_NDELAY | O_NONBLOCK); 
      if (fd == -1)
      {
            sprintf(m_messagebuf, "open_port: Unable to open %s\n", THE_PORT);
            perror(m_messagebuf);
            return -1;
      }       
     return (fd);
}
4

1 回答 1

2
if (fd = open_port() < 0)

相当于

if (fd = (open_port() < 0))

and<运算符返回0or 1,这不是您想要的文件描述符。

你可能想做:

if ((fd = open_port()) < 0)

反而。

另一个问题:您的函数ConfigurePort末尾没有默认返回值(最终})。没有返回值意味着它返回一个不确定的值,读取这个值是未定义的行为。

于 2012-08-20T18:13:42.133 回答