0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

英创信息技术工控主板USB通信方案介绍

英创信息技术 来源:英创信息技术 作者:英创信息技术 2020-01-15 14:44 次阅读

英创AMR9系列工控主板可以使用USB与PC连接并进行通信。在主板上,我们将USB引到了COM1,使得我们可以通过操作串口的方式来操作USB口的连接与收发。在PC端,我们提供一个使用WDK提供的驱动,来进行USB通信的解决方案。

驱动的安装及说明请参考文章《英创工控主板USB驱动安装说明》。

工控主板端USB收发程序说明

英创AMR9系列工控主板已将USB引导COM1,这里使用开发光盘中的串口例程SPT_HEX做USB收发调试例程。

代码中需要注意的地方:

BOOL ret = OpenPort(portName, baud, databit, stopbit, parity); /* 打开串口*/

在界面中选择COM1打开,调用函数OpenPort,参数portName值为_T('COM1:')。

波特率,停止位,数据位,校验参数不产生实际作用,这里可以使用默认值。

GetCommTimeouts(m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 100; /* 接收字符间最大时间间隔*/
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutConstant = 0; /* 读数据总超时常量*/
CommTimeOuts.WriteTotalTimeoutMultiplier = 1; /* 设置写超时,避免阻塞*/
CommTimeOuts.WriteTotalTimeoutConstant = 2; /* 设置写超时,避免阻塞*/
SetCommTimeouts(m_hComm, &CommTimeOuts) ;

在函数OpenPort中,调用SetCommTimeouts设置超时函数时最好设置有写超时,否则在发数据时,在PC端接收完数据前,WriteFile函数会一直阻塞。

PC端USB收发程序说明

在WDK提供的驱动中,创建了2个pipe来进行USB的收发,通过对这两个pipe的ReadFile和WriteFile操作进行USB通信。

1、检测设备

USB设备支持即插即用,当设备连接或断开时,都可以收到系统将发出的消息。

使用该消息需要先引用系统头文件

#include 'dbt.h'

并在在MESSAGEMAP宏中添加设备检测消息WM_DEVICECHANGE

BEGIN_MESSAGE_MAP(Cusb_connDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP

ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

在对话框头文件中添加该消息的响应函数

afx_msg BOOL OnDeviceChange(UINT nEventType,DWORD_PTR dwData);

当设备发生变化(USB接上或断开)时,OnDeviceChange函数会得到响应。
BOOL Cusb_connDlg::OnDeviceChange( UINT nEventType, DWORD_PTR dwData )
{
switch(nEventType)
{
case DBT_DEVICEARRIVAL:
// UpdateUsbDeviceList();
break;
case DBT_DEVICEREMOVECOMPLETE:
//UpdateUsbDeviceList();
//UpdateWindow();
break;
}
return TRUE;
}

获取USB读写管道路径

首先,获取设备路径需要使用到setupapi.lib库中的相关函数,所以需要在工程中添加setupapi.lib库

添加setupapi.lib库的头文件

#include

添加驱动代码的public.h头文件,该头文件定义了USB设备的GUID

// {6068EB61-98E7-4c98-9E20-1F068295909A}

DEFINE_GUID(GUID_CLASS_USBSAMP_USB,
0x873fdf, 0x61a8, 0x11d1, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0x8b);

添加一个GetUsbDeviceFileName函数通过GUID获取设备地址

BOOL Cusb_connDlg::GetUsbDeviceFileName(LPGUID pGuid, LPWSTR devName)
{
ULONG NumberDevices;
HDEVINFO hardwareDeviceInfo;
SP_DEVICE_INTERFACE_DATA deviceInfoData;
ULONG i;
BOOLEAN done;
PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL;
ULONG predictedLength = 0;
ULONG requiredLength = 0;
hardwareDeviceInfo =
SetupDiGetClassDevs ( pGuid,
NULL, // Define no enumerator (global)
NULL, // Define no
(DIGCF_PRESENT | // Only Devices present
DIGCF_DEVICEINTERFACE)); // Function class devices.
if (hardwareDeviceInfo == INVALID_HANDLE_VALUE) {
return FALSE ;
}
NumberDevices = 4;
done = FALSE;
deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
i=0;
while (!done)
{
NumberDevices *= 2;
for (; i < NumberDevices; i++)
{
if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
0, // We don't care about specific PDOs
pGuid,
i,
&deviceInfoData))
{
SetupDiGetDeviceInterfaceDetail (
hardwareDeviceInfo,
&deviceInfoData,
NULL, // probing so no output buffer yet
0, // probing so output buffer length of zero
&requiredLength,
NULL); // not interested in the specific dev-node
predictedLength = requiredLength;
// sizeof (SP_FNCLASS_DEVICE_DATA) + 512;
functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (predictedLength);
if(NULL == functionClassDeviceData)
{
break;
}
functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
if (! SetupDiGetDeviceInterfaceDetail (
hardwareDeviceInfo,
&deviceInfoData,
functionClassDeviceData,
predictedLength,
&requiredLength,
NULL))
{
free( functionClassDeviceData );
break;;
}

StringCchCopy(devName, MAX_LENGTH, functionClassDeviceData->DevicePath) ;
free( functionClassDeviceData );
done = TRUE;
break;
}
else
{
if (ERROR_NO_MORE_ITEMS == GetLastError())
{
done = TRUE;
i = -1;
break;
}
}
}
}
NumberDevices = i;
SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
if (i >= 0)
{
return TRUE;
}
else
{
return FALSE;
}
}

该函数大致流程:

1.通过SetupDiGetClassDevs函数根据GUID获得设备顶级窗口句柄。

2.然后通过这个句柄,使用SetupDiEnumDeviceInterfaces函数枚举USB设备,直到找到符合条件的USB设备或枚举完所有设备为止。

3.当找到符合条件的设备后,使用SetupDiGetDeviceInterfaceDetail函数获取设备路径。

根据设备路径获得输入管道和输出管道的路径。

// 获得USB设备路径 deviceName '\\?\usb#vid_045e&pid_00ce#00000000-0000-0000-0427-980002d9f4b1#{00873fdf-61a8-11d1-aa5e-00c04fb1728b}'
if(!GetUsbDeviceFileName((LPGUID)&GUID_CLASS_USBSAMP_USB, deviceName))
{
MessageBox(L'设备未连接');
return;
}
// hRead读管道路径 inPipe '\\?\usb#vid_045e&pid_00ce#00000000-0000-0000-0427-980002d9f4b1#{00873fdf-61a8-11d1-aa5e-00c04fb1728b}\PIPE00'
StringCchCopy(inPipe , MAX_LENGTH, deviceName);
StringCchCat(inPipe, MAX_LENGTH, L'\\' );
if(FAILED(StringCchCat (inPipe, MAX_LENGTH, L'PIPE00'))) {
return;
}
// hWrite写管道路径 outPipe '\\?\usb#vid_045e&pid_00ce#00000000-0000-0000-0427-980002d9f4b1#{00873fdf-61a8-11d1-aa5e-00c04fb1728b}\PIPE01'
StringCchCopy(outPipe , MAX_LENGTH, deviceName);
StringCchCat(outPipe, MAX_LENGTH, L'\\' );
if(FAILED(StringCchCat (outPipe, MAX_LENGTH, L'PIPE01'))) {
return;
}

驱动代码设定,输入管道路径为设备路径加上\PIPE00,输出管道路径为设备路径加上\PIPE01

2、USB口通信

通过CreateFile打开管道,使用WriteFile和ReadFile就可以进行USB口的输入输出了。

注意,在读取USB口数据时,ReadFile函数会阻塞。所以需要用非阻塞的方式读,在打开PIPE时使用FILE_FLAG_OVERLAPPED标记。

hRead = CreateFile(inPipe,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if(hRead == INVALID_HANDLE_VALUE)
{
MessageBox(L'输入通道打开失败');
return;
}

在读线程中使用异步方式读。

success = ReadFile(pDlg->hRead, pDlg->inBuf, 65536, &len, &overlap);
// 因为是overlapped操作,ReadFile会将读文件请求放入读队列之后立即返回(false),而不会等到文件读完才返回(true)
if (!success)
{
if (GetLastError() == ERROR_IO_PENDING)
{
dwRes = WAIT_TIMEOUT;
while(dwRes != WAIT_OBJECT_0)
{
dwRes = WaitForSingleObject(pDlg->hRead, 1000);
// 获取读的的长度
success = GetOverlappedResult(pDlg->hRead, &overlap, &len, FALSE);
// 上面二条语句完成的功能与下面一条语句的功能等价:
// 一直阻塞等到得到数据才继续下面。
// GetOverlappedResult(pDlg->hRead, &overlap, &len, TRUE);
if (pDlg->killThread)
{
// 关闭线程,直接关闭
return 0;
}
}
}
else
{
// 出错!
return -1;
}
}

传输速度测试

编写程序,测试工控主板端向PC端的数据传输速度。

EM9170上传速度最高可达3.6MB/秒。

EM9160上传速度最高可达500kb/秒。

其他说明

驱动中默认的管道BUFFER大小为256字节,在读写操作时,不宜超过管道BUFFER大小,否则会返回失败。例程中提供一个修改后的驱动,只是简单将BUFFER扩大到64K,原驱动保留为usbsamp_bak.sys。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式主板
    +关注

    关注

    7

    文章

    6084

    浏览量

    35148
收藏 人收藏

    评论

    相关推荐

    中科达荣获2024年软件和信息技术服务优秀企业

    及前百家企业”名单。中科达凭借非凡的技术实力与持续的创新能力,成功入选“2024年度软件和信息技术服务竞争力百强企业”以及“2024年软件和信息技术服务优秀企业”。
    的头像 发表于 10-30 11:44 296次阅读

    工控机重装系统的方法介绍

      工控机怎么重装系统,工控机重装系统的方法介绍攻略   首先看下自己购买的什么工控机,是工业平板电脑还是常规的工控主机,我们此篇
    的头像 发表于 10-23 17:11 151次阅读

    工控主板有哪些特点?

     工控主板是用于工业控制领域的专用主板,具有以下特点: 稳定性:工控主板通常经过严格的测试和优化,具有较高的稳定性和可靠性,能够在恶劣的工业
    的头像 发表于 10-10 08:55 167次阅读

    国产化背景下的工控主板发展现状

    ,是信息技术应用创新产业的简称,于2016年“信工委会”(信息技术应用创新工作委员会)提出,目的就是要推动我们国内软硬件关键技术的研发
    的头像 发表于 09-21 16:15 257次阅读

    梯度科技入选2023年信息技术应用创新解决方案名单

    日前,工业和信息化部网络安全产业发展中心(工业和信息化部信息中心)在天津举办2024信息技术应用创新发展大会暨解决方案应用推广大会。会上正式
    的头像 发表于 09-09 16:29 349次阅读

    兆芯金融方案入选工信部2023年信息技术应用创新典型解决方案

    近日,由工信部网络安全产业发展中心等主办的2024信息技术应用创新发展大会暨解决方案应用推广大会在天津、浙江、福建、山东四地联动同步召开,会上公布了2023年信息技术应用创新解决方案
    的头像 发表于 08-05 16:12 628次阅读

    浅析安卓工控主板的优势

    安卓工控主板作为专为工业控制领域设计的硬件平台,相较于普通商用主板,拥有诸多优势,以满足工业环境对稳定、可靠、长期运行的严格要求。以下是安卓工控主板
    的头像 发表于 06-27 14:50 279次阅读

    使用工控主板时该注意哪些事项?

    最近大家都在频繁问一个问题就是工控主板在什么人为情况下容易出现故障,从而造成工控主板的损坏,那今天小编就来讲讲,我们在使用工控
    的头像 发表于 06-05 16:01 331次阅读
    使用<b class='flag-5'>工控</b><b class='flag-5'>主板</b>时该注意哪些事项?

    工控主板容易出现故障的原因有哪些?

    最近大家都在频繁问一个问题就是工控主板在什么人为情况下容易出现故障,从而造成工控主板的损坏,那今天小编就来讲讲,我们在使用工控
    的头像 发表于 05-17 10:57 287次阅读

    工控主板的性能指标有哪些?

    工控主板是工业控制领域中的关键组成部分,它承载着工控系统的核心功能。因此,工控主板的性能指标是评估其质量和性能的重要标准。本文将
    的头像 发表于 05-10 16:27 845次阅读
    <b class='flag-5'>工控</b><b class='flag-5'>主板</b>的性能指标有哪些?

    翼辉信息入选2023年信息技术应用创新解决方案名单

    近日,2023 年(第五届)信息技术应用创新解决方案公布遴选名单,历经资格初审、技术中评、区域评议、终评预审,翼辉以“面向工业领域嵌入式操作系统 SylixOS 解决方案”,成功在全国
    的头像 发表于 04-28 11:37 490次阅读
    翼辉<b class='flag-5'>信息</b>入选2023年<b class='flag-5'>信息技术</b>应用创新解决<b class='flag-5'>方案</b>名单

    工控主板和普通主板的区别有哪些

    工控主板和普通主板是两种在计算机硬件领域中常见的主板类型,它们在设计、功能和用途上有着明显的区别。工控
    的头像 发表于 04-25 16:54 1086次阅读
    <b class='flag-5'>工控</b><b class='flag-5'>主板</b>和普通<b class='flag-5'>主板</b>的区别有哪些

    购买工控主板的三大误区

    最近有很多人问我什么样的工控主板算好的,有没有一个统一的标准。工控主板作为整机的核心组成部分,在性能稳定上有着至关重要的作用,那今天小编就来给大家讲解一下在购买
    的头像 发表于 04-16 16:40 275次阅读

    龙芯中科三项信方案入围工信部2023年信息技术应用创新应用示范案例名单

    近日,工业和信息化部通报了2023年信息技术应用创新解决方案征集遴选结果,本次共评选出典型解决方案173个、应用示范案例83个、单项创新案例64个。
    的头像 发表于 03-07 16:45 820次阅读
    龙芯中科三项信<b class='flag-5'>创</b><b class='flag-5'>方案</b>入围工信部2023年<b class='flag-5'>信息技术</b>应用创新应用示范案例名单

    工控机主板与嵌入式主板的区别是什么?

    在计算机硬件中,主板是至关重要的组成部分,它连接并控制着所有的硬件设备。然而,根据其设计和使用场景的不同,主板可以被分为多种类型,选择合适的主板对于不同的嵌入式系统应用来说至关重要。那么工控机
    的头像 发表于 11-16 10:29 1894次阅读
    <b class='flag-5'>工控机主板</b>与嵌入式<b class='flag-5'>主板</b>的区别是什么?