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 例程调试笔记 的相关文章

  • 软件和与外部设备串行通信的波特率限制

    我使用 USB 端口作为虚拟 COM 端口运行 以使用 MATLAB 或 Visual Basic 6 实现与外部设备的串行通信 我面临波特率限制 具体取决于我用于与设备通信的软件 MATLAB 2018a 没有问题 因为它可以设置高波特率
  • 发现多个 USB-IrDA 设备,打开并连接每个设备的套接字

    对于任何优秀的套接字程序员 是否可以使用套接字枚举通过 USB 端口连接到 PC 的多个活动 IrDA 设备 如果是这样 怎么办 这确实是我的主要问题 帖子的其余部分完善了细节并描述了我所尝试的内容 我正在使用 Microsoft SDK
  • 不支持混合类型

    请看一下下面的头文件 pragma once using namespace UsbLibrary ref class MissileLauncher public MissileLauncher void private Bytes us
  • 使用 adb 连接到 LG 手机时出现问题 (Mac OS X 10.7.5)

    当我跑步时adb devices没有设备显示为已连接 我的设备是运行 4 4 2 的 LG Optimus Exceed 2 周围有很多这样的帖子 所以这就是我所做的 我正在使用电话附带的数据线 它会充电并尝试同步照片 因此这不是问题 切换
  • 如何对 USB/HID/蓝牙适配器进行逆向工程。使用什么工具?

    需要对蓝牙USB鼠标适配器进行逆向工程 并使用鼠标板测量距离 并用绘图库 http matplotlib org 我发现这些工具可以帮助完成此任务 Linux lsusb usbmon usbhid转储 rfcomm hidrd 转换 xx
  • 如何在 DriverKit 中将我的 dex 与 USB 设备匹配?

    我正在编写一个驱动程序包扩展 其目标是阻止 USB 设备 例如闪存驱动器 作为起点 我选择了示例项目https developer apple com documentation driverkit communicating Betwee
  • Windows 8.1 上的 Pyusb - 没有可用的后端 - 如何安装 libusb?

    使用 pyinstaller 3 1 python 2 7 9 和 tkinter 尝试使用 pyusb 而不是 pyserial 但没有可用的后端 调查Windows 上的 Pyusb 没有可用的后端 https stackoverflo
  • 如何枚举所有HID设备? C#

    我需要枚举连接到我的 PC 的所有 HID 设备 我尝试使用这个答案 https stackoverflow com a 3331509 902424 但它枚举了 USBHub 设备 但我在那里找不到我的 HID 设备 EDIT 我很高兴知
  • 我可以从哪里开始使用可编程硬件?

    一段时间以来 我一直渴望至少学习一点有关硬件编程的知识 并想在这里提出要求以获得一些起点 我是一位相当有成就的程序员 具有 Delphi 和 Objective c 经验 但从未听过设备端口 中断 我什至不知道术语 更不用说对硬件进行编程了
  • 如何设置USB连接模式?

    我正在编写一个应用程序 该应用程序应该将数据转储到 SD 卡上 然后在 PC 上编写另一个应用程序 当设备连接到 PC 时 在光盘驱动器模式下 该应用程序应该读取数据 在我的 HTC Legend 上 有一个对话框可供选择 仅充电 HTC
  • 如何在 C# 中从 USB 令牌读取证书

    我有一个 USB 令牌 其中包含一个加密证书 该证书具有公钥和私钥 现在我想用 C 创建一个应用程序 通过它我可以找到可访问的证书信息 当我插入 USB 令牌时 它会被检测到 但计算机部分上没有显示任何驱动器 就像闪存驱动器一样 如何从 U
  • 时间:2019-03-17 标签:c#usbdecision

    我们当前的应用程序中有几个进程 一个进程处理 USB 加载程序的检测和删除 处理检测和删除的代码如下 protected override void WndProc ref Message m switch m Msg case Win32
  • Swift 上的 USB 连接委托

    Swift 中是否有一个代表可以让我的班级知道何时通过计算机的 USB 插入新设备 我想知道我的程序何时可以使用新设备 Eric Aya 的答案已经相当不错了 但这里有一个 Swift 3 的改编 我把大部分丑陋的东西包裹在一个USBWat
  • 虚拟USB设备的安装与仿真

    我已经读过创建虚拟USB设备 https stackoverflow com questions 5016363 creating a virtual usb device and 虚拟USB设备 https stackoverflow c
  • BeagleBone Black 如何用作大容量存储设备?

    是否可以使用 BB 作为大容量存储设备 我希望将其连接到可以从 USB 连接 例如 USB 闪存驱动器 读取文件的音频播放器并充当包含一个特定文件夹的数据存储设备 及其子文件夹 从文件系统 如果可能 在连接到开发板的闪存驱动器上 正如设备规
  • 如何在Android上读取/写入外部USB存储设备?

    我目前正在制作一个应用程序 需要能够读取和写入通过 USB OTG 适配器连接的 USB 闪存驱动器 有没有一种简单的方法可以通过标准访问此存储Java io File蜜蜂 该应用程序只能在运行 Android 4 2 2 的已 root
  • 如何在 C# 中知道 PID 和 VID 来发现虚拟 COM 端口名称

    如果我知道 PID 和 VID 我会尝试找到查找 COM 端口名称的正确方法 到目前为止 我写了解决方法 但我不相信没有更优雅和正确的方法 顺便说一句 我知道我可以使用 REGEX 编写此代码只是为了测试解决方法 我知道还有很大的改进空间
  • 使用 Intel xHC 执行启用插槽命令后,如何确定 USB 设备连接在哪个根集线器端口上?

    我正在一个使用 UEFI 启动的小型业余爱好操作系统中为英特尔 xHC 编写一个小型驱动程序 重置所有根集线器端口后 我收到 2 个端口状态更改事件 这是因为我要求 QEMU 在命令行中模拟 USB 键盘和 USB 鼠标 每个设备的一个端口
  • 在 Windows 中以编程方式重新启动 USB 设备

    我正在开发的一些软件需要 USB 设备 我作为串行端口与 USB 转 UART 桥进行交互 有时 计算机从休眠状态重新启动后 无法检测到该设备 并且我无法再通过串行端口写入或读取该设备 需要对设备进行读 写访问 我不能依赖用户采取任何操作
  • Android USB Host 模式和 Accessory 模式

    我正在尝试学习 Android USB 主机 配件连接 我读到 Android 设备可以充当 USB 主机或 USB 配件 因此 我创建了两个项目 其中一个是 USB 主机项目 另一个是 USB 附件项目 我将这些项目安装到两个不同的 An

随机推荐

  • 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盘 把程序下载到开发板后