winusb —— 不再为你的usb设备编写驱动

2023-11-14

【blog.csdn.net/lanmanck】

曾几何时我们找工作还发现有个驱动工程师职位,月薪也不低,没接触过的人代码压根看不懂。

今天可好了,如果不太追求差异化,不用驱动也能让系统与USB设备通信了,Linux就不说了,libusb很好用,现在说下windows的。

Winusb是从XP-SP2起微软提供的一个类似libusb与usb设备通信的中间件,通过它我们就不需要再费奏折的研究和编写USB驱动了。这是几篇资源,先列出来,后面会专门转载一篇详细的blog文,以便有个彻底的认识,不过是E文的,要看仔细点。

资源:

1、libusb介绍:http://www.libusb.org/wiki/windows_backend

2、Jan的使用博客:http://www.lvr.com/winusb.htm,以及它的详细介绍:http://www.lvr.com/winusb_article.htm

3、微软教你如何安装inf:http://blogs.msdn.com/b/usbcoreblog/archive/2012/09/26/how-to-install-winusb-sys-without-a-custom-inf.aspx

4、另一个哥们写的.net-winusb控件和源码:http://www.asyncop.com/MTnPDirEnum.aspx?treeviewPath=[o]+Open-Source\WinUSB+Component

5、微软官方描述:http://msdn.microsoft.com/zh-cn/library/ff540196.aspx

6、微软教你如何通信:http://msdn.microsoft.com/library/windows/hardware/gg487341

7、一个哥们做的stm32通信,要翻墙:http://searchingforbit.blogspot.com/2012/04/winusb-communication-with-stm32-part-1.html

好了,转帖一个winusb的e文介绍,还是老外写的专业点:

Explore USB with WinUSB
This article originally appeared in Nuts & Volts.

If you’re developing a device that needs to talk to a PC, the chances are good that USB will be involved. For each USB device, the PC assigns a software driver. Windows provides drivers for devices that fit into defined USB classes such as human interface, printer, or mass storage. If your device doesn’t fit a defined class, Microsoft’s WinUSB driver is an option.

In this article, I'll show how to program and access WinUSB devices. The WinUSB driver requires a PC with Windows XP SP2 or later, including Windows Vista and Windows 7.

A Transfer Type for Every Purpose
Every USB data transfer is between a PC or other USB host computer and a device endpoint. A device endpoint is a buffer that stores received data or data to transmit. Every device must support endpoint zero, which is bidirectional. Additional, optional endpoint addresses each have a number (1-15) and a direction (IN or OUT).

Even though endpoints reside on devices, the USB specification defines endpoint direction from the view of the host PC. An IN endpoint sends data to the PC, and an OUT endpoint receives data from the PC. This naming convention can be confusing when writing code for the device side!

One reason why USB is so versatile is its support for four transfer types, each with different strengths. WinUSB supports control, bulk, and interrupt transfers. Control transfers use endpoint zero. The other transfer types can use endpoints one and higher.

Control transfers provide a structured way to send requests and data and receive responses. Control transfers are the only type that can pass information in both directions in a single transfer. After device attachment, in a process called enumeration, the host computer uses control transfers to learn about the device.

WinUSB devices can also use control transfers to send and receive data in vendor-defined requests. For example, you can define a request to set or read a switch, send data to configure device operation, or receive a sensor reading.

A control transfer has two or three stages. To learn about a newly attached device, the host computer uses control transfers to request data structures called descriptors from the device. In the Setup stage, the host sends the request. In the Data stage, the device sends the requested descriptor. In the Status stage, the host acknowledges receiving the descriptor. A host can also use control transfers to send information to a device in the Data stage, with the device acknowledging in the Status stage. Some requests have no Data stage.

A USB host reserves a portion of the bus bandwidth for control transfers: 10% for low- and full-speed endpoints and 20% for high-speed endpoints. If the bus isn’t busy, control transfers can use more than the reserved bandwidth. But all devices must share the bus, so on a busy bus, a control transfer may have to wait.

The other transfer types don’t have multiple stages and can transfer data for any purpose. On an otherwise idle bus, bulk transfers are the fastest. But bulk transfers have no guaranteed bandwidth, so on a busy bus, bulk transfers must wait. Common uses for bulk transfers are printers and scanners, where quick transfers are nice but not essential.

For interrupt transfers, the host guarantees a maximum interval between requests for data from IN endpoints or sending data to OUT endpoints. Common uses for interrupt transfers are mice and keyboards, which need to transfer user input quickly to the host computer.

Isochronous transfers have a guaranteed transfer rate but unlike the other transfer types, isochronous transfers don’t use acknowledgements, and the receiver has no defined way to request re-transmitting corrupted data. Common uses for isochronous transfers are streaming audio and video, where users won’t notice or will tolerate a few corrupted or missing packets. WinUSB doesn’t support isochronous transfers.

Using the USB Framework
My example code is for Microchip Technology’s PIC18F4550 microcontroller and MPLAB C18 compiler. I tested the code on Microchip’s PICDEM FS-USB development board. A complete WinUSB project for the PIC along with companion Visual Basic and Visual C# applications are available from my website.

My PIC code uses Microchip’s free USB Framework, which is a set of source-code modules that handle low-level USB communications. Using the Framework can save much time and trouble.

For each endpoint besides endpoint zero, the device provides an endpoint descriptor. This listing shows endpoint descriptors for bulk and interrupt endpoints in each direction:

// Endpoint descriptors
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP01_OUT,               //  Endpoint number and direction
_BULK,                   //  Transfer type
0x40, 0x00,              //  Endpoint size in bytes
0x00,                    //  Ignored for bulk endpoint
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP01_IN,                //  Endpoint number and direction
_BULK,                   //  Transfer type
0x40, 0x00,              //  Endpoint size in bytes
0x00,                    //  Ignored for bulk endpoint
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP02_OUT,               //  Endpoint number and direction
_INT,                    //  Transfer type
0x08, 0x00,              //  Endpoint size in bytes
0x0A,                    //  Endpoint interval
0x07,                    //  Descriptor size in bytes
USB_DESCRIPTOR_ENDPOINT, // Descriptor type
_EP02_IN,                //  Endpoint number and direction
_INT,                    //  Transfer type
0x08, 0x00,              //  Endpoint size in bytes
0x0A                     //  Endpoint interval
The USB Framework defines constants that help make the code more readable and easier to maintain. For example, in Listing 1, USB_DESCRIPTOR_ENDPOINT is the constant 0x05, which the USB specification defines as the value that identifies an endpoint descriptor.

Other descriptors include the device descriptor, which contains the device’s Vendor ID (VID) and Product ID (PID) and one or more interface descriptors that specify an interface number and how many endpoints belong to the interface. The USB 2.0 specification defines the fields in the descriptors.

Bulk and Interrupt Transfers
To read and write to endpoints, program code accesses an endpoint’s buffer descriptor (BD).  To program USB Framework communications on PICs, you need to understand BDs.

A BD consists of four byte-wide registers that hold information about an endpoint’s most recent data transfer or the next data transfer. The microcontroller core and the USB module share ownership of the BD. The microcontroller core is the CPU that executes the code, or firmware, that you program into the device. The USB module, also called the serial interface engine (SIE), provides hardware support for USB communications. A USB_HANDLE is a pointer to an endpoint’s BD.

The key to accessing a BD is its UOWN bit. When UOWN = 0, the microcontroller core owns the buffer, and firmware can read and write to the BD. When UOWN = 1, the USB module owns the BD, and firmware can read UOWN but should not read or write to other locations in the BD.

This listing shows code for reading received data on a bulk OUT endpoint.

#define WINUSB_BULK_EP 1
#define WINUSB_BULK_IN_EP_SIZE 64
#define WINUSB_BULK_OUT_EP_SIZE 64
WORD bulk_bytes = 0; 
USB_HANDLE USBWinUsbBulkOutHandle;
unsigned char winusb_bulk_in_buffer[WINUSB_BULK_IN_EP_SIZE];
unsigned char winusb_bulk_out_buffer[WINUSB_BULK_OUT_EP_SIZE];
// Set up the endpoint to enable receiving data.
USBWinUsbBulkOutHandle = USBGenRead(WINUSB_BULK_EP,
     (BYTE*)&winusb_bulk_out_buffer, WINUSB_BULK_OUT_EP_SIZE);
if(!USBHandleBusy(USBWinUsbBulkOutHandle))
{
   // The microcontroller  core owns the endpoint. 
   // Check for received  data.
   bulk_bytes =  USBHandleGetLength(USBWinUsbBulkOutHandle); 
   if (bulk_bytes > 0)
   {
      // Data was received. 
      // Copy it to for  sending back to the host.
      for (count; count <=  bulk_bytes - 1; count++)
      {
         winusb_bulk_in_buffer[count] = 
         winusb_bulk_out_buffer[count];
      }
   }
}
(Remember that an OUT endpoint receives data from the host.) The USB Framework’s USBGenRead function handles many details of preparing the endpoint to receive data. The function accepts an endpoint number, a pointer to a buffer to hold received data, and the maximum number of bytes to receive. The function sets up the transfer, sets UOWN = 1 to transfer BD ownership to the USB module, and returns a pointer to the BD.

The USB module then manages the data transfer without further intervention by firmware. When the endpoint receives an OUT token packet followed by data, the USB module stores the data in the passed buffer and sets UOWN = 0 to transfer BD ownership back to the microcontroller core.

To check for received data, the Framework’s USBHandleBusy macro first checks to see if UOWN = 0. If so, the USBHandleGetLength macro returns the number of bytes received. Firmware can retrieve and use the received data in any way. Listing 2 copies the data into winusb_bulk_in_buffer for sending back to the host in a basic loopback test. After retrieving the data, firmware can call USBGenRead again to prepare the endpoint to receive new data.

This listing shows code for sending data to the host from a bulk IN endpoint:

USB_HANDLE USBWinUsbBulkInHandle;
if (!USBHandleBusy(USBWinUsbBulkInHandle)) 
{
  // The microcontroller core owns the endpoint. 
  // Prepare to send data to the host.
  USBWinUsbBulkInHandle = USBGenWrite(WINUSB_BULK_EP, 
    (BYTE*)&winusb_bulk_in_buffer, bulk_bytes);
To send data, USBHandleBusy first checks to see if UOWN = 0. If so, a call to USBGenWrite prepares to send the data.

The function accepts an endpoint number, a pointer to a buffer that holds the data to send, and the number of bytes to send. The function sets up the transfer, sets UOWN = 1 to transfer BD ownership to the USB module, and returns a pointer to the BD.

The USB module then manages the data transfer without further intervention by firmware. On receiving an IN token packet at the endpoint, the USB module sends the data and sets UOWN = 0 to pass ownership back to the microcontroller core. Firmware can then prepare for another transfer.

At the device, bulk and interrupt transfers are identical except for the endpoint type. The only difference is in scheduling by the host. So to convert listings 2 and 3 for use with interrupt transfers, just replace every instance of bulk with interrupt and set WINUSB_INTERRUPT_EP = 2 (or whatever endpoint number the interrupt endpoint addresses are using) and set WINUSB_INTERRUPT_IN_EP_SIZE and WINUSB_INTERRUPT_OUT_EP_SIZE to match the endpoint sizes in the endpoint descriptors.

Control Transfers
Because of their multiple stages, control transfers are more complicated to program than bulk and interrupt transfers. The first step in responding to a control transfer is to detect the received request. From information received in the Setup stage, firmware can learn whether the request is directed to the whole device or to a specific interface in the device.

This listing checks values received in the Setup stage to find out if the request is directed to the WinUSB interface and if the firmware has defined the request. If so, the function examines the Setup data to determine whether the host or device sends data in the Data stage and calls a function to handle the request:

// Check the Setup packet to find out if the request is  
// directed to an interface, names the WinUSB interface ID,
// and is a Vendor request.
if(SetupPkt.Recipient != RCPT_INTF) return;
if(SetupPkt.bIntfID != WINUSB_INTF_ID) return;
if(SetupPkt.RequestType != VENDOR) return;
// It’s a vendor-specific request to the WinUSB interface.
// Decode the request and call a routine to handle it.
switch(SetupPkt.bRequest)
{
  case WINUSB_REQUEST_1:
    // The Data stage is  host-to-device.
    WinusbControlWriteTransferHandler();
    break;
  case WINUSB_REQUEST_2:
    // The Data stage is  device-to-host.
    WinusbControlReadTransferHandler();            
    break;    
}   
The example handles two requests. Request 1 has a host-to-device Data stage, and request 2 has a device-to-host Data stage.

I patterned my code to handle the control-transfer requests after similar code in the USB Framework. For requests where the device sends data to the host, I used the Get_Descriptor request as a model. Code for requests where the host sends data to the device is less common, but I found an example in the Framework’s virtual COM port example in the SET_LINE_CODING request.

Installing a Device
The other side of WinUSB communications is the PC software that detects the device, assigns a driver, and exchanges data with the device.

An INF file is a text file that Windows uses to match a driver to a device. The INF file for a WinUSB device includes the VID and PID from the device descriptor and a 128-bit value called a GUID, which applications use to identify a specific WinUSB device. The GUID’s length and the method used to generate the GUID make it highly unlikely that multiple devices will have the same GUID.

You can generate a GUID in several ways. In Microsoft’s Visual Studio Standard edition and higher, select Tools > Create GUID. Other options are Microsoft’s GUID generator, guidgen.exe, or an online GUID generator, both easily found via a web search.

To customize my project’s WinUSB INF file for your device, replace the GUID and the VID and PID with your values. The GUID is in the [Version] section’s ClassGUID item:

   ClassGUID = {36FC9E60-C465-11CF-8056-444553540000}
Replace the value between the curly brackets with your GUID.

The device’s VID and PID are in the INF file’s [Manufacturer] section in this item:

   %USB\MyDevice.DeviceDesc% = USB_Install,  USB\VID_0925&PID_1456
Replace the VID (0925h) and PID (1456h) with the idVendor and idProduct values in the device descriptor for your device.

To install a WinUSB device on Windows XP, the PC must have three co-installer DLLs. Microsoft’s free Windows Driver Kit (WDK) contains the files, which you can distribute with your software. You don’t need to provide the files for Windows Vista systems.

On first attachment, Windows searches for an INF file with a matching VID and PID. If needed, point the Found New Hardware Wizard to the location of the INF file and the co-installer files.

When the device is installed and ready for use, Windows Device Manager shows the device under Universal Serial Bus Controllers. To view the Device Manager, right-click My Computer and select Manage, then Device Manager.

Writing Applications
You can access WinUSB devices with Visual Basic or Visual C#, including the free Express editions. But Microsoft’s .NET Framework doesn’t provide a class for accessing WinUSB devices. Instead, applications use Windows API functions and the WinUSB API to detect and communicate with devices.

For each API function used, Visual Basic and Visual C# applications must provide a declaration. Writing a declaration requires translating Microsoft’s declaration, written in C, to the syntax and data types supported by Visual Basic or Visual C#. To call a function, you provide parameters whose data types match those in the declaration.

API functions can find a specific device by GUID value, obtain a handle for accessing the device, learn the number and type of endpoints, configure timeouts and other behavior, and exchange data using bulk, interrupt, and control transfers. If you’re not familiar with calling API functions, the programming can seem obscure, but my example applications show the way.

With this introduction to firmware and applications, you’re ready to start experimenting with USB transfers for use in your projects.


--------------------- 
作者:lanmanck 
来源:CSDN 
原文:https://blog.csdn.net/lanmanck/article/details/8883642 
版权声明:本文为博主原创文章,转载请附上博文链接!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

winusb —— 不再为你的usb设备编写驱动 的相关文章

  • 通过 USB 模拟 UART

    有谁知道是否可以通过 USB 模拟 UART 简单串行发送和接收 这将如何实现 我在 Microchip 网站上找到了这个链接 但不是很容易找到 http www microchip com forums m522571 print asp
  • 如何在 DriverKit 中将我的 dex 与 USB 设备匹配?

    我正在编写一个驱动程序包扩展 其目标是阻止 USB 设备 例如闪存驱动器 作为起点 我选择了示例项目https developer apple com documentation driverkit communicating Betwee
  • WriteFile 返回错误代码 87

    我正在开发一个写入 HID 设备的程序 但收到错误 87 WriteFile 函数参数无效 我从 Jan Axelson 的 USB Complete 获得了这些功能 所以我不确定为什么会收到错误 我用它来查找我的设备 private vo
  • 使用 STM32 USB 设备库将闪存作为大容量存储设备

    我的板上有这个闪存IC 它连接到我的STM32F04 ARM处理器 处理器的USB端口可供用户使用 我希望我的闪存在通过 USB 连接到 PC 时被检测为存储设备 作为第一步 我在程序中将 USB 类定义为 MSC 效果很好 因为当我将主板
  • Android 版 usbmon

    我想分析我的设备的 USB 通信 SGS4 我到处都看到需要配置 usbmon 并将其编译到内核中 Afaik 这个模块没有内置在android linux系统中 我在编译内核方面没有太多经验 但如果有必要 我会这样做 您能说出这样做的步骤
  • USBInterfaceOpen总是报kIOReturnExclusiveAccess错误

    最近我遇到了这个问题 很头疼 我已经在这个问题上花了一个星期了 但仍然失败 希望您能帮我把这块石头踢开 非常感谢 我的问题 我们公司为iPhone生产USB存储设备 实际上这个存储设备中有一个SDCard 现在 我们想要开发一个 Mac 应
  • 在 Linux (libusb-1.0) 上访问 USB 设备?

    我正在编写一个小程序 使用 Linux 上的 libusb 1 0 与特定 USB HID 产品 由供应商和产品 ID 标识 进行通信 现在 我必须以 root 身份运行该程序 因为 libusb 需要对 USB 设备节点的写访问权限 有没
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 如何设置USB连接模式?

    我正在编写一个应用程序 该应用程序应该将数据转储到 SD 卡上 然后在 PC 上编写另一个应用程序 当设备连接到 PC 时 在光盘驱动器模式下 该应用程序应该读取数据 在我的 HTC Legend 上 有一个对话框可供选择 仅充电 HTC
  • USB 端口速度 Linux [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何以编程方式确定运行 Linux 内核的嵌入式设备中的 USB 端口速度 你可以阅读 sys bus usb devices usb s
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • Android USB_DEVICE_ATTACHED 持久权限

    如何让 Android 在每次重新连接 USB 设备时都不再请求权限 我想让它记住 USB 设备的 默认使用 复选标记 这样我就不必每次都向同一设备授予权限 我以编程方式检测 USB 设备 Android 手机 何时连接到我的主机设备 An
  • libusb 和轮询/选择

    我正在使用 Linux 操作系统 想知道是否有任何文件描述符可以轮询 选择 当数据等待从 USB 设备读取时会触发这些文件描述符 我也在使用 libusb 库 但尚未找到可以使用的文件描述符 Use libusb 的轮询函数 http li
  • Android 两次请求 USB 许可

    我有一个运行 Android 4 0 4 的开发板 并将其用作 USB 配件 当我关闭板上的应用程序然后通过 USB 插入 Android 手机时 板会提示 连接此 USB 设备时打开 AppName 当我触摸 确定 时 应用程序启动并再次
  • Delphi - 如何获取 USB 可移动硬盘和记忆棒的列表?

    在我的应用程序 Delphi 中 我需要列出所有 USB 存储设备 这些可以是闪存棒or外部存储驱动器 有一个Jvcl成分JvDriveCombo 并且它有DriveType属性 问题是我是否选择DriveType Fixed那么除了外部驱
  • 使用 Windows 原始访问 API 直接访问 USB 驱动器

    在USB物理驱动器的末尾 我想使用Windows原始访问API直接写入数据 我不想使用内核驱动程序来做到这一点 据我所知 出于安全原因 Windows XP SP2 或 SP3 阻止了 HDD 直接访问 我不确定 USB 驱动器是否如此 请
  • USB编程

    我想对微控制器 AVR 进行编程 以通过 USB 控制一些 LED 它只是出于对如何构建和编程 USB 设备的兴趣 有一些 AVR 微控制器支持 USB 协议 或者我可以自己在另一个微控制器中实现 USB 协议 但我想知道用什么来在计算机上
  • Android 10 中没有设备筛选器的 USB_DEVICE_ATTACHED

    我正在开发一个 Android 应用程序 它在清单中为 BroadcastReceiver 注册了四个意图过滤器 这些都是 android hardware usb action USB DEVICE ATTACHED android ha
  • 作为附件的 Android 设备

    我有 2 个 Android 设备 我想用 USB OTG 电缆连接它们 并在两个设备之间进行来回通信 据我了解 一台 Android 设备将充当 USB 主机 运行 4 4 的 Nexus 7 另一台 Android 设备将充当 USB
  • 当前有哪些 USB 设备(友好名称)连接到 PC?

    我可以获得当前连接到计算机的设备列表吗 我检查了this https stackoverflow com q 3331043 75500 and this https stackoverflow com questions 3685615

随机推荐

  • pthread 的几个结构体

    Copyright C 2002 2003 2004 2005 2006 2007 Free Software Foundation Inc This file is part of the GNU C Library Contribute
  • Google人机认证解决方法

    针对Chrome浏览器 下载gooreplacer 下载地址1 下载地址2 安装 gooreplacer crx Chrome无法从该网站添加应用 扩展程序和用户脚本 将 crx后缀改为 rar 之后开发者模式安装 重定向网址 重定向 将网
  • cad添加自己线性_创建cad线型的两种方法(线型文件和linetype) - CAD自学网

    作图过程中 我们最常见的线型是实线 虚线 点划线 有的时候这些基本线型可能满足不了你的需求 CAD也有自带的特殊线型 比如 HW 这种自带文字的线型 但你想要的确实 X 那么这便涉及到新线型的建立 建立新线型有两种方法 直接修改线型文档和通
  • CSTrack: Rethinking the competition between detection and ReID in Multi-Object Tracking

    CSTrack Rethinking the competition between detection and ReID in Multi Object Tracking 论文链接 https arxiv org abs 2010 121
  • 什么是标称属性?什么是二元属性?什么是序数属性?

    什么是属性 属性是一个数据字段 表示数据对象的一个特征 一个属性的类型由该属性可能具有的值的集合决定 标称属性 标称意味着 与名称有关 标称属性的值是一些符号或者是事物的名称 每个值代表某种类别 编码或者状态 尽管标称属性有数值 但是不能把
  • 全面剖析《自己动手写操作系统》第四章--FAT12文件系统

    一 FAT12 FAT12是DOS时代就开始使用的文件系统 File System 直到现在仍然在软盘上使用 FAT12软盘的被格式化后为 有两个磁头 每个磁头80个柱面 磁道 每个柱面有18个扇区 每个扇区512个字节空间 所以标准软盘的
  • Android Google Maps 开始

    由于工作需要 最近对Android的各大地图进行了试用 其中有Google地图 百度地图 高德地图 还有开源的OSM 在使用Google地图的时候 官网流程写的非常清楚 但是其中也遇到一些问题 这里我将我的流程写出来 方便他人 这个是官方安
  • 【C++】Boost::circular_buffer——循环缓冲区

    参考 Boost circular buffer 循环缓冲区 一 概述 Boost Circular buffer维护了一块连续内存块作为缓存区 当缓存区内的数据存满时 继续存入数据就覆盖掉旧的数据 它是一个与STL兼容的容器 类似于 st
  • golang json性能分析详解

    原文地址 https www jb51 net article 135264 htm json格式可以算我们日常最常用的序列化格式之一了 Go语言作为一个由Google开发 号称互联网的C语言的语言 自然也对JSON格式支持很好 下面这篇文
  • 基于决策树算法构建员工离职预测模型

    1 1背景介绍 每一个公司都会面临着人才管理的问题 而许多企业在发展中辛苦培养发展起来的技术人才 却不断流失 那么 如何调整公司管理制度 才能最大化保证员工的留任与能力发展 从而促进公司业务持续增长呢 本课程介绍收集了某公司人才流失各方面的
  • GLSL #define GL_SPIRV 100说明

    GLSL define GL SPIRV 100说明 版权 hankern https blog csdn net hankern article details 90690297 Standard Portable Intermediat
  • 【学习笔记】POST和GET的区别

    吃水不忘挖井人系列之 https mp weixin qq com s N2GStE2ksWUO yzIETTcQQ 在开撸之前吗 让我们先看一下标准答案长什么样子 w3school GET 对比 POST 标准答案很美好 但是在面试的时候
  • Chrome 快捷键大全

    从2013年开始使用 Chrome 浏览器 简洁好用 以前是用来专门科学上网 后来工作发现 Chrome 是开发必备 今天整理了一下Chrome的快捷键 有些挺常用 熟悉掌握快捷键 甚至不要鼠标就可以装逼了 标签和窗口 同个窗口新建标签 C
  • 【Linux】软件安装&卸载

    目录 1 notepad plus plus 2 notepadqq 3 pycharm 4 Anaconda 5 vscode 6 android ndk 7 搜狗输入法 8 卸载vmware 9 GIMP 10 git 11 llvm
  • JAVA 写Excel附件 每天定时发送邮件

    JAVA 写Excel附件 每天定时发送邮件 http hi baidu com star850323 blog item 63c5750f520e05ec37d1228d html http hi baidu com star850323
  • HBuilderX 最新安装使用教程,附详细图解,持续更新

    HBuilderX 安装使用教程 HBuilderX是HBuilder的升级版 它是是DCloud 数字天堂 推出为前端开发者服务的通用IDE 或者称为编辑器 HBuilderX的功能从下图可以直观的了解个大概 官网地址 https ask
  • Java基础总结之各个模块重要知识点

    一 对象模块 一 初始化 1 对this super 构造函数 构造代码块 静态代码块总结 this 代表当前对象 也就是所在函数所属对象的引用 this对象后面加 调用的是对象的成员变量和方法 this say this对象后面加 调用的
  • 毕业设计-基于机器视觉的甘蔗茎秆识别方法-OpenCV

    目录 前言 课题背景和意义 实现技术思路 一 总体思路 二 图像处理 三 甘蔗识别 四 结 语 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几
  • OpenCV中的图像处理

    颜色空间转换 1 基本读写操作 import cv2 import numpy as np img cv2 imread MyPic png cv2 IMREAD GRAYSCALE print img shape cv2 imwrite
  • winusb —— 不再为你的usb设备编写驱动

    blog csdn net lanmanck 曾几何时我们找工作还发现有个驱动工程师职位 月薪也不低 没接触过的人代码压根看不懂 今天可好了 如果不太追求差异化 不用驱动也能让系统与USB设备通信了 Linux就不说了 libusb很好用