简体   繁体   English

在c ++和Linux中使用超时写入和读取串行端口

[英]writing and reading to/from a serial port with a timeout in c++ and Linux

I'm trying to send some hex string to a serial port, and directly read its answer in c++. 我正在尝试将一些十六进制字符串发送到串行端口,并直接在c ++中读取它的答案。 If there is no answer it should timeout after a given period of time. 如果没有答案,它应该在给定的一段时间后超时。

  • What is the simplest implementation of such a task? 这项任务最简单的实现是什么?
  • Do i need to use stuff like boost? 我需要使用像boost这样的东西吗?

To be clear: I'm searching for the most simple way to achieve this. 要明确:我正在寻找实现这一目标的最简单方法。

Sorry if my question is dumb, but im new to this topic, thanks in advance! 对不起,如果我的问题是愚蠢的,但我是这个话题的新手,请提前感谢!

EDIT: Sorry that I forgot to mention, it should run on Linux. 编辑:对不起,我忘了提,它应该在Linux上运行。

this should be similar to your declaration: 这应该类似于你的声明:

Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);

Setup(CSerial::EBaudrate(9600),
      CSerial::EDataBits(8),
      CSerial::EParity(NOPARITY),
      CSerial::EStopBits(ONESTOPBIT));

Reading data: 阅读数据:

// Read data, until there is nothing left
    DWORD dwBytesRead = 0;
    BYTE  abBuffer[100];
    do
    {
        // Read data from the COM-port
        serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
        if (dwBytesRead > 0)
        {
            // TODO: Process the data
        }
    }
    while (dwBytesRead == sizeof(abBuffer));

More details can be found here on code project: http://www.codeproject.com/Articles/992/Serial-library-for-C 更多细节可以在代码项目中找到: http//www.codeproject.com/Articles/992/Serial-library-for-C

Please note: I am used to programming serial ports in c#, and so (to the best of my knowledge) believe this would work for you. 请注意:我习惯用c#编写串口,所以(据我所知)相信这对你有用。 (I would also like to point outall serial port communication is send actually through as hex, but may be read via the buffer as a decimal value ( please refer to http://www.asciitable.com/ for converstion, or use something similar to UTF8 encoding) (我还想指出所有串口通信实际上是以十六进制形式发送的,但可以通过缓冲区读取十进制值(请参考http://www.asciitable.com/进行转换,或者使用类似的东西)到UTF8编码)

EDIT - As per comment; 编辑 - 根据评论;

Please refer to : http://msdn.microsoft.com/en-gb/library/windows/hardware/hh439614(v=vs.85).aspx for details on serial port read/write timeouts 有关串行端口读/写超时的详细信息,请参阅: http//msdn.microsoft.com/en-gb/library/windows/hardware/hh439614(v = vs.85).aspx

Write timeout will be similar to; 写超时将类似于;

[BrowsableAttribute(true)]
public:
property int WriteTimeout {
    int get ();
    void set (int value);
}

Which allows you to get or set the timeout attribute 这允许您获取或设置超时属性

Full Program 完整计划

public:
    static void Main()
    {
        String^ name;
        String^ message;
        StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
        Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read));

        // Create a new SerialPort object with default settings.
        _serialPort = gcnew SerialPort();

        // Allow the user to set the appropriate properties.
        _serialPort->PortName = SetPortName(_serialPort->PortName);
        _serialPort->BaudRate = SetPortBaudRate(_serialPort->BaudRate);
        _serialPort->Parity = SetPortParity(_serialPort->Parity);
        _serialPort->DataBits = SetPortDataBits(_serialPort->DataBits);
        _serialPort->StopBits = SetPortStopBits(_serialPort->StopBits);
        _serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);

        // Set the read/write timeouts
        _serialPort->ReadTimeout = 500;
        _serialPort->WriteTimeout = 500;

        _serialPort->Open();
        _continue = true;
        readThread->Start();

        Console::Write("Name: ");
        name = Console::ReadLine();

        Console::WriteLine("Type QUIT to exit");

        while (_continue)
        {
            message = Console::ReadLine();

            if (stringComparer->Equals("quit", message))
            {
                _continue = false;
            }
            else
            {
                _serialPort->WriteLine(
                    String::Format("<{0}>: {1}", name, message) );
            }
        }

        readThread->Join();
        _serialPort->Close();
    }

    static void Read()
    {
        while (_continue)
        {
            try
            {
                String^ message = _serialPort->ReadLine();
                Console::WriteLine(message);
            }
            catch (TimeoutException ^) { }
        }
    }

EDIT 2 编辑2

Please refer to Linux Serial Port: Blocking Read with Timeout where this has been declared in the question and some of the answers may prove useful to you as well! 请参阅Linux Serial Port:Blocking Read with Timeout ,其中已在问题中声明了这一点,并且一些答案也可能对您有用! :) :)

I recently came for the same issue and I found a good solution using select() Read the documentation here: manpages.courirer-mta.org/htmlman2/select2.html 我最近遇到了同样的问题,我找到了一个很好的解决方案,使用select()阅读这里的文档:manpages.courirer-mta.org/htmlman2/select2.html

In your case you need to setup the timeout, which is the 5th argument of select: 在你的情况下,你需要设置超时,这是选择的第五个参数:

    struct timeval timeout;

    timeout.tv_sec = 0 ; // seconds

    timeout.tv_usec = 1000 ; // microseconds

Hope this helps. 希望这可以帮助。

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

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