Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C函数赢得';在串行端口关闭之前,不要发送_C_Linux_Serial Port_Posix_Beagleboneblack - Fatal编程技术网

C函数赢得';在串行端口关闭之前,不要发送

C函数赢得';在串行端口关闭之前,不要发送,c,linux,serial-port,posix,beagleboneblack,C,Linux,Serial Port,Posix,Beagleboneblack,(2014年2月1日编辑-针对此问题的成对代码。使用较小的代码进行测试。编辑此姿势以显示仍然存在相同问题的整个新代码。) 我正在使用POSIX串行指南编写Angstrom Linux分发内核3.8中的beagle bone black 我有一组函数来处理serial.c中定义的串行通信。我想将这些函数用作其他程序使用的库。 在函数定义之前,我将这些函数的许多公共变量声明为serial.c顶部的静态变量。我这样做的目的是,这些变量将类似于全局变量,但只适用于serial.c中的函数,并且它们将在函

(2014年2月1日编辑-针对此问题的成对代码。使用较小的代码进行测试。编辑此姿势以显示仍然存在相同问题的整个新代码。)

我正在使用POSIX串行指南编写Angstrom Linux分发内核3.8中的beagle bone black

我有一组函数来处理serial.c中定义的串行通信。我想将这些函数用作其他程序使用的库。 在函数定义之前,我将这些函数的许多公共变量声明为serial.c顶部的静态变量。我这样做的目的是,这些变量将类似于全局变量,但只适用于serial.c中的函数,并且它们将在函数调用之间保持其值。这看起来确实像是我想要的那样

函数之一是send_serial()。它只做它所说的,将数据发送到串行端口。 如果我在serial.c中编写一个main()函数,然后从定义的同一个文件中调用它,那么send_serial()将按预期工作。一旦程序使用send_serial()点击该行,数据将立即写入串行端口。我可以看到发送和接收指示灯闪烁,我得到了预期的数据

但是,当我尝试从另一个文件使用send_serial()时,它的行为异常。它执行ok并返回正确的写入字节数,程序继续下一行,除非根本没有实际的串行端口通信。直到程序结束或我在串行端口上调用close,数据才真正在串行端口上发送

为什么它在同一个文件中可以正常工作,但在不同的文件中却不能正常工作。在这两种情况下,我使用完全相同的函数来设置和打开串行端口

连载

#ifndef _PUP_SERIAL_   /* Include guard */
#define _PUP_SERIAL_ 

#define MAXBUF      1024

typedef struct byte_array {
    unsigned char byte[MAXBUF];
    int count;
} byte_array;

void set_serial_debug(int debug_value);
void close_serial();
int setup_serial_port(char * port_name);
int send_serial(byte_array message);
byte_array read_serial(); 
byte_array test_message();

#endif
连载

//#define _SERIAL_IS_MAIN_ // comment out this line for this file to be a library instead of main function

#include <stdio.h>   /* Standard input/output definitions */
#include <fcntl.h>   /* File control definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <sys/time.h>
#include "serial.h"


static int            debug;
static int            fd;
static struct termios options;


void print_bytes_as_hex(char * str, byte_array message)
{
    int n;
    int i;
    printf(str);
    if (message.count > 0)
        for (i = 0; i < message.count; i++)
        {
            n = (int) message.byte[i];
            printf("0x%.2x ", n);
        }
    else
        printf("-x--");
    printf("\n");
} // end of print bytes as hex


int setup_serial_port(char * port_name)
{
    fd = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY);
    printf("Opened up port %s as number %d",port_name,fd);
    tcgetattr(fd, &options);

    if (port_name == "/dev/ttyUSB0")<--Fixed by changing to: if (strcmp(port_name,"/dev/ttyUSB0")==0)
        options.c_cflag &= ~CRTSCTS;  // set NO RTS control for USB
    else
        options.c_cflag |= CRTSCTS;  // set RTS control for ttyO#

    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);

    // set No parity (8N1):
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    options.c_iflag |= IGNBRK;
    options.c_iflag &= ~(IXON | IXOFF | IXANY); // No software handshake

    options.c_lflag = 0;
    options.c_oflag = 0;

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Raw Input
    //options.c_lflag |= (ICANON | ECHO | ECHOE); // Canonical input

    options.c_cc[VMIN] = 1; // 1 means read dos not block
    options.c_cc[VTIME] = 1; // 1 means 0.1 seconds read timeout

    options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode

    /* Make raw */
    cfmakeraw(&options);

    /* Flush Port, then applies attributes */
    tcflush( fd, TCIFLUSH );
    fcntl(fd, F_SETFL, 0);
    tcsetattr(fd, TCSANOW, &options); // Set the new options for the port
    if (fd == -1)
    { //Could not open the port.
        perror("open_port: Unable to open");
        printf("Could not open port %s\n",port_name);
    }
    else // port is open
        printf("Port %s is open as # %d\n",port_name, fd);

    return fd;
} // End of setup_serial_port

void set_serial_debug(int debug_value)
{
    debug = debug_value;   
}

void close_serial()
{
    close(fd);
}

int send_serial(byte_array message)
{
    int n;
    printf("about to send to serial port...\n");
    n = write(fd, message.byte, message.count);
    printf("sent %d bytes to serial port %d\n",n,fd);
    return n;
}

byte_array read_serial()
{
    static byte_array message;
    int n;
    int i;

    printf("Attempting to read from serial port %d...\n",fd);
    for (i = 0; i < 8; i++)
        n = read(fd, &message.byte[i], 1);
    message.count = i;
    printf("read %d bytes from the serial port %d\n",message.count,fd);
    return message;
}

byte_array test_message()
{
    int i;
    unsigned char st[] = {0x02, 0x10, 0x27, 0x0D, 0x02, 0x01, 0xFB, 0x43, 0x56, 0x00, 0x00, 0x00, 0x00, 0xDC};
    byte_array return_message;

    for (i = 0; i < 14; i++)
        return_message.byte[i] = st[i];
    return_message.count = 14;
    return return_message;
}

#ifdef _SERIAL_IS_MAIN_
int main(int Count, char *Strings[])
{
    setup_serial_port("/dev/ttyUSB0");

    byte_array out_message = test_message();
    byte_array in_message;

    print_bytes_as_hex("sending: ",out_message);
    send_serial(out_message);
    in_message = read_serial();
    print_bytes_as_hex("recieved: ",in_message);

}
#endif
/#define _SERIAL _IS _MAIN //注释掉这一行,使该文件成为库而不是主函数
#包括/*标准输入/输出定义*/
#包含/*文件控制定义*/
#包括/*POSIX终端控制定义*/
#包括
#包括“serial.h”
静态int调试;
静态int-fd;
静态结构termios选项;
无效打印字节为十六进制(字符*str,字节数组消息)
{
int n;
int i;
printf(str);
如果(message.count>0)
对于(i=0;i如果(端口名称=“/dev/ttyUSB0”)我终于找到了问题所在。Chux是正确的。作为独立程序串行运行。c没有使用RTS控件。c作为main.c的一部分运行。它使用RTS控件。因为我将它连接到USB端口,所以它不应该使用RTS。造成混淆的原因是
设置_串行_端口(char*端口名称)

其中port_name是char*。我不确定为什么在serial.c中它会工作(返回true),但在main.c中它返回false。当我将其更改为:

if (strcmp(port_name,"/dev/ttyUSB0")==0)
该程序在这两种情况下都能正常工作


有人能解释一下为什么
if(port_name==“/dev/ttyUSB0”)
在serial.c中返回true吗?(端口名是
/dev/ttyUSB0
,但在调查这个问题之后,我发现您无法将字符串与
=
进行比较。那么,为什么在一种情况下返回true,而在另一种情况下返回true?

怀疑在serial.c之外使用了不同的缓冲/握手。这里缺少太多内容,无法说明发生了什么-包括serial端口打开和配置,来自另一个文件的调用,以及为在另一个文件中获得这些函数的原型和声明所做的任何操作。在这两种情况下,您是否编写完全相同的数据?在每种情况下,strace的输出是什么样子的?我在这两种情况下使用相同的串行端口设置例程。I“我已经减少了代码,这样我就可以把它缩小到这个问题,然后我在这里发布了整个代码。有时C编译器会在一个“.C”中两次或多次提到完全相同的文本字符串。”文件中,只在RAM中存储一次,这样所有指向这些字符串的指针最终都指向同一地址。几乎所有C编译器,当两个不同的“.C”文件中提到完全相同的文本字符串时,将该字符串在RAM中存储两次,这样指向这些字符串的指针最终指向不同的地址。有关详细信息,请参阅。
# gcc -o serial serial.c
# ./serial      
Opened up port /dev/ttyUSB0 as number 3Port /dev/ttyUSB0 is open as # 3
sending: 0x02 0x10 0x27 0x0d 0x02 0x01 0xfb 0x43 0x56 0x00 0x00 0x00 0x00 0xdc 
about to send to serial port... 
sent 14 bytes to serial port 3  <-- Send and Receive Lights blink
Attempting to read from serial port 3...
read 8 bytes from the serial port 3
recieved: 0x02 0x10 0x27 0x07 0x81 0x02 0x0e 0xbc
(edit serial.c to comment out //#define _SERIAL_IS_MAIN_)
# gcc -o main main.c serial.c
# ./main
Opened up port /dev/ttyUSB0 as number 3Port /dev/ttyUSB0 is open as # 3
sending: 0x02 0x10 0x27 0x0d 0x02 0x01 0xfb 0x43 0x56 0x00 0x00 0x00 0x00 0xdc 
about to send to serial port...          
sent 14 bytes to serial port 3           <-- comm lights do not blink at all
Attempting to read from serial port 3... <-- Program waits here for ever until CTRL^C
^C                                       <-- Once I press CTRL^C snd and rec comm lights blink
if (port_name == "/dev/ttyUSB0")
if (strcmp(port_name,"/dev/ttyUSB0")==0)