可以真正实现免驱的WinUSB设备-程序员宅基地

技术标签: 驱动程序  usb  windows 10  

为什么要使用WinUSB设备?

  1. 如果您现在需要开发一款设备需要与PC通信,用USB接口是个不错的选择。每个USB设备在PC主机上都有对应的一个驱动程序,Windows操作系统为常用标准USB设备类型(如HID设备类、USB接口打印机、优盘等)提供了对应的驱动程序,但如果您开发的USB设备不是标准设备类,那么使用微软WinUSB将是个不错的选择。我们平常见得最多的就是USB_HID类型的USB,但是HID类型适合鼠标、键盘等传输速率比较小的设备,如果你需要传输大量数据并且传输速率要比USB_HID快,同时也能实现免驱的话,不妨试试WinUSB。
  2. Windows USB (WinUSB) 是 Microsoft 提供的 USB 设备的通用驱动程序。WinUSB由两部分组成,分别是winusb.sys和winusb.dll。Winusb.sys 是一种内核模式驱动程序,可在 USB 设备的内核模式设备堆栈的协议驱动程序之上作为筛选器驱动程序或功能驱动程序进行安装。Winusb.dll 是一种公开 WinUSB 功能的用户模式 DLL。当 Winusb.sys 作为设备的功能驱动程序安装后,应用程序可以使用这些功能与其进行通信。
  3. Microsoft 提供了 Winusb.inf,其中包含将Winusb.sys 作为 USB 设备的设备驱动程序安装所需的信息。如果你的系统是windows 7,那么你需要自己你需要提供自定义 INF。自定义 INF 指定设备特定的硬件 ID,同时包括内置 Winusb.inf 的部分。这些部分是实例化服务、复制内置二进制文件以及注册设备接口 GUID(应用程序查找设备和与设备通讯必须使用 GUID)所必需的。在枚举成功之后进行驱动更新的时候,选择包含自定义inf的文件夹即可(如下)。但是如果你的系统是windows 7以上系统,你就不必提供inf文件,因为 Microsoft已经替你准备好了,你只需要在更新驱动时选择“浏览我的电脑以获取驱动程序软件”—》选择“让我从计算机上的设备驱动程序列表中选择” —》从设备类别列表中,选择通用串行总线设备—》向导显示WinUsb设备,选择它以加载驱动程序即可。自定义inf文件实例(windows 7系统用):
; ================ Version section =================
 
[Version]
Signature="$Windows NT$"
Class=USB
ClassGuid={
    88bae032-5a81-49f0-bc3d-a4ff138216d6}
Provider = %ProviderName%
DriverVer = 12/04/2012, 0.2.0.0

; ========== Manufacturer/Models sections =========== 

[Manufacturer]
%ProviderName% = MyWinUSBDevice,NTx86,NTamd64

[MyWinUSBDevice.NTx86]
%DeviceDesc%=USB_Install, USB\VID_0483&PID_5750

[MyWinUSBDevice.NTamd64]
%DeviceDesc%=USB_Install, USB\VID_0483&PID_5750
; ================== Installation ==================
[ClassInstall]
AddReg=ClassAddReg

[ClassInstall32]
AddReg=ClassAddReg

[ClassAddReg]
HKR,,,,"%ClassName%"
HKR,,Icon,,-28

[USB_Install]
Include = WinUSB.inf 
Needs = WinUSB.NT 

[USB_Install.Services]
Include = WinUSB.inf
AddService = WinUSB, 0x00000002, WinUSB_ServiceInstall

[WinUSB_ServiceInstall]
DisplayName     = %WinUSB_SvcDesc%
ServiceType     = 1
StartType       = 3
ErrorControl    = 1
ServiceBinary   = %12%\WinUSB.sys

[USB_Install.Wdf]
KmdfService = WinUSB, WinUSB_Install

[WinUSB_Install]
KmdfLibraryVersion = 1.11

[USB_Install.HW]
AddReg = Dev_AddReg

[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x00010000,"{745a17a0-74d3-11d0-b6fe-00a0c90f57da}"

[USB_Install.CoInstallers]
AddReg = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles

[CoInstallers_AddReg]
HKR, , CoInstallers32, 0x00010000, "WinUSBCoInstaller2.dll","WdfCoInstaller01009.dll, WdfCoInstaller"

[CoInstallers_CopyFiles]
WinUSBCoInstaller2.dll
WdfCoInstaller01009.dll


[SourceDisksNames]
1 = %MediaDescription%
 
[SourceDisksFiles]
WinUSBCoInstaller2.dll = 1, x86
WdfCoInstaller01009.dll = 1, x86

 
[SourceDisksFiles.amd64]
WinUSBCoInstaller2.dll = 1, amd64
WdfCoInstaller01009.dll = 1, amd64
 
[DestinationDirs]
CoInstallers_CopyFiles = 11

; ==================== Strings =====================
[Strings]
ProviderName="YMSG Software"

DeviceDesc="MY WINUSB"
MediaDescription  = "USB MY WINUSB Disc"
WinUSB_SvcDesc = "WinUSB Driver Service"

USB设备的枚举过程

要想让设备被识别为WinUSB设备,首先得先让设备被识别成为USB设备(USB设备的枚举过程)如果在枚举过程中出错,我们就很难判断出错误在哪里,这里推荐大家使用bus hound(大家可以自己去网上下载)来进行抓包分析。这里是我自己抓包结果:

Bus Hound 6.00 capture on Windows Vista (x64). Complements of www.perisoft.net

  Device - Device ID (followed by the endpoint for USB devices)
            (31) STM32 WINUSB
            (32) STM32 WINUSB
            (33) STM32 WINUSB
  Length - Total transfer length
  Phase  - Phase Type
            CTL   USB control transfer       
            IN    Data in transfer           
            URB   USB request block          
  Data   - Hex dump of the data transferred
  Descr  - Description of the phase
  Cmd... - Position in the captured data


Device  Length    Phase  Data                                                Description       Cmd.Phase.Ofs(rep)
------  --------  -----  --------------------------------------------------  ----------------  ------------------
  33.0            CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           1.1.0        
  33.0        18  IN     12 01 00 02  00 00 00 40  83 04 50 57  00 02 01 02  .......@..PW....         1.2.0        
                         03 01                                               ..                       1.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         1.3.0        
                         00 00 00 00  45 00 47 00  b0 cc cb 7a  0e 96 ff ff                           1.3.16       
                         5b 00 5c 00  12 00 00 00  b0 53 51 6f  0e 96 ff ff                           1.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           1.3.48       
  33.0            CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           2.1.0        
  33.0        18  IN     12 01 00 02  00 00 00 40  83 04 50 57  00 02 01 02  .......@..PW....         2.2.0        
                         03 01                                               ..                       2.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         2.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           2.3.16       
                         0b 00 00 00  12 00 00 00  68 3b 14 7c  0e 96 ff ff                           2.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           2.3.48       
  33.0            CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR           3.1.0        
  33.0         9  IN     09 02 20 00  01 01 04 c0  32                        .. .....2                3.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         3.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           3.3.16       
                         0b 00 00 00  09 00 00 00  10 71 4c 73  89 ce ff ff                           3.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           3.3.48       
  33.0            CTL    80 06 00 02  00 00 20 00                            GET DESCRIPTOR           4.1.0        
  33.0        32  IN     09 02 20 00  01 01 04 c0  32 09 04 00  00 02 ff 00  .. .....2.......         4.2.0        
                         00 00 07 05  01 02 40 00  00 07 05 81  02 40 00 00  ......@......@..         4.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         4.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           4.3.16       
                         0b 00 00 00  20 00 00 00  90 b7 e4 82  0e 96 ff ff                           4.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           4.3.48       
  33.0            CTL    80 00 00 00  00 00 02 00                            GET STATUS               5.1.0        
  33.0         2  IN     01 00                                               ..                       5.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         5.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           5.3.16       
                         0b 00 00 00  02 00 00 00  d0 6e 4c 73  89 ce ff ff                           5.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           5.3.48       
  33.0            CTL    00 09 01 00  00 00 00 00                            SET CONFIG               6.1.0        
  33.0            URB    70 00 00 00  00 00 00 00  98 53 19 84  f1 69 00 00  SELECT CONFIG            6.2.0        
                         00 00 00 00  00 00 00 00  90 b7 e4 82  0e 96 ff ff                           6.2.16       
                         30 cc df 7d  0e 96 ff ff  48 00 00 00  ff 00 00 00                           6.2.32       
                         e0 9b 30 7f  0e 96 ff ff  02 00 00 00  00 00 00 00                           6.2.48       
  33.0            CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR           7.1.0        
  33.0         9  IN     09 02 20 00  01 01 04 c0  32                        .. .....2                7.2.0        
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         7.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           7.3.16       
                         0b 00 00 00  09 00 00 00  40 1b 2e 83  0e 96 ff ff                           7.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           7.3.48       
  33.0            CTL    80 06 00 02  00 00 20 00                            GET DESCRIPTOR           8.1.0        
  33.0        32  IN     09 02 20 00  01 01 04 c0  32 09 04 00  00 02 ff 00  .. .....2.......         8.2.0        
                         00 00 07 05  01 02 40 00  00 07 05 81  02 40 00 00  ......@......@..         8.2.16       
  33.0            URB    88 00 08 00  00 00 00 00  98 53 19 84  f1 69 00 00  CONTROL TRANSFER         8.3.0        
                         00 00 00 00  00 00 00 00  b0 cc cb 7a  0e 96 ff ff                           8.3.16       
                         0b 00 00 00  20 00 00 00  40 1b 2e 83  0e 96 ff ff                           8.3.32       
                         00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00                           8.3.48       

其中对于各种描述符的配置,大家可以参考这里

如何让一个USB设备被识别为WinUSB设备?

在成功识别为USB设备之后, 若要将 USB 设备标识为 WinUSB 设备,设备固件必须具有这些 Microsoft OS 描述符。

1.支持 OS 字符串描述符
为了让 USB 驱动程序堆栈了解设备支持扩展的特征描述符,设备必须定义存储在字符串索引 0xEE 处的 OS 字符串描述符。在枚举过程中,驱动程序堆栈查询字符串描述符。如果存在描述符,驱动程序堆栈会假定设备包含一个或多个OS 特征描述符和检索这些特征描述符所需要的数据。检索的字符串描述符具有 bMS_VendorCode 字段值。该值表示 USB 驱动程序堆栈必须用来检索扩展特征描述符的供应商代码。

#define bMS_VendorCode              ( 0x01 )
// "MSFT100" : index : 0xEE : langId : 0x0000
const U8 OS_StringDescritpor[ ] =
{
     0x12,  0x03,  'M',  0,  'S',  0,  'F',  0,  'T',  0,  '1',  0,  '0',  0,  '0',  0,  bMS_VendorCode,  0 };

2.设置兼容 ID 特征描述符
匹配内置 Winusb.inf 和加载 WinUSB 驱动程序模块所需要的扩展兼容 ID OS 特征描述符。扩展兼容 ID OS 特征描述符包含紧跟一个或多个功能部分的标题部分,具体取决于是否是复合设备。标题部分指定整个描述符的长度、功能部分的数量以及版本号。对于非复合设备,标题后紧跟一个仅与设备的接口关联的功能部分。该部分的 compatibleID 字段必须指定 “WINUSB” 作为字段值。复合设备有多个功能部分。每个功能部分的 compatibleID 字段必须指定 “WINUSB”。

// "WINUSB\0\0" : wIndex : 0x0004
const U8 WINUSB_ExtendedCompatId_Descritpor[ ] =
{
    
  0x28, 0x00, 0x00, 0x00,                         // dwLength
  0x00, 0x01,                                     // bcdVersion
  0x04, 0x00,                                     // wIndex
  0x01,                                           // bCount
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       // Reserved[7]
  0x00,                                           // bFirstInterfaceNumber
  0x01,                                           // RESERVED ( 0x01 )
  'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,       // compactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00              // Reserved[6]
};

3.注册设备接口 GUID
注册设备接口 GUID 所需要的扩展属性 OS 特征描述符。需要使用 GUID 从应用程序或服务查找设备、配置设备以及执行 I/O 操作。在以前版本的 Windows 中,设备接口 GUID 注册通过自定义 INF 完成。从 Windows 8 开始,你的设备应使用扩展属性 OS 特征描述符报告接口 GUID。

// L"DeviceInterfaceGUID" : wIndex = 0x0005
// L"{12345678-1234-1234-1234-123456789ABC}"(可以换自己的GUID)
const U8 WINUSB_ExtendedProperty_InterfaceGUID_Descritpor[ ] =
{
    
  0x8E, 0x00, 0x00, 0x00,     // dwTotalSize = Header + All sections
  0x00, 0x01,                 // bcdVersion
  0x05, 0x00,                 // wIndex
  0x01, 0x00,                 // wCount
  
  0x84, 0x00, 0x00, 0x00,     // dwSize -- this section
  
  0x01, 0x00, 0x00, 0x00,     // dwPropertyDataType
  
  0x28, 0x00,                 // wPropertyNameLength
  
  'D', 0x00, 'e', 0x00,       // bProperytName : WCHAR : L"DeviceInterfaceGUID"
  'v', 0x00, 'i', 0x00,       // bProperytName : WCHAR
  'c', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'I', 0x00, 'n', 0x00,       // bProperytName : WCHAR
  't', 0x00, 'e', 0x00,       // bProperytName : WCHAR
  'r', 0x00, 'f', 0x00,       // bProperytName : WCHAR
  'a', 0x00, 'c', 0x00,       // bProperytName : WCHAR
  'e', 0x00, 'G', 0x00,       // bProperytName : WCHAR
  'U', 0x00, 'I', 0x00,       // bProperytName : WCHAR
  'D', 0x00, 0x00, 0x00,      // bProperytName : WCHAR
  
  0x4E, 0x00, 0x00, 0x00,     // dwPropertyDataLength : 78 Bytes = 0x0000004E
  
  '{', 0x00, '1', 0x00,       // bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '4', 0x00, '-', 0x00,       // bPropertyData
  '1', 0x00, '2', 0x00,       // bPropertyData
  '3', 0x00, '4', 0x00,       // bPropertyData
  '-', 0x00, '1', 0x00,       // bPropertyData
  '2', 0x00, '3', 0x00,       // bPropertyData
  '4', 0x00, '5', 0x00,       // bPropertyData
  '6', 0x00, '7', 0x00,       // bPropertyData
  '8', 0x00, '9', 0x00,       // bPropertyData
  'A', 0x00, 'B', 0x00,       // bPropertyData
  'C', 0x00, '}', 0x00,       // bPropertyData
  0x00, 0x00                  // bPropertyData
};

WinUSB设备枚举成功后如何挂载驱动

                       WinUSB设备驱动挂载流程
                       
一、在windows 10系统上:
1.将WinUSB设备插入主机系统。
2.打开设备管理器并找到WinUSB设备。
3.选择并按住(或右键单击)WinUSB设备,然后从上下文菜单中选择“更新驱动程序软件... ”。
4.在向导中,选择“浏览我的电脑以获取驱动程序软件”。
5.选择“让我从计算机上的设备驱动程序列表中选择” 。
6.从设备类别列表中,选择通用串行总线设备。
7.向导显示WinUsb设备。选择它以加载驱动程序。

二、在windows 7系统上(找到Windows 7 Driver文件夹位置):
1.将WinUSB设备插入主机系统。
2.打开设备管理器并找到WinUSB设备。
3.选择并按住(或右键单击)WinUSB设备,然后从上下文菜单中选择“更新驱动程序软件... ”。
4.在向导中,选择“浏览我的电脑以获取驱动程序软件”。
5.选择文件夹Windows 7 Driver。
6.点击下一步。
7.选择“始终安装此驱动软件程序“。
8.加载驱动成功。

如何确定WinUSB设备驱动挂载成功

1.在”通用串行总线设备“下面可以看到枚举成功的”STM32 WINUSB“:
在
2.在”常规“里可以看到如下结果:
在这里插入图片描述
3.在”驱动程序“里可以看到如下结果:在这里插入图片描述
4.在”详细信息“里的”设备描述“可以看到如下结果:在这里插入图片描述
推荐网站:
1.https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation
2.https://blog.csdn.net/weixin_34081595/article/details/85552321

说到最后

这是我作为实习生去公司后自己独自一人搞了两个月(目前还在搞),从不熟悉usb协议到最后WinUSB枚举成功,其中的难度对我来说还是很大的,因为网上WinUSB的资料确实不是很多(也可能我没有找到),只能自己慢慢摸索,每次碰壁之后我都会回去看看usb最基础的协议,总能给我启发。但是成功之后的喜悦也是无可比拟的。最后也希望这篇文章能对大家有所帮助,如果有什么问题也希望大家指出来,共同交流。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46753805/article/details/116200729

智能推荐

艾美捷Epigentek DNA样品的超声能量处理方案-程序员宅基地

文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。

11、合宙Air模块Luat开发:通过http协议获取天气信息_合宙获取天气-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文  本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。  先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。  我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气

EasyMesh和802.11s对比-程序员宅基地

文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s

线程的几种状态_线程状态-程序员宅基地

文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态

stack的常见用法详解_stack函数用法-程序员宅基地

文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法

2018.11.16javascript课上随笔(DOM)-程序员宅基地

文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树:  节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...

随便推点

layui.extend的一点知识 第三方模块base 路径_layui extend-程序员宅基地

文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend

5G云计算:5G网络的分层思想_5g分层结构-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构

基于二值化图像转GCode的单向扫描实现-程序员宅基地

文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。

算法随笔:强连通分量-程序员宅基地

文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量

Django(2)|templates模板+静态资源目录static_django templates-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates

linux下的GPU测试软件,Ubuntu等Linux系统显卡性能测试软件 Unigine 3D-程序员宅基地

文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...

推荐文章

热门文章

相关标签