当前位置: 首页 > news >正文

windows 驱动实例分析系列-COM驱动的I/O处理

在文章 COM驱动讲解 中,我们讲解了virtualSerial驱动几乎所有代码,但是唯独没有讲解I/O操作,这是因为I/O操作往往关乎驱动的功能,由于那个驱动仅仅作为案例,故我们不打算在上面讲解太多,但实际开发中,serial一般都具有实际的功能,故大部分情况下我们都需要改造之前的umdfserial驱动,让它实际具有一定的功能。

在umdfserial中,写入数据是正确的,但是怎么读取数据是一个问题,实际上作为最经常使用的接口,serial的经典应用是它会源源不断主动上报数据,这个数据往往是调试信息、日志输出、传感器信息等。

所以我们先研究用户层是如何读取数据的,驱动层又是如何上报数据的。

数据上报方式

在windows api中,可以使用ReadFile、ReadFileEx、DeviceIoControl这样的消息来完成从串口读取数据的操作,但这需要解决的问题就是我们如何知道什么时候需要读取数据。

初学者最容易想到的就是使用一个线程持续的读取数据,代码看起来像下面一样:

...ret = ReadFile(hFile,lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead,lpOverlapped);
...

注意,无论使用同步或者异步,结果都没什么变化,尤其是对于我们的 umdfserial 代码来说。

更机智的做法是深入了解UART的硬件机制,serial本身存在流控的说法,就是当数据到达的时候,它有某种方案通知上层,就是RTS和CTS信号,当然,对于我们来说,我们并没有实际上的信号线,但上层不知道这一点,所以我们只需要装作有RTS和CTS信号的样子就可以了。

不过在那之前,我们先来看一般的串口程序会怎么做,一般的串口读写工具(sscom之类的)往往会使用WaitCommEvent和ClearCommError函数,下面是代码:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>int main()
{HANDLE hCom;BOOL fSuccess;DWORD dwEvtMask;DWORD dwError;COMSTAT ComState = { 0 };CHAR    buffer[256] = { 0 };hCom = CreateFile(COM_NAME,GENERIC_READ | GENERIC_WRITE,0,    // exclusive access NULL, // default security attributes OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);if (hCom == INVALID_HANDLE_VALUE){printf("CreateFile failed with error %d.\n", GetLastError());return;}// 设置事件掩码fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR | EV_RXCHAR);if (!fSuccess){printf("SetCommMask failed with error %d.\n", GetLastError());return;}// 等待事件 WaitCommEvent函数会在SetCommMask设定的监听时间发生前返回if (WaitCommEvent(hCom, &dwEvtMask, NULL)){// 这个函数可以获取数据缓冲区的长度if (ClearCommError(hCom, &dwError, &ComState)){DWORD Size = 0;DWORD Length = 0;while (ComState.cbOutQue != Length){if (!ReadFile(hCom, buffer + Length, ComState.cbOutQue, &Size, NULL)){break;}Length

http://www.mrgr.cn/news/36371.html

相关文章:

  • 【2024/9/25更新】最新版植物大战僵尸V2.5.1发布啦
  • [前端]DOM+CSS+HTML实现水波进度效果
  • 【WRF数据介绍第二期】气象驱动场数据介绍及下载
  • 系统分析师13:软件工程
  • HashMap哈希表练习
  • Springboot Mybatis XML配置文件
  • 毕业设计选题:基于ssm+vue+uniapp的自助购药小程序
  • 快手一面:给定一棵二叉树,要求将其转换为其镜像?
  • python库 | lxml库
  • 使用AI进行需求分析的案例研究
  • 进制数知识(2)—— 浮点数在内存中的存储 和 易混淆的二进制知识总结
  • 深圳前海壹方汇的免费停车点探寻
  • Java查找算法——(四)分块查找(完整详解,附有代码+案例)
  • 【mac开发入坑指南】分屏mac程序坞移动到另外一个屏幕
  • mysql学习教程,从入门到精通,SQL FULL JOIN 语句(25)
  • alpine安装docker踩坑记
  • 链表入门(LeetCode题目)
  • Claude 的上下文检索功能提升了 RAG 准确率,这会是人工智能革命?
  • C++深入学习string类成员函数(1):默认与迭代
  • yolov8训练数据集——labelme的json文件转txt文件