串行端口写入缓冲区的用途是什么?

发布于 2024-11-02 02:59:30 字数 294 浏览 0 评论 0原文

从外部 SerialPort 对象来看,写入缓冲区的大小以及是否已满似乎没有什么区别。

使用同步写入,write 方法会阻塞,直到所有数据都已发送且缓冲区为空。

使用异步写入,数据排队,程序继续运行。直到写操作完成且数据出缓冲区时才会调用回调方法。

无论缓冲区中有多少数据以及缓冲区是否已满,串行端口对象的行为似乎都是相同的。当写入缓冲区已满时似乎不会发生错误。

那么,为什么要检查 BytesToWrite 和 WriteBufferSize 呢?当写入缓冲区已满时,SerialPort 的行为是否有不同?

From outside SerialPort object, it seems to make no difference what the size of the write buffer is, and whether or not it is full.

Using synchronous writing, the write method blocks until all the data has been sent and the buffer is empty.

Using async writing, the data is queued and the program continues on going. The callback method is not called until the write operation is completed and the data is out of the buffer.

The behavior of the serialport object seems to be the same regardless of how much data is in the buffer and whether or not the buffer is full. No errors seem to happen when the write buffer is full.

So, why be able to check BytesToWrite and WriteBufferSize at all? Is there any way that SerialPort behaves differently when the write buffer is full?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兔姬 2024-11-09 02:59:30

缓冲区是一种机制,旨在允许处理缓冲区的任何人在自己的时间以自己的方式进行操作。
当我发送数据时,我希望它以端口的最大速率推送,但我不想在端口上忙等待并等待每个字节发送完毕,然后再推送下一个字节。因此,您有一个为硬件提供数据的处理缓冲区,并且可以按块传递。

至于为什么你想要检查 BytesToWrite - 你通常有兴趣知道在继续你想做的下一件事情之前是否发送了所有数据,你可能期望在给定的时间段后得到响应,你可能想知道实际的传输速率是多少等等。

Buffers are a mechanism designed to allow whoever processes the buffer to do it in their own way, at their own time.
When i send data, i want it to be pushed at the maximal rate of the port, but i don't want to busywait on the port and wait for each byte to be sent before i push the next one. So you have a processing buffer that feeds the hardware, and can be passed in chunks.

As for the why you'd want to check the BytesToWrite - you are often interested to know if all your data was sent before moving on to the next thing you want to do, you might expect a response after a given period of time, you might want to know what the actual transfer rate is etc'.

花之痕靓丽 2024-11-09 02:59:30

C# SerialPort.BytesToWrite 属性对应于非托管 Win32 COMSTAT.cbOutQue 字段,该字段描述为:

  • 所有写入操作中剩余要传输的用户数据字节数。对于非重叠写入,该值为零。

这似乎表明您可以观察到写入缓冲区在调用写入完成回调之前通过异步写入发送时被消耗。

The C# SerialPort.BytesToWrite property corresponds to the unmanaged Win32 COMSTAT.cbOutQue field which is described as:

  • The number of bytes of user data remaining to be transmitted for all write operations. This value will be zero for a nonoverlapped write.

This seems to suggest you could observe the write buffer being consumed as it is sent with async writing before the write complete callback is called.

诠释孤独 2024-11-09 02:59:30

我想创建一个测试实用程序,不断地从串行端口发送 0xAA,没有间隙,永远。我不关心RX。

我使用计时器来保持缓冲区已满,并监视 BytesToWrite 以等待其低于阈值,然后再将更多数据写入缓冲区。

我也可以不使用计时器,而是刷新 AsyncCallback 中的串行端口,但我想这样做是为了好玩。您可以查看 label11 以查看缓冲区填充和清空。

请注意,您可以在短时间内使用 BeginWrite 而不用 EndWrite,但最终您将耗尽资源。我基本上只是放入一个虚拟的 EndWrite。

    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        timerFill.Enabled = checkBox2.Checked;
    }

    private void timerFill_Tick(object sender, EventArgs e)
    {
        GenerateSquareWave();
    }

    int const bufferSize = 256;

    void GenerateSquareWave()
    {
        int k = serialPort1.BytesToWrite;
        label11.Text = k.ToString();
        if (k < bufferSize)
        {
            byte[] data = new byte[bufferSize];
            for (int i = 0; i < bufferSize; i++)
            {
                data[i] = 0xAA;
            }
            serialPort1.BaseStream.BeginWrite(data, 0, data.Length, new AsyncCallback((IAsyncResult ar) => serialPort1.BaseStream.EndWrite(ar)), null);
        }
    }

I wanted to create a test utility that constantly sends out 0xAA out the serial port, with no gaps, forever. I don't care about RX.

I used a timer to keep the buffer full, and monitored BytesToWrite to wait below it was below threshold, before I wrote more data into the buffer.

I could have alternatively not used a timer, but refreshed the serial port in the AsyncCallback, but I wanted to do it this way for fun. You can view the label11 to see the buffer fill and empty.

Note you can get away with BeginWrite without EndWrite for a short time, but eventually you will run out resources. I am basically just putting in a dummy EndWrite.

    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        timerFill.Enabled = checkBox2.Checked;
    }

    private void timerFill_Tick(object sender, EventArgs e)
    {
        GenerateSquareWave();
    }

    int const bufferSize = 256;

    void GenerateSquareWave()
    {
        int k = serialPort1.BytesToWrite;
        label11.Text = k.ToString();
        if (k < bufferSize)
        {
            byte[] data = new byte[bufferSize];
            for (int i = 0; i < bufferSize; i++)
            {
                data[i] = 0xAA;
            }
            serialPort1.BaseStream.BeginWrite(data, 0, data.Length, new AsyncCallback((IAsyncResult ar) => serialPort1.BaseStream.EndWrite(ar)), null);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文