STM32 USB Mass Storage 例程调试笔记

2023-11-17

一、问题起因

     近来有几个客户反映STM3210E的开发板的USB Mass Storage 例程有点问题,组长安排我来调试。Mass Storage例程在PC上实现两个U盘,一个是SD盘,一个是NAND Flash盘,把程序下载到开发板后,PC上能够检测到NAND Flash盘和SD盘,却提示磁盘要格式化,按照提示操作,格式化不成功,可用磁盘空间和已用磁盘空间都为0。

调试前的准备

二、调试前准备

  调试之前花了三天的时间,大致的看了一下USB的框架,后来才发现,没什么必要,不过多学点知识总是好的。

      1.USB只提供一个数据通道,USB总线并不知道设备具体是怎么操作,有什么状态,USB设备的状态是设备自己来决定的,这就是USB描述符的功能了。描述符中记录了设备的类型、厂商、产品ID、端点信息等。描述符主要要:设备描述符、接口描述符、端点描述符、字符串描述符等。设备描述符记录了该设备使用的USB版本号、厂商ID、产品ID、可能的配置数等与设备相关的信息;配置描述符记录了配置包含的接口数、供电方式、是否支持远程唤醒等;接口描述符记录了接口的端点数、接口使用的类、协议等;端点描述符记录了端点号、数据传输的方向、传输类型、最大包长度等;字符串描述符记录了一些文字信息,方便客户理解。

      USB协议中规定了四种传输类型:批量传输、同步传输、中断传输和控制传输

      MassStorage例程中只用到了批量传输和控制传输,所以这里只介绍这两种方式

      (1)批量传输使用bulk transaction传输数据,主要应用在数据大量数据传输和接受数据上同时又没有带宽和间隔时间要求的情况下。特点:要求保证传输。打印机、大容量存储设备和扫描仪属于这种类型这种类型的设备。适合于传输非常慢和大量被延迟的传输,可以等到所有其它类型的数据的传输完成之后再传输和接收数据。

       一次批量事物有三个阶段:令牌包阶段、数据包阶段和握手包阶段。

  第一阶段 令牌包阶段
 Host端发出一个Bulk的令牌请求、令牌包中包含了设备地址、端点号。
 如果令牌是IN请求 ,则是从Device到Host的请求;
 如果令牌是OUT请求,则是从Host到Device端的请求。
  第二阶段 数据包阶段
 根据先前请求的令牌的类型,数据传输有可能是IN方向,也有可能是OUT方向。传输数据的时候用DATA0和DATA1令牌携带着数据交替传送。
 数据传输格式DATA1和DATA0,这两个是重复数据,确保在1数据丢失时0可以补上,不至于数据丢失。
 第三阶段 握手包阶段
 如果数据是IN 方向,握手信号应该是Host端发出;
 如果数据是OUT方向,握手信号应该是Device端发出。
 握手信号可以为ACK, 表示正常响应,
 NAK, 表示没有正确传送。
 STALL,表示出现主机不可预知的错误。

       (2)控制传输

  作用:USB系统用来主要进行查询配置和给USB设备发送通用的命令,它要保证数据传输过程的数据完整性。设备枚举过程中的各种设备描述符的获取以及设置地址、设置配置都是通过控制传输来实现的。特点:控制传输是双向传输,数据量通常较小;数据传送是无损性的。
 控制传输也分为三个阶段,即令牌阶段、数据传送阶段、握手阶段

     2.USB协议中规定了一类大容量存储设备 mass storage device,包括u盘、移动硬盘等。大容量存储设备接口类代码(bInterfaceClass)为0x08,U盘接口子类代码(bInterfaceSubClass)使用0x06,表示使用SCSI透明指令集.协议代码(bInterfaceProtocol)有三种:0x01、0x00和0x50,前面两种需要使用中断传输,这里使用的是最后一种协议,即协议使用仅批量传输(bulk only transport)。

  仅批量传输协议中规定了两个特殊的类请求:bulk-only Mass Storage Reset 和Get Max LUN,前者是复位到命令状态的请求,后者是获取最大逻辑单元的请求。
      1.Get Max LUN的格式如下图

usb协议中采用的是小端格式,这一点要格外注意,比如ASCII 0x55、0x53,用小端格式表示就是0x5355

bmRequestType为0xa1,表示它是发送到接口的类输入请求,bRequest为0xfe,wIndex为请求的接口号,传输的数据长度为1字节,设备将在数据过程返回1字节的数据,表示设备有多少个逻辑单元,0表示1个逻辑单元,1表示有两个。

  2.bulk-only Mass Storage Reset 的格式如下图

 

bulk-only Mass Storage Reset请求是通知设备接下来的批量端点输出数据为命令快封装包CBW(Command Block Wrapper),在这个请求中,仅需要设置一下状态,说明接下来的数据是CBW,然后返回一个长度为0的状态数据包。

  3.仅批量传输的的数据流

  类请求完成后,就进入了数据传输过程,在仅批量数据传输协议中规定,数据传输分为三个阶段:命令阶段、数据阶段和状态阶段。命令阶段是由主机通过批量端点发送一个CBW(命令封装包)的结构,在CBW中定义了要操作的命令以及传输数据的方向和数量,数据阶段的传输方向由命令阶段决定,而状态阶段则总是由设备返回该命令完成的状态。

 

CBW的结构如下图

 

 

官方文档对这些字段的介绍:

dCBWSignature:
Signature that helps identify this data packet as a CBW. The signature field shall contain the value
43425355h (little endian), indicating a CBW.
dCBWTag:
A Command Block Tag sent by the host. The device shall echo the contents of this field back to the
host in the dCSWTag field of the associated CSW. The dCSWTag positively associates a CSW with the corresponding CBW.
dCBWDataTransferLength:
The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore
bmCBWFlags:
The bits of this field are defined as follows:
Bit 7 Direction - the device shall ignore this bit if the dCBWDataTransferLength field is
zero, otherwise:
0 = Data-Out from host to the device,
1 = Data-In from the device to the host.
Bit 6 Obsolete. The host shall set this bit to zero.
Bits 5..0 Reserved - the host shall set these bits to zero.
bCBWLUN:
The device Logical Unit Number (LUN) to which the command block is being sent. For devices that
support multiple LUNs, the host shall place into this field the LUN to which this command block is
addressed. Otherwise, the host shall set this field to zero.
bCBWCBLength:
The valid length of the CBWCB in bytes. This defines the valid length of the command block. The
only legal values are 1 through 16 (01h through 10h). All other values are reserved.
CBWCB:
The command block to be executed by the device. The device shall interpret the first bCBWCBLength
bytes in this field as a command block as defined by the command set identified by bInterfaceSubClass .
If the command set supported by the device uses command blocks of fewer than 16 (10h) bytes in
length, the significant bytes shall be transferred first, beginning with the byte at offset 15 (Fh). The
device shall ignore the content of the CBWCB field past the byte at offset (15 + bCBWCBLength - 1).

  命令封装包CSW

 

dCSWSignature:
Signature that helps identify this data packet as a CSW. The signature field shall contain the value
53425355h (little endian), indicating CSW.
dCSWTag:
The device shall set this field to the value received in the dCBWTag of the associated CBW.
bCSWStatus:
bCSWStatus indicates the success or failure of the command. The device shall set this byte to zero if
the command completed successfully. A non-zero value shall indicate a failure during command
execution according to the following table:
Value Description
00h Command Passed ("good status")
01h Command Failed
02h Phase Error
03h and 04h Reserved (Obsolete)
05h to FFh Reserved

  定义一个缓冲区用来接收命令块封装包CBW,然后进入到数据处理阶段,在数据处理中,对CBW进行解码,返回或者接收响应的数据。数据发送或者接收完毕后,进入到状态阶段,返回命令执行的情况,然后再次进入命令阶段,等待主机发送CBW包。

3.SCSI命令集

小型计算机系统接口(英语:Small Computer System Interface; 简写:SCSI),一种用于计算机和智能设备之间(硬盘、软驱、光驱、打印机、扫描仪等)系统级接口的独立处理器标准。 SCSI是一种智能的通用接口标准。它是各种计算机与外部设备之间的接口标准。

在U盘中经常用到的命令有:INQUIRY、READ CAPACITY 、READ(10)、WRITE(10)命令等。

INQUIRY命令请求查询目标设备的一些基本信息,操作码为0x12,。

READ FORMAT CAPACITIES命令可以让主机读取设备各种可能的格式化容量的列表,如果设备中没有存储设备,则设备返回最大能够支持的格式化容量。

读容量命令READ CAPACITY可以让主机读取到当前存储媒介的容量,操作代码为0x25,READ CAPACITY读取的是实际的磁盘容量。

主机使用READ(10)命令来读取实际磁盘的数据,使用WRITE(10)来往设备中写入实际的磁盘数据。

4.STM32 相关知识

  STM32提供的有USB全速设备接口,支持USB全速总线、USB挂起/恢复操作,可以停止设备时钟实现低功耗。USB和CAN共用一个专用的512字节的SRAM存储器用于数据的发送和接收,不能同时使用USB和CAN总线。

PC主机和微控制器之间的数据传输是通过共享这一专用的数据缓冲区来完成的,数据缓冲区能被USB外设直接访问。这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用512 字节缓冲区,最多可用于16个单向或8 个双向端点。USB模块同PC主机通信,根据USB规范实现令牌分组的检测,数据发送/ 接收的处理,和握手分组的处理。整个传输的格式由硬件完成,其中包括CRC的生成和校验。 每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数。 当USB模块识别出一个有效的功能/ 端点的令牌分组时,( 如果需要传输数据并且端点已配置) 随之发生相关的数据传输。USB模块通过一个内部的16位寄存器实现端口与专用缓冲区的数据交换。在所有的数据传输完成后,如果需要,则根据传输的方向,发送或接收适当的握手分组。 在数据传输结束时,USB模块将触发与端点相关的中断,通过读状态寄存器和/ 或者利用不同的中断处理程序,微控制器可以确定

● 哪个端点需要得到服务

● 产生如位填充、格式、CRC、协议、缺失ACK、缓冲区溢出/ 缓冲区未满等错误时,正在进行的是哪种类型的传输。

USB模块对同步传输和高吞吐量的批量传输提供了特殊的双缓冲区机制,在微控制器使用一个缓冲区的时候,该机制保证了USB外设总是可以使用另一个缓冲区。 在任何不需要使用USB模块的时候,通过写控制寄存器总可以使USB模块置于低功耗模式(SUSPEND模式) 。在这种模式下,不产生任何静态电流消耗,同时USB时钟也会减慢或停止。通过对USB线上数据传输的检测,可以在低功耗模式下唤醒USB模块。也可以将一特定的中断输入源直接连接到唤醒引脚上,以使系统能立即恢复正常的时钟系统,并支持直接启动或停止时钟系统。

三、例程分析

  1.首先进行系统配置,如时钟、USB、NAND FLASH、SD卡的初始化等

      2.配置中断,本例程中使用了三个中断通道

  USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等)。固件在处理中断前应当首先确定中断源。中断处理函数为:USB_Istr ,进入中断处理函数后会进行usb复位操作或者usb数据传输(调用CTR_LP函数)。

  USB高优先级中断(通道19):仅能由同步和双缓冲批量传输的正确传输事件触发,目的是保证最大的传输速率。它的中断处理函数是CTR_HP。

  说明:函数CTR_HP和CTR_LP最终都会调用Mass_Storage_In(端点1)和Mass_Storage_Out(端点2)两个函数来和PC端的USB HOST 通信

     3.SD的I/O 中断(通道49) 

  为了让SD I/O卡能够中断多媒体卡/SD 模块,在SD接口上有一个具有中断功能的引脚——第8脚,在4 位SD模式下这个脚是SDIO_D1,卡用它向多媒体卡/SD 模块提出中断申请。对于每一个卡或卡内的功能,中断功能是可选的。SD I/O的中断是电平有效,即在被识别并得到多媒体卡/SD 模块的响应之前,中断信号线必须保持有效电平( 低) ,在中断过程结束后保持无效电平(高)。在多媒体卡/SD 模块服务了中断请求后,通过一个I/O 写操作,写入适当的位到SD I/O卡的内部寄存器,即可清除中断状态位。所有SD I/O卡的中断输出是低电平有效,多媒体卡/SD 模块在所有数据线(SDIO/D[3:0])上提供上拉电阻。多媒体卡/SD 模块在中断阶段对第8 脚(SDIO_D/IRQ) 采样并进行中断检测,其它时间该信号线上的数值将被忽略。

  4.进入while循环,等待中断的发生

      当USB主机检测到USB设备插入后,进入中断,先对设备进行复位,USB在复位后其地址为0,主机通过地址0和刚插入的设备通信,建立控制传输,将设备描述符发送给主机。复位的操作在MASS_Reset()函数中。

      主机对设备又一次复位,这时就进入了设置地址阶段,这也是一个控制传输的过程,主机会分配一个唯一的地址给刚接入的设备。

      主机再次获取设备描述符。

      主机获取配置描述符,主机获取字符串描述符。

主机发送Get Max LUN请求,获取最大逻辑单元。

主机通过批量端点发送CBW包,在CBW中定义了要操作的命令以及传输数据的方向和数量,返回该命令完成的状态,即由设备返回CSW包,端点2用于输出,端点1用于输入数据至主机。CBW的标志是0x55,0x53,0x42,0x43。

在USB主机和设备的通信过程中,数据会先被放到一个大小为512字节的专用SRAM缓冲区里面,然后再传输到主机或者USB设备。

      USB主机通过发送 SCSI Read10 Command和SCSI Write10 Command命令来对从机进行读写,分别调用的是SCSI_Read10_Cmd和SCSI_Write10_Cmd函数,最终调用MAL_Read和MAL_Write,在这两个函数中判断是对SD卡还是NANDFLASH进行读写。具体的过程可以参考代码。

四、例程问题现象和解决方法

1.NAND FLASH盘可以被识别,格式化失败。既然NAND FLASH盘可以被识别,那就表明USB的控制传输没出现问题,USB批量传输出问题了,而且最可能的是NAND FLASH的驱动有问题,仔细看完代码,发现在建立坏块表,对Spare 区域进行读操作中,对NAND FLASH 有一个NAND_CMD_AREA_TRUE1命令操作,查看代码,

#define NAND_CMD_AREA_TRUE1        ((u8)0x30)

 而30H这个命令在数据手册中找不到,在程序中把这行注释掉,编译代码,下载,还是无法格式化,最后研究了一下手册,在注释代码的这一行加上5微秒的延迟,然后编译,下载,NAND FLASH可移动磁盘可以正常的读写了。

2.SD盘也能被识别,不能格式化。开始用的是2G的SD卡,后来尝试1G和512M的,它们都能用,也就是说,这个SD卡驱动只识别1G和512M的SD卡。

在代码中添加调试信息,结果是写入的块长度出错。通过对读SD卡信息了解到,2G的SD卡,块大小是1024字节,其它的卡都是512字节。我在SDIO例程中设置块大小为1024字节,读写出错,设置512字节,居然是正确的。

USB MassStorage例程中是首先从SD卡中读取SD卡块大小的值,按照这个值来读写SD卡,而实际上2G的SD卡只能按照512字节来读写。所以在读取块大小的值后,把块的大小除以2,块数目乘以2,卡的总容量不变,程序运行后,一切正常了。

USB Mass Storage例程下载地址:http://files.cnblogs.com/irwin0112/USB_MassStorage.zip

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

STM32 USB Mass Storage 例程调试笔记 的相关文章

  • 检测 Android 上的 USB 网络共享

    有没有什么方法可以 以编程方式 在您的活动 应用程序中知道用户已在其手机上启用 USB 网络共享 您还可以使用反射来访问用于设置 USB 网络共享的隐藏功能 这是我的代码 ConnectivityManager cm Connectivit
  • 如何检查 Android 上是否启用 USB 连接模式?

    我在 Android 市场上有一个应用程序 用户经常将他们的设备连接到计算机以将音乐添加到应用程序文件夹中 我在说明中特别指出 当启用 USB 连接模式时 Android 应用程序无法与 SD 卡通信 显然这还不够愚蠢的证据 有没有办法在j
  • 如何阻止 Linux 初始化 USB HID 设备

    我有一个 USB HID 设备 可以在两种不同的模式下工作 模式的选择基于发送给它的 USB 枚举 初始化数据包的顺序 我使用的是运行 Raspbian 的 Raspberry Pi 3 但是如果我为桌面 Ubuntu 发行版编译代码 我也
  • 如何在 OSX Catalina (10.15) 中使用 Wireshark 捕获 USB 流量

    我正在尝试让 Wireshark USB 捕获工作 显然 Catalina 之前的技巧就是调出界面 以便 Wireshark 可以看到它 https forums developer apple com thread 95380 https
  • Android 到 PC USB 读/写

    我在 PC 上有一个程序 从 USB 接收字符串输入 旧程序 我有一个 Android 4 X 平板电脑 需要向在 PC 上运行的程序提供 USB 上的字符串输入 当我在 Android 上使用示例代码时 以下代码给出了空的哈希图 PC 在
  • 在 Mac 上通过 USB 访问 iOS 设备

    我有一个移动应用程序需要将文件传输到数据库 然而 其规范之一是 如果用户没有设置无线网络 则应该能够将其插入 Mac 并将文件传输到数据库 然而 我遇到的问题是如何将上述文件从 iPad 上通过 USB 传输到计算机上 上周我研究了各种解决
  • 如何在PyUsb中绑定/取消绑定USB设备?

    我需要在 python 脚本上打开 关闭多个 USB 设备 我可以使用 PyUsb 绑定和取消绑定 USB 设备吗 我可以使用 shell 命令来做到这一点 关闭电源 echo device nuber gt sys bus usb dri
  • Silverlight 能否访问可访问 USB 端口的 .Net 库?

    我们有一个 Net 库 可以通过 USB 端口访问一些自定义硬件 我读到 Silverlight 包含 Net 运行时的子集 所以 我的问题是 这个子集足以让 Net 库运行吗 不可以 您不能使用从 Silverlight 内部访问 USB
  • WriteFile 返回错误代码 87

    我正在开发一个写入 HID 设备的程序 但收到错误 87 WriteFile 函数参数无效 我从 Jan Axelson 的 USB Complete 获得了这些功能 所以我不确定为什么会收到错误 我用它来查找我的设备 private vo
  • Windows 8.1 上的 Pyusb - 没有可用的后端 - 如何安装 libusb?

    使用 pyinstaller 3 1 python 2 7 9 和 tkinter 尝试使用 pyusb 而不是 pyserial 但没有可用的后端 调查Windows 上的 Pyusb 没有可用的后端 https stackoverflo
  • 从网络浏览器中检测和访问 USB 设备 - 即使用插件

    是否可以通过插件 activeX Java 或 Flex 编写一个能够检测从 USB 设备通道读取数据流的浏览器插件 我做了一些研究 但没有找到答案 http support microsoft com kb 832678 http sup
  • 适用于 Android 的 USB 主机

    I am trying to communicate with my freeduino board which is similar to arduino uno via usb through android device nexus
  • Android:如何以编程方式连接/断开 OTG

    我想在我的 Android 设备中以编程方式连接和断开 USB OTG 笔式驱动器 硬盘驱动器等 对于USB 我使用以下路径在连接到PC时绑定 取消绑定USB sys bus usb drivers usb bind or unbind 我
  • 如何在 C# 中从 USB 令牌读取证书

    我有一个 USB 令牌 其中包含一个加密证书 该证书具有公钥和私钥 现在我想用 C 创建一个应用程序 通过它我可以找到可访问的证书信息 当我插入 USB 令牌时 它会被检测到 但计算机部分上没有显示任何驱动器 就像闪存驱动器一样 如何从 U
  • LibUsb 声明接口访问被拒绝 Java

    我希望能够从 USB 计步器读取数据 我正在 Java 中尝试此操作 并且使用 LibUsb 和 Usb4Java 库 我似乎无法认领 USB 管道或类似的东西 我正在使用的代码 final Context context new Cont
  • Android USB_DEVICE_ATTACHED 持久权限

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

    我有一个运行 Android 4 0 4 的开发板 并将其用作 USB 配件 当我关闭板上的应用程序然后通过 USB 插入 Android 手机时 板会提示 连接此 USB 设备时打开 AppName 当我触摸 确定 时 应用程序启动并再次
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • IntelliJ IDEA 中的 Android 开发导致电脑死机

    我使用 IntelliJ IDEA 10 5 进行 Android 开发 并使用最新的 Google USB 驱动程序 版本 4 进行调试 在 IntelliJ IDEA 中开发一段时间后 当通过 USB 连接 Android 设备 Nex
  • 虚拟USB设备的安装与仿真

    我已经读过创建虚拟USB设备 https stackoverflow com questions 5016363 creating a virtual usb device and 虚拟USB设备 https stackoverflow c

随机推荐

  • java socket——心跳包

    首先先说说心跳包在socket连接中的意义 通过socket连接的双方为了保证在一段时间未发消息不被防火墙断开连接或者使对方及时知道自己是否已经断线而定期给对方发送的某些特殊标识字符 这个字符可以根据双方自定义 没有实际的通讯意义 而定制的
  • 前奏

    上期我们一起学了CNN中四种常用的卷积操作 如下链接 CNN中常用的四种卷积详解 从这期开始 我们开始步入目标检测领域的大门 开始逐步一层一层的揭开目标检测的面纱 路要一步一步的走 字得一个一个的码 步子不能跨太大 太大容易那个啥 字也不能
  • Appnium下载及安装

    Appnium官方访问地址为 http appium io 可访问查看关于Appnium的相关资料 根据官网提供的安装步骤 gt brew install node get node js gt npm install g appium g
  • 预览图片pdf等文件

    文件下载直接返回流即可 但是如果返回图片pdf等 不想下载只想预览下 即可以设置不同的头 返回不同的预览流 文件预览 param bucketName 桶名称 param request 请求 param response 请求响应 pub
  • 2023华为OD机试真题Java实现【篮球比赛/深度优先搜索】【2023.Q2】

    题目内容 在篮球比赛中 每个队员的实力不通 队伍的实力计算方式为所有球员战斗力之和为该队伍的总体战斗力 篮球队员的总人数为10 他们分成两个队伍 教练希望2个队伍的战斗力差值能够尽可能的小 请你帮他实现目标 给出10个球员的战斗力 如果你是
  • 【华为OD机试】导师请吃火锅【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 入职后 导师会请你吃饭 你选择了火锅 火锅里会在不同时间下很多菜 不同食材要煮不同的时间 才能变得刚好合适 你希望吃到最多的刚好合适的菜 但你的手速不够快 用m代表手
  • uniapp项目中防止用户重复提交

    1 在根目录下新建common文件并创建common js文件 代码直接复制粘贴即可 防止处理多次点击 function noMultipleClicks methods info methods是需要点击后需要执行的函数 info是点击需
  • CE认证EMC指令测试项及测试内容(智能开关)

    目录 发射 EMISSiON 1 交流电源端口传导发射Conducted Emissions from the AC mains power ports 2 辐射发射Radiated Emissions 3 谐波电流Harmonic Cur
  • SpringBoot项目中常见的参数传输方式

    传参方式 例子 请求方式 获取参数方式 说明 query 传统方式 getUser id 1 get和post 选用 RequestParam PathParam 路径传参 使用实体类 path REST风格 user 1 get和post
  • 【Redis】分布式锁

    Redis分布式锁 问题描述 随着业务发展的需要 原单体单机部署的系统被演化成分布式集群系统后 由于分布式系统多线程 多进程并且分布在不同机器上 这将使原单机部署情况下的并发控制锁策略失效 单纯的Java API并不能提供分布式锁的能力 为
  • Matlab多维数组漫谈教程

    MATLAB是一种强大的科学计算和数据分析工具 它支持多维数组操作 这使得它在处理复杂数据和矩阵计算方面非常出色 本文将详细介绍MATLAB中的多维数组以及如何使用它们进行各种操作 首先 我们需要了解多维数组的概念 多维数组是一个由元素组成
  • [从零开始学DeepFaceLab-2]: 使用-Windows可执行工具的下载、解压

    目录 前言 第1步 登录github官网 第2步 找到可执行程序下载入口
  • ElasticSearch安装在Windows上详细教程

    ElasticSearchWindows安装教程 Download Elasticsearch Elastic 解压ElasticSearch 打开elasticsearch 6 4 2 bin调用黑窗口 输入elasticsearch b
  • 给定一个字符串 s ,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。

    class Solution public vector
  • 2023第五届CCPC河南省赛

    2023第五届CCPC河南省赛经历和题解 题目链接 榜单 经历 算法生涯第一场比赛正好是三年以来第一次线下省赛 因为学校不报销 QAQ 我和我们班两个同学三个大一一队跟着学长学姐一队一起自费趁着周六日假期从洛阳跑到郑州打比赛 周六晚上六点十
  • android项目迁移到androidX:类映射(android.support.v4*)

    支持库类 AndroidX 类 android support v4 accessibilityservice AccessibilityServiceInfoCompat androidx core accessibilityservic
  • 开源库uthash第三弹utstack.h

    文章目录 一 简介 1 1 介绍 1 2 源码获取 二 使用方法 2 1 栈头声明 2 2 栈操作 2 3 一个简单的实例 2 4 其他宏 一 简介 1 1 介绍 utstack h中包含了一组动态stack宏 使用起来非常简单 只需要将u
  • BUUCTF 之 [极客大挑战 2019] Havefun(GET 传参)

    BUUCTF 之 极客大挑战 2019 Havefun GET 传参 相关 题解 相关 项目 内容 难度 简单 类型 WEB 靶场 BUUCTF 坐标 Havefun 题解 启动靶机后 映入眼帘的是一只猫 网站首页没有按钮 提示信息等等 遇
  • $(window).load(function() {})和$(document).ready(function(){})的区别

    在我以前的开发中 一般用到javascript 我都是采用jquery的模式 也就是大多数时候 第一行写的是 document ready function 这个时候 不一定要等所有的js和图片加载完毕 就可以执行一些方法 不过有些时候 必
  • STM32 USB Mass Storage 例程调试笔记

    一 问题起因 近来有几个客户反映STM3210E的开发板的USB Mass Storage 例程有点问题 组长安排我来调试 Mass Storage例程在PC上实现两个U盘 一个是SD盘 一个是NAND Flash盘 把程序下载到开发板后