USB Mass Storage学习笔记-STM32+FLASH实现U盘
用STM32CubeMX快速生成一个U盘模拟程序
用STM32CubeMX快速生成一个U盘模拟程序前提:默认已经装好MDK V5和STM32CubeMX。
Step1.新建工程选择芯片型号。
Step2.配置时钟引脚。
Step3.配置USB引脚。
Step4.配置USB设备类。
Step5.配置时钟树,USB模块输入要求为48MHz时钟。
Step6.配置USB设备描述符。
此处默认即可。
Step7.生成MDK工程及代码。
特别注意,一定要加大堆栈大小,否则USB设备无法启动。
Step8.打开MDK工程。
Step9.选择芯片型号。
Step10.编译工程。
Step11.编译下载运行。
运行程序后,通过USB线链接电脑,将出现如下提示信息。
查看“设备管理器”,可以看到USB MSC设备。
“我的电脑”界面下可以可移动磁盘。
但是,双击无法打开,出现格式化提示。
进入格式化对话框,可以看到磁盘总容量是32MB。
实际上无法进行格式化操作。
Step12.修改代码。
只需修改usbd_storage_if.c文件。
将60行的宏定义改为200,即将要模拟的U盘有200个扇区。
61行是扇区大小定义512。
用60,61行的宏,定义一个二维数组,这个数组就是将要模拟的U盘的实际存储空间。
因此该U盘总容量为100KB。
然后为两个函数添加功能,一个是读块,一个是写块。
他们是对msc_data数组的读写操作。
操作规则就和SD卡一样,按照512字节为一个扇区进行整体的读/写。
Step13.再次编译下载运行。
运行程序后,通过USB线链接电脑,不再像前一次一样出现很多提示信息,只是在任务栏最右边出现U盘插入的图标。
在“我的电脑”界面下可以看到“可移动磁盘”。
双击无法打开,提示进行格式化,点“是”进入格式化窗口。
可以看到U盘容量为100KB。
勾选“快速格式化”,点击“格式化”按钮。
不支持普通格式化,我也没弄清楚原因。
格式化完成后,就可以双击打开这个“U盘”了,这是一个可以进行读写的U盘。
将这个U盘弹出,然后断开USB链接线,然后再重新连接,就可以被360 U盘助手发现了。
STM32USB学习笔记
基于STM32的USB学习总结第一章基础之简析USB协议1、USB包的分类USB包主要有以下几种:令牌包、数据包、握手包,其他包暂时用不到先不提。
1.1、令牌包顾名思义,这个类型的包是用来发布命令的,我们知道USB协议是典型的主从结构的协议,主设备就是用来发送令牌包,从设备是接收令牌后执行相应的命令的设备。
而令牌包下面又分了几种类型的令牌,他们分别带表了不同命令。
令牌包可分为SETUP包、IN包、OUT包、SOF包,其中SETUP包、IN包、OUT包结构构如下:其中同步域是用来同步主机和从机的,8位PID号分别代表了不同的包,其中低4位代表PID,高4位是用来取反的。
USB协议也是靠不同的PID来区别不同类型的包的。
我们先列下令牌包的几种包的PID以及各1.2、数据包用来代表这个包是用来装载用户传输的数据,包的长度大小和设备的属性有关,第一个数据包总是跟在令牌的后面,有了令牌包才会有数据包。
DAET0和DATE1都是用来传送数据,那为什么要2个不同的包呢?因为在USB协议里,每次成功传送一次数据后,都会进行数据类型的反转,即从DATE0到DATE1或者DATE1到DATE0。
举例说明:如果传送不成功主句不会收到ACK,那么他就会以原来的数据包PID进行发送数据,这样从机接收到新的PID和自己的是一样的,会保存数据;另外一种情况是,从机保存了数据并进行了数据类型反转,然后向主机发送了ACK,但主机没收到,主机也会按原来的PID数据包从新发送,当从机接收到了数据包后发现与将要接收的PID类型不一样,则不会保存数据。
1.3、握手包这种包是用来进行确认消息是否有效或者消息是否发送成功的,握手包可以分为ACK,NAK,STALL和ACK,NAK,STALL和NYET包的PID如下表:2、USB 事务USB 事务也可以称为USB 事件,每次事件的发生必定会存在3种包:令牌包---用来发送指令,数据包---用来传送数据,握手包-----用来确认操作。
如何实现Linux下的U盘(USB Mass Storage)驱动 v0.4
如何实现Linux下的U盘(USB Mass Storage)驱动How to Write Linux USB MSC (Mass Storage Class) Driver版本: 0.4作者: crifan联系方式:green-waste (at) 版本历史目录1正文之前 (6)1.1本文目的 (6)1.2阅读此文所需要的前提知识 (7)1.3声明 (7)2USB基本知识 (8)2.1USB的硬件 (8)2.2USB相关的协议 (8)2.3USB相关的软件实现 (8)3USB Mass Storage大容量存储的基本知识 (9)3.1USB Mass Storage相关的协议 (13)3.1.1USB Mass Storage相关协议简介 (14)3.1.1.1USB MSC Control/Bulk/Interrupt (CBI) Transport (14)3.1.1.2USB MSC Bulk-Only (BBB) Transport (15)3.1.1.2.1为何USB MSC中Bulk-only Transport被叫做 BBB (15)3.1.1.2.2为何已经有了CBI,又再弄出个BBB (15)3.1.1.3USB MSC UFI Command Specification (16)3.1.1.4USB MSC Bootability Specification (16)3.1.1.5USB MSC Compliance Test Specification (17)3.1.1.6USB Lockable Storage Devices Feature Specification (17)3.1.1.7USB MSC USB Attached SCSI Protocol (UASP) (17)3.1.1.7.1已有SCSI协议,为何还要再弄一个UASP (17)3.1.2USB MSC的各个协议之间关系总结 (19)3.1.3U盘与USB中的Class,Subclass和Protocol的对应关系 (20)3.1.3.1bInterfaceClass=0x08=Mass Storage (21)3.1.3.2bInterfaceSubClass=0x06=SCSI Transparent (21)3.1.3.3bInterfaceProtocol=0x50=Bulk Only Transport (21)3.2USB Mass Storage相关的软件实现 (22)4实现U盘驱动的整个流程是什么样的 (23)5Linux系统下,USB驱动的框架已经做了哪些事情 (24)6Linux下实现U盘驱动,自己需要做哪些事情以及如何做 (25)7引用文章 (26)图表图表 1 U盘 (6)图表 2 USB Mass Storage Framework (9)图表 3 PC和U盘 (10)图表 4 PC和U盘的芯片内部结构 (10)图表 5 PC和U盘的内部逻辑框图 (11)图表 6 PC和USB MSC设备 (12)图表 7 USB MSC的分类 (12)图表 8 USB Storage Class Protocol Relation (19)图表 9 SubClass Codes Mapped to Command Block Specifications (21)图表 10 Mass Storage Transport Protocol (21)图表 11 USB数据流向图 (23)缩写1 正文之前1.1 本文目的关于U盘,估计大家都用过。
基于STM32单片机和SDRAM的模拟U盘设计
【 关键词 】 S T M3 2 F 4 2 9 ;S D R A M;模拟u盘
参考文献 【 1 】 张晓辉, 马殿 光, 徐 青菁, 唐厚君 . 数控切割机调 高器系统 的
图3 US B接口电路
图1系统结构 图
2 . 1 S DR A M接 口电 路 虚拟U盘 的存储介质 采用 同步 动态随机存 储器S DR AM【 3 】 ,
芯片选 择I S 4 2 S 1 6 4 0 0 J ,该芯 片容量8 MHz ,频率 1 4 3 MHz ,速 度达 ̄ U 7 n s ,工作温度范 围. 4 0 。_ 8 0 。 ,满足工 业场合 的应用 要 求 。其容量大小也满足大 多数L E D屏的需求 。
E L E C T R 0Nl C S W 0R L D・ 蔗
r
基 于S T M3 2 单 相和 S D R AM晌模 拟 U盘 设计
重庆邮电大学光电工程学院 朱仁义 李泓成 张 辽
【 摘要 】 介绍了 ̄ .  ̄ t ' _ S T M3 2 单片机和外挂S D RA M存储器实现模拟u盘的设计,给 出了系统电路原理图和单片机模拟u盘的程序流
图 2降 压 电 路
2 . 3 U S B 接 口 电路 系统的数据交换通 ̄ I : US B 接口实现,S r I M3 2 F 4 2 9 内部集成0 , I G l . F S 控制器和O T G - HS 控制器,本文采用O T G fS 控制器 ] ,传输速度 达到1 2 Mb / s ,符合应用要求。U S B 接 口电路如图3 所示。US B 的差分 数据线D + 与D . 都串接了2 2 欧匹配电阻,提高了抗干扰能力,D + 信号 线接1 . 5 K欧上拉电阻到5 v,将被主机识别为高速设备。
USB Mass Storage学习笔记
USB Mass Storage学习笔记-STM32+FLASH实现U盘一、内容概述采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘。
1、STM32的USB控制器STM32F103的MCU自带USB从控制器,符合USB规范的通信连接;PC 主机和微控制器之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被USB外设直接访问。
这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用512字节缓冲区,最多可用于16个单向或8个双向端点。
USB模块同PC主机通信,根据USB规范实现令牌分组的检测,数据发送/接收的处理,和握手分组的处理。
整个传输的格式由硬件完成,其中包括CRC的生成和校验。
每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数。
当USB模块识别出一个有效的功能/端点的令牌分组时,(如果需要传输数据并且端点已配置)随之发生相关的数据传输。
USB模块通过一个内部的16位寄存器实现端口与专用缓冲区的数据交换。
在所有的数据传输完成后,如果需要,则根据传输的方向,发送或接收适当的握手分组。
在数据传输结束时,USB模块将触发与端点相关的中断,通过读状态寄存器和/或者利用不同的中断来处理。
USB的中断映射单元:将可能产生中断的USB事件映射到三个不同的NVIC 请求线上:(1)USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等)。
固件在处理中断前应当首先确定中断源。
(2)USB高优先级中断(通道19):仅能由同步和双缓冲批量传输的正确传输事件触发,目的是保证最大的传输速率。
(3)USB唤醒中断(通道42):由USB挂起模式的唤醒事件触发。
图 1、USB设备框图2、大页NAND K9F1G08Nand flash 以页为单位读写数据,而以块为单位擦除数据。
Keil移植stm32的usb及usb+massStorage步骤
Keil移植stm32的usb及usb massStorage步骤1.将STM32的usb的库文件拷贝到Src\Libraries下并在工程中添加STM32_USB-FS-Device_Driver全部源文件;在工程属性c++选项include Path 添加STM32_USB-FS-Device_Driver\inc路径2.将本目录的Mass_Storage文件夹拷贝到Src\Usr文件下并在工程中添加Mass_Storage\src全部源文件;在工程属性c++选项include Path 添加Mass_Storage\inc路径3.将下面三个头文件和两个函数加到stm32f10x_it.c中#include "usb_lib.h"#include "usb_istr.h"#include "usb_pwr.h"void USB_HP_CAN1_TX_IRQHandler(void){CTR_HP();}void USB_LP_CAN1_RX0_IRQHandler(void){USB_Istr();}6.对Mass_Storage\src下的usb_hw_config.c文件下其中2个函数void USB_Disconnect_Config(void) [注意:此处的IO口设置为推挽输出]void USB_Cable_Config (FunctionalState NewState)重新按照自己硬件改写Mass_Storage\inc下的usb_hw_config.h文件三个定义#define USB_DISCONNECT GPIOA#define USB_DISCONNECT_PIN GPIO_Pin_8#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOA关于usb的使能IO 按照自己硬件改写7.在\Src\Usr\Mass_Storage\mass_mal.c文件中A:添加存储器驱动文件相关函数的头文件B:填写四个函数,均为存储器的相关驱动函数在unsigned short int MAL_Init(unsigned char lun)中添加存储器初始化函数在unsigned short int MAL_Write(unsigned char lun, unsigned int Memory_Offset, unsigned int *Writebuff, unsigned short int Transfer_Length) 中添加存储器写缓存函数在unsigned short int MAL_Read(unsigned char lun, unsigned int Memory_Offset, unsigned int *Readbuff, unsigned short int Transfer_Length) 中添加存储器读缓存函数在unsigned short int MAL_GetStatus (unsigned char lun)中添加存储器容量的函数8.使用方法:包含头文件#include "usb_lib.h"#include "usb_hw_config.h"#include "usb_pwr.h"调用函数:MassStorageInit(); //IO相关初始化Set_USBClock(); //USB时钟初始化USB_Interrupts_Config(); //USB通信中断配置USB_Init(); //USB初始化9.吴青松2012-3-15。
usb mass storage大容量存储的基本知识 -回复
usb mass storage大容量存储的基本知识-回复USB Mass Storage(简称USB存储)是指使用通用串行总线(USB)接口的设备来存储和传输大容量数据的技术。
USB存储设备通常包括闪存驱动器、外部硬盘和光盘驱动器等。
本文将一步一步回答关于USB存储的基本知识。
1. 什么是USB存储?USB存储是一种用于存储和传输大容量数据的技术方法,通过USB接口连接计算机设备。
USB存储设备可以是可携带的闪存驱动器、外部硬盘、光盘驱动器等,可以在不同设备之间快速、方便地存储和传输数据。
2. USB存储的工作原理是什么?USB存储设备通过USB接口连接到计算机设备,其内部包含一个控制器芯片,用于处理数据传输和设备管理。
当将USB存储设备连接到计算机时,操作系统会识别设备并安装相应的驱动程序。
通过USB接口,计算机可以读取和写入存储设备中的数据。
3. USB存储设备有哪些类型?USB存储设备的类型多种多样,常见的包括:- 闪存驱动器(USB闪盘):这是一种使用闪存芯片进行数据存储的便携式设备,具有小巧轻便,容量可大可小的特点。
- 外部硬盘驱动器:这种存储设备使用类似于计算机硬盘的旋转硬盘或固态硬盘进行数据存储,能够提供较大的存储容量。
- 光盘驱动器:这种设备用于读取和写入光盘(如CD、DVD)中的数据,可以用于存储和传输大容量数据。
4. USB存储设备的优势是什么?USB存储设备的优势包括:- 便携性:USB存储设备通常小巧轻便,方便携带。
用户可以随时将数据放入存储设备并随身携带,无需依赖网络或其他外部存储设备。
- 大容量:随着技术的发展,USB存储设备的存储容量不断增加,从几GB到几TB不等。
用户可以选择适合自己需求的存储容量。
- 兼容性:USB存储设备在不同的计算机和操作系统上具有广泛的兼容性。
几乎所有的现代计算机都具备USB接口,因此用户可以轻松连接到各种设备上。
5. 如何使用USB存储设备?使用USB存储设备非常简单,只需按照以下步骤操作:- 将USB存储设备插入计算机的可用USB接口中。
基于STM32的USB枚举过程学习笔记(四)
基于STM32的USB枚举过程学习笔记(四)前几篇介绍中,USB 主机完成了获取设备的描述符,现在进入第二步,设置设备的地址阶段。
该阶段是一个无数据过程的控制传输。
首先,在建立过程中USB 主机往设备的端点0 发出一个设置地址的请求,新地址在建立过程的数据包中。
该事务的结构包括:SETUP0 令牌包+SET_ADDRESS 数据包+ 握手包。
在建立过程之后直接进入到的状态过程,因为设置地址阶段是一个无数据过程的控制传输。
在状态过程,设备等待主机请求状态返回(即等待主机发送一个IN 令牌包),收到IN 令牌包后,设备就返回一个0 长度的数据包,如果主机确认该数据包已经正确收到,就会发送应答包ACK 给设备,设备收到ACK 之后,就要启动新的设备地址,这样设备就分配到了一个唯一的设备地址。
接下来将这段设置地址的过程通过USB 分析仪捕捉分析如下接着分析STM32 USB_HID 例子中的枚举过程的设置地址阶段。
同样在接收到主机的setup0 令牌后,STM32 USB 进入中断处理函数Setup0_Process(),由于是没有数据过程的控制传输,接着进入NoData_Setup0()函数,函数最后通过USB_StatusIn()等待主机的IN 令牌,即状态阶段。
主机发IN 令牌进入到状态阶段,USB 中断函数中执行In0_Process()函数,该函数把在建立过程函数Setup0_Process()中保存在pInformation 的地址信息,通过SetDeviceAddress()函数,配置新的设备地址。
串口的调试信息如下至此,设备新的地址设置成功,这里设置成0x6,之后的过程将使用这个新。
零死角玩转stm32-高级篇6、UsbDevice(模拟U盘)
0、友情提示《零死角玩转STM32》系列教程由初级篇、中级篇、高级篇、系统篇、四个部分组成,根据野火STM32开发板旧版教程升级而来,且经过重新深入编写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让您零死角玩转STM32。
M3的世界,与野火同行,乐意惬无边。
另外,野火团队历时一年精心打造的《STM32库开发实战指南》将于今年10月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利于查阅资料。
内容上会给你带来更多的惊喜。
是一本学习STM32必备的工具书。
敬请期待!6、UsbDevice(模拟U盘)6.1 实验描述及工程文件清单实验描述这是一个USB Mass Storage 实验,用USB线连接PC机与开发板,在电脑上就可以像操作普通U盘那样来操作开发板中的MicroSD卡,并在超级终端中打印出相应的调试信息。
在这里野火用的MicroSD卡的容量是1G。
硬件连接PE3-USB-MODE (PE3为普通I/O)PA11-USBDM(D-)PA12-USBDP(D+)用到的库文件startup/start_stm32f10x_hd.cCMSIS/core_cm3.cCMSIS/system_stm32f10x.cFWlib/stm32f10x_gpio.cFWlib/stm32f10x_rcc.cFWlib/stm32f10x_usart.cFWlib/misc.cFWlib/stm32f10x_dma.cFWlib/stm32f10x_sdio.cFWlib/stm32f10x_flash.c用户编写的文件USER/main.cUSER/stm32f10x_it.cUSER/usart1.cUSER/sdcard.cUSER/usb_istr.cUSER/usb_prop.cUSER/usb_pwr.cUSER/hw_config.cUSER/memory.cUSB文件usb_core.cusb_init.cusb_mem.cusb_regs.cusb_bot.cusb_scsi.cusb_data.cusb_desc.cusb_endp.c其中USER文件夹下红色标注的5个c文件也是USB库文件,只因为我们需要修改它们才没有把它们放在USBLIB目录下。
5 我的基于STM32的USB学习笔记
对USB的初步了解:1、USB的优点:可以热插拔,即插上后可以自动识别;系统总线供电,USB共有四根线,一根电源线,一根地线,一根D+线,一根D-线,D+和D-线是差分输入线;可以支持多种设备,且扩展容易,通过HUB可以再一个主机上连接多个设备传输数据的速度快,最快可达480Mbit/s方便的设备互联:在没有主机的情况下,实现点到点的通信(还可以实现主从互换)(USB OTG)2、USB的基本规范:USB1.0/1.1 低速情况下1.5Mbit/s:键盘、鼠标等全速情况下12Mbit/s:U盘、CD-ROMUSB2.0 高速达到480Mbit/s:音频设备、显示器等USB OTG 设备到设备的传输3、USB设备类规范:大容量存储设备类(Mass Storage Device)U盘、CD-ROM等人机交互设备类(Human Interface Device)键盘、鼠标、游戏手柄语音设备类(Audio Device)麦克风、音响等通信设备类(Communication Device)电话、调制解调器等打印机设备类(Printer Device)打印机监视设备类(Monitor Device)显示器、摄像头等4、USB逻辑上分为3:信号层,协议层,数据传输层协议层:包是USB系统中信息传输的基本单位,所有的数据都是经过打包后在总线上传输的。
包由6部分组成:同步字段(SYNC);包标识符(PID);地址字段(ADDR);数据字段(DA TA);检验字段(CRC);包结束(EOP)包标识符(PID):令牌包(Token)(输出,输入,帧起始,建立),数据包(DA TA)(数据,数据1),握手包(Handsnake)(确认,不确认,停止),专用包(Special)(前同步)5、USB协议提供4种数据传输方式:控制传输:突发,非周期性,由主机发起,用于命令和状态的传输同步传输:周期性,持续性的传输,用于传输与时效相关的信息,并且在数据中保存时间戳的信息中断传输:周期性,低频率,允许有限延迟的通信大容量的数据传输:非周期性,大容量突发数据的通信6、USB描述符:1)设备描述符:描述设备的类型、厂商信息、USB的协议类型、端点的报数据的最大长度等,每个USB设备只有一个Device Descriptor2)配置描述符:每个配置描述符提供了设备特定的配置,描述了设备的接口和端点的性质、供电模式、设备的耗电3)接口描述符:描述了设备的不同接口的特性,例如,一个设备U盘的功能,又有键盘的功能,用两个接口描述符分别描述两个功能4)字符串描述符:描述了设备制造商、设备名称、何序列号等信息基于STM32制作USB的过程STM32的USB模块特性:遵循USB2.0全速设备标准支持双向8个端点,8个IN端点和8个OUT端点(每个端点最大可使用512字节)[ 每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数]硬件实现CRC自动生成/校验,NRZI编码/解码和bit-stuffing(位插入,位填充)支持控制传输、中断传输、大容量传输和同步传输四种传输方式支持USB的挂起和/唤醒***USB设备的实现过程***一、系统初始化1、初始化系统时钟,设置USB时钟2、配置USB中断,选择通道,设置优先级,使能中断3、配置GPIO4、USB的初始化,对描述符、设备的端点接口等的初始化5、FLASH的初始化二、USB的枚举枚举过程就相当于主机和设备建立连接的过程(接头),Host向Device询问一些东西,Device将自身的设备类型,如何进行通信报告给Host,这样,Host就知道怎么对Device 进行操作。
基于STM32的USB枚举过程学习笔记(一)
基于STM32的USB枚举过程学习笔记(一)之前使用ST 官方的库以及网络的资料,完成了使用USB HID 类进行STM32 和PC 机的通讯。
由于其他原因并没有深入的分析,虽然实现了功能,但是关于USB 设备的枚举,以及具体的通讯方式都没有清晰的概念,所以现在回头重新学习USB 相关知识。
主要参考资料是《圈圈教你玩USB》、USB 枚举过程图解,ST 官方的USB HID 例程。
一,USB 数据包 B 数据包分类USB 总线上的数据传输以包为基本的单位。
USB 协议规定了四种包:令牌包、数据包、握手包、特殊包。
不同的包通过包中的8 位PID 域区分。
令牌包令牌包用于启动一次USB 传输,USB 的数据传输必须由主机发起。
令牌包有四种:输出令牌包(OUT):用来通知设备将要输出一个数据包。
数据方向主机--> 设备输入令牌包(IN):用来通知设备将要返回一个数据包。
数据方向设备-->主机建立令牌包(SETUP):通知设备将要输出一个数据包,类似OUT 包。
不过SETUP 包只能往端点0 发包,只用在控制传输中。
帧起始包(SOF):用于帧计数,USB 全速设备每毫秒产生一帧,USB 高速设备每125μS 产生一帧。
OUT , IN, SETUP 包的结构:同步域+8 位PID+7 位地址+4 位端点号+5 位CRC 校验+包结束符EOP数据包数据包用来传输数据,分成DATA0. DATA1 。
数据格式如下同步域+8 位PID+N 个字节的数据+CRC16 校验+包结束符EOP握手包握手包用来表示一个传输是否被对方确认,有。
STM32 U盘
这段时间主要在搞usb通信,先用STM32+FLASH实现u盘。
在做之前,先对usb的通信协议和STM32的usb控制器进行深入的学习和理解。
在看usb2.0协议的时候,经常看到端点这个词,所以我要先把端点的含义弄懂,usb通讯的最基本形式是通过一个称为端点的东西,端点可以被看做一个单向管道。
usb端点有4种不同的类型:1、控制端点:用来控制对usb设备的不同部分访问。
2、中断端点:当usb主机向设备请求数据时,中断端点以固定速率传送小量数据。
3、批量端点:用来传送大量数据。
4、等时端点:也是传送大量数据,但不被保证能送达。
同时对枚举过程也要有深入的理解,枚举就是从设备读取一些信息,知道设备是什么样的设备,如何进行通信,这样主机就可以根据这些信息来加载合适的驱动程序。
调试USB设备,很重要的一点就是USB的枚举过程,只要枚举成功了,那么就已经成功大半了。
首先,USB主机检测到USB设备插入后,就会先对设备复位。
设备复位后,USB 主机就会对地址为0的设备发送获取设备描述符的标准请求。
所有的USB设备在总线复位后其地址都为0,这样主机就可以跟那些刚刚插入的设备通过地址0通信。
主机在建立阶段发出获取设备描述符的输入请求,设备收到该请求后,在数据过程将设备描述符返回给主机。
主机在成功获取到一个数据包的设备描述符后并且确认没有什么错误后(注意:有些USB设备的端点0大小不足18字节(但至少具有8字节),而标准的设备描述有18字节,在这种情况下,USB设备只能暂时按最大包将部分设备描述符返回,而主机在成功获取到前面一部分描述符后,就不会再请求剩下的设备描述符部分,而是进入设置地址阶段),就会返回一个0长度的状态数据包给设备。
然后主机再对设备复位一下,接下来就会进入到设置地址阶段。
这时USB主机发出一个设置地址的请求(建立过程,设置地址无数据过程),地址包含在建立包中,具体的地址USB主机会负责管理,它会分配一个唯一的地址给新的设备。
基于STM32的USB枚举过程学习笔记(三)
基于STM32的USB枚举过程学习笔记(三)上一篇介绍到了主机上电复位USB 设备,在控制传输的建立过程,发送了8 个字节的数据给设备,这8 个字节为0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00,该请求为USB 标准设备请求中的GET_DESCRIPTOR 请求。
0x80 表示标准设备请求,数据方向是设备到主机。
0x60 表示请求类型GET_DESCRIPTOR。
0x01 表示描述符类型是设备描述符。
0x40 表示描述符长度。
设备在收到该请求以后,首先进行解析,根据请求中的0x40 表示该控制传输有数据过程,因此进入到Data_Setup0()函数。
该函数根据请求的不同描述符,执行不同的回调函数CopyRoutine(),并在DataStageIn()函数中把要发送给主机的描述符填入USB 缓冲区,等待USB 主机发送IN 令牌包。
主机在建立过程最后收到ACK 以后,发送IN 令牌包,从而进入到数据过程。
在CTR_LP()函数中判断是IN0 中断后,进入In0_Process()函数。
在数据过程将之前填在USB 缓冲器的设备描述符发给主机,并等待主机的应答。
主机在确认接收到的设备描述符没有出错后,就会返回一个0 数据长度的确认包,即控制传输的状态过程。
在CTR_LP()函数中判断是OUT0 中断,进入Out0_Process()函数,由于在状态过程,所以调用回调函数Process_Status_OUT()。
下面和上篇一样,对照着USB 分析仪捕捉的数据分析获取设备描述符这次控制传输的数据过程和状态过程。
下面通过串口打印信息查看获取设备描述符控制传输过程中的数据包的数据。
打印信息如下至此,USB 主机成功获取到设备描述符。
打印信息最后可以看。
HZM移植Mass Stroage笔记
u16 MAL_Write(u8 lun, u32 Memory_Offset, u32 *Writebuff, u16 Transfer_Length);
写入介质上的一块区域,写入方法:由函数调用的原型看出,Transfer_Length以后传入的值,最大时就是你写入的最低可擦除扇区的大小(字节),如W25Q32的最低擦除为4K字节。
读取介质的参数,页大小,总页数,以及总大小,这个视STM32的内Flash情况而定,为文件系统format介质提供依据
u16 MAL_Read(u8 lun, u32 Memory_Offset, u32 *Readbuff, u16 Transfer_Length);
读取介质上的一块区域,读取方法:可以看调用函数的原型,u32 *Readbuff可以根据自己的实际改为u8类型,提取Transfer_Length个字节就好
我们需要把文件存储在STM32的内部Flash中,因此更改这里的接口即可
mass_mal向外提供了四个函数:
u16 MAL_Init (u8 lun);//初始化存储设备
初始化介质,由于是内部Flash,为了能写入,只需Unlock FLASH
u16 MAL_GetStatus (u8 lun);//得到存储设备的信息:大小,块个数,页大小
/*0071*/ return MAL_FAIL;
/*0072*/ }
其他函数也根据实际的存储设备进行填写。
另外:实际运行中还有一个问题,那就是在memory.c中Data_Buffer定义大小为512Bytes,这里我们的Flash是1K一页,要将Data_Buffer重新定义成1KBytes的
3.把buf整个写回扇区当中。
USB Mass Storage HZM经验
修改 设备管理器内名字的位置:
scsi_data.c 文件内的Standard_Inquiry_Data 数组。
修改开始栏右边显示 弹出U盘的名字:
usb_desc.c 内MASS_StringProduct 数组,并根据实际长度修改MASS_SIZ_STRING_PRODUCT 的长度值
break;
}
return res;
如果USB中保存的扇区大小比存储设备实际的扇区大小要小,可能导致电脑端无法对存储设备格式化,只能在单片机内,用文件系统的函数进行格式化。并且这样传输速度会慢,但是这样需要占据的RAM较小
{
case CTRL_SYNC :
res = RES_OK;
break;
//扇区大小
case GET_SECTOR_SIZE:
*(DWORD*)buff = _MAX_SS;
res = RES_OK; Fra bibliotek break;
//总扇区个数 SPI_FLASH_SECTOR_SIZE是spi flash或其他设备实际的扇区大小, //SPI_FLASH_SECTOR_COUNT 是实际有的扇区数
case GET_SECTOR_COUNT:
*(DWORD*)buff = SPI_FLASH_SECTOR_COUNT * (SPI_FLASH_SECTOR_SIZE/_MAX_SS);
res = RES_OK;
break;
default:
res = RES_PARERR;
还有重要部分,对于文件系统 扇区的划分
B 的mass_mal.c中MAL_GetStatus 函数:
关于STM32的FLASH操作
关于STM32的FLASH操作说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。
当然,FLASH还可以用来装数据。
FLASH分类根据用途,STM32片内的FLASH分成两部分:主存储块、信息块。
主存储块用于存储程序,我们写的程序一般存储在这里。
信息块又分成两部分:系统存储器、选项字节。
系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。
这个区域由芯片厂写入BootLoader,然后锁死,用户是无法改变这个区域的。
选项字节存储芯片的配置信息及对主存储块的保护信息。
FLASH的页面STM32的FLASH主存储块按页组织,有的产品每页1KB,有的产品每页2KB。
页面典型的用途就是用于按页擦除FLASH。
从这点来看,页面有点像通用FLASH的扇区。
STM32产品的分类STM32根据FLASH主存储块容量、页面的不同,系统存储器的不同,分为小容量、中容量、大容量、互联型,共四类产品。
小容量产品主存储块1-32KB,每页1KB。
系统存储器2KB。
中容量产品主存储块64-128KB,每页1KB。
系统存储器2KB。
大容量产品主存储块256KB以上,每页2KB。
系统存储器2KB。
互联型产品主存储块256KB以上,每页2KB。
系统存储器18KB。
对于具体一个产品属于哪类,可以查数据手册,或根据以下简单的规则进行区分:STM32F101xx、STM32F102xx、STM32F103xx产品,根据其主存储块容量,一定是小容量、中容量、大容量产品中的一种,STM32F105xx、STM32F107xx是互联型产品。
互联型产品与其它三类的不同之处就是BootLoader的不同,小中大容量产品的BootLoader只有2KB,只能通过USART1进行ISP,而互联型产品的BootLoader有18KB,能通过USAT1、4、CAN等多种方式进行ISP。
关于STM32的FLASH操作
关于STM32的FLASH操作说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。
当然, FLASH还可以用来装数据。
FLASH分类根据用途,STM32片内的FLASH分成两部分:主存储块、信息块。
主存储块用于存储程序,我们写的程序一般存储在这里。
信息块又分成两部分:系统存储器、选项字节。
系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。
这个区域由芯片厂写入BootLoader,然后锁死,用户是无法改变这个区域的。
选项字节存储芯片的配置信息及对主存储块的保护信息。
FLASH的页面STM32的FLASH主存储块按页组织,有的产品每页1KB,有的产品每页2KB。
页面典型的用途就是用于按页擦除FLASH。
从这点来看,页面有点像通用FLASH 的扇区。
STM32产品的分类STM32根据FLASH主存储块容量、页面的不同,系统存储器的不同,分为小容量、中容量、大容量、互联型,共四类产品。
小容量产品主存储块1-32KB,每页1KB。
系统存储器2KB。
中容量产品主存储块64-128KB,每页1KB。
系统存储器2KB。
大容量产品主存储块256KB以上,每页2KB。
系统存储器2KB。
互联型产品主存储块256KB以上,每页2KB。
系统存储器18KB。
对于具体一个产品属于哪类,可以查数据手册,或根据以下简单的规则进行区分:STM32F101xx、STM32F102xx 、STM32F103xx产品,根据其主存储块容量,一定是小容量、中容量、大容量产品中的一种,STM32F105xx、STM32F107xx是互联型产品。
互联型产品与其它三类的不同之处就是BootLoader的不同,小中大容量产品的BootLoader只有2KB,只能通过USART1进行ISP,而互联型产品的BootLoader 有18KB,能通过USAT1、4、CAN等多种方式进行ISP。
目标板识别为U盘
⽬标板识别为U盘Mass Storage的实际应⽤就是U盘,⽬标板和PC通过USB相连,PC可以把⽬标板识别为U盘,在很多产品上都很常⽤。
这⾥介绍⼀下在WinCE系统中U盘功能的实现。
在谈WinCE的USB Mass Storage实现之前,⾸先要具备以下条件:1. 开发板⽀持USBClient设备。
2. 开发板上⾄少有⼀种存储设备可以被⽤来映射为U盘。
现在的处理器⼀般都带有USB Client或者是USB OTG控制器,并且BSP中都有相应的驱动。
对于存储设备来说,Nandflash或者SD卡都可以作为存储设备。
所以都不是什么问题。
下⾯介绍⼀下步骤:1. 选择WinCE Mass Storage组件在定制WinCE的时候,在Catalog Items View中选择”Device Drivers”->”USB Function”->”USB Function Clients”->”Mass Storage”。
2. 更改USB Client驱动的注册表配置在WinCE中,USB Client驱动的注册表配置如下:[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers]“DefaultClientDriver”:设置默认的USB Client驱动,这⾥应该是Mass_Storage_Class[HKEY_LOCAL_MACHINE\Drivers\USB\FunctionDrivers\Mass_Storage_Class]“Dll”:USB Client的驱动“DeviceName”:被映射为U盘的存储设备的设备名“FriendlyName”:显⽰设备名“idVendor”:Vendor ID,应该向USB组织申请“idProduct”:Product ID,由⼚商定义“Manufacturer”:⼚商名“Product”:产品名“bcdDevice”:设备的版本号“InterfaceSubClass”:USB Host端通过该值来枚举设备,06h表⽰Mass Storage。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
USB Mass Storage学习笔记-STM32+FLASH实现U盘一、 内容概述采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘。
1、STM32的USB控制器STM32F103的MCU自带USB从控制器,符合USB规范的通信连接;PC主机和微控制器之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被USB外设直接访问。
这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用512字节缓冲区,最多可用于16个单向或8个双向端点。
USB模块同PC主机通信,根据USB 规范实现令牌分组的检测,数据发送/接收的处理,和握手分组的处理。
整个传输的格式由硬件完成,其中包括CRC的生成和校验。
每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节数。
当USB模块识别出一个有效的功能/端点的令牌分组时,(如果需要传输数据并且端点已配置)随之发生相关的数据传输。
USB模块通过一个内部的16位寄存器实现端口与专用缓冲区的数据交换。
在所有的数据传输完成后,如果需要,则根据传输的方向,发送或接收适当的握手分组。
在数据传输结束时,USB模块将触发与端点相关的中断,通过读状态寄存器和/或者利用不同的中断来处理。
USB的中断映射单元:将可能产生中断的USB事件映射到三个不同的NVIC 请求线上:(1)USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等)。
固件在处理中断前应当首先确定中断源。
(2)USB高优先级中断(通道19):仅能由同步和双缓冲批量传输的正确传输事件触发,目的是保证最大的传输速率。
(3)USB唤醒中断(通道42):由USB挂起模式的唤醒事件触发。
图 1、USB设备框图2、大页NAND K9F1G08Nand flash 以页为单位读写数据,而以块为单位擦除数据。
根据NAND 的容量等级又将NANDFLASH分为大页NAND和小页NAND;K9F1G08就是大页NAND,它的页大小为(2K+64)Byte,块大小为(128K+4K)Byte。
K9F1208U0M 为小页NAND,它的页大小为(512+16)Byte,块大小为(16K+512)Byte。
由于写数据至FLASH时,只能将指定的位变为0,而不能将指定的位变位1。
因此在写一个页的数据前,必须先擦除(将所有的位全部置1),否则写数据会失败。
在编制FLASH的读写程序时,需要传递三个参数,要操作的地址,要操作的数据缓存,要操作的数据长度;在写操作时,还要有擦写和坏块管理。
3、USB Mass storage Bulk OnlyMass Storage类支持两个传输协议:1、Bulk-Only 传输(BOT)2、Control/Bulk/Interrupt传输(CBI)Mass Storage类规范定义了两个类规定的请求:Get_Max_LUN和Mass Stor age Reset,所有的Mass Storage类设备都必须支持这两个请求。
Bulk-Only Mass Storage Reset(bmRequestType=00100001b and bReques t= 11111111b)用来复位Mass Storage设备及其相关接口。
Get_Max_LUN(bmRequestType= 10100001b and bRequest= 11111110b)用来确认设备支持的逻辑单元数。
Max LUN的值必须是0~15。
注意:LUN是从0开始的。
主机不能向不存在的LUN发送CBW。
支持BOT传输的Mass Storage设备接口描述符要求如下:接口类代码bInterfaceClass=08h,表示为Mass Storage设备;接口类子代码bInterfaceSubClass=06h,表示设备支持SCSI Primary Com mand-2(SPC-2);协议代码bInterfaceProtocol有3种:0x00、0x01、0x50,前两种需要使用中断传输,最后一种仅使用批量传输(BOT)。
支持BOT的设备必须支持最少3个endpoint:Control, Bulk-In和Bulk-O ut。
USB2.0的规范定义了控制端点0。
Bulk-In端点用来从设备向主机传送数据。
Bulk-Out端点用来从主机向设备传送数据。
Bulk-Only传输(BOT)像控制传输一样,BOT也是由Command阶段,可选的数据阶段和状态阶段组成。
所有的command请求都可能有或没有Data阶段。
下图说明了BOT的Comman d传输,Data-In,Data-Out传输及Status传输。
图2、Bulk-Only传输示意图CBW是由31个字节组成的短包。
CBW和后续的数据以及CSW都是从新封包开始的。
要注意的是所有CBW传输都是little-endian模式。
在CBW中,dCBWSignature必须是“43425355h”,表示是CBW封包。
dCBWTag是CB标签,会通过对应的CSW的标签反馈回来。
在CSW中,dCSWSignature必须是“53425355h”,表示是CSW包。
二、 系统的初始化1、初始化系统时钟,设置USB时钟为48MHz;2、USB中断配制,选择通道、设置优先级、使能中断。
3、USB初始化:连接USB、USB硬件复位、配制CNTR寄存器使能和屏蔽中断、清零中断状态寄存器。
4、FLASH初始化。
三、 USB的枚举当USB连接时,进入USB低优先级中断。
首先获取中断状态(读ISTR寄存器),在MASS STORAGE中有USB复位中断、USB挂起中断和正确的数据传输中断。
注:在usb_istr.c 的void USB_Istr(void)函数中。
1、USB总线复位:设置分组缓冲区描述表起始地址;初始化端点:端点0为控制端点、端点1、2为批量端点;设置发送和接收状态,设置发送和接收缓冲区地址。
设置CBW签名, CBW.dSignature=0x43425355;初始化BOT状态机。
注:在usb_prop.c的void MASS_Reset()函数中。
2、USB总线挂起:Xms总线上无数据传输,USB总线挂起,进入低功耗模式。
注:在usb_pwr.c的void Suspend()函数中。
3、正确的数据传输中断(usb_int.c CTR_LP();)清除中断标志;获取端点标识符;控制端点处理:读端点寄存器,用来判断是数据输入、输出还是建立包。
非控制端点处理:下一节介绍。
详见软件流程图。
图3、USB枚举软件流程图四、 非控制端点处理(usb_endp.c -> usb.bot.c)端点2输出中断:usb主机传数据或命令包至mcu。
端点1输入中断:mcu传数据或描述符至usb主机。
1、端点2输出中断(1) 将主机传过来的数据从USB端点缓存区copy至MCU内存;(2) 判断BOT状态,根据BOT状态做出相应的处理:当BOT状态位为0时,CBW包解析,并处理SCSI命令;当BOT状态为1时,表示数据输出,执行WRITE10命令处理。
2、端点1输入中断判断BOT状态,如果BOT状态为2,表示数据输入,执行READ10命令处理;如果BOT状态为4,则表示数据输入完成,则返回CSW,进行到命令状态。
3、BOT状态机软件流程图(1)端点2输出中断流程图(usb_bot.c -> Mass_Storage_Out())图4、端点2输出中断(2)CBW包解析软件流程图(usb_bot.c -> CBW_Decode())图5、CBW包解析(3)READ10命令软件流程图(usb_scsi.c -> SCSI_Read10_Cmd(lun , LBA , BlockNbr))图6、READ10命令(4)WRITE10命令软件流程图(usb_scsi.c -> SCSI_Write10_Cmd(lun , LBA , BlockNbr))(5)端点1输入中断流程图(usb_bot.c -> Mass_Storage_In())图8、端点1输入中断4、USB对Memory的操作在MASS STORAGE中,USB对MEMORY的操作是以扇区(在FAT中,一个扇区为512字节)为单位的,而USB端点的最大包长为64字节,因此要发送或接收的数据会先放到内存,假设是CPU向端点1写数据,则首先从FLASH 或SD卡中读取一扇区数据,再按最大包长分8次向USB端点发送。
如果是端点2输出数据,则CPU将收到的数据先放至内存,并累加,当是512字节的整数倍时,再将数据写入FLASH或SD,软件操作流程如下:图9、READ_MEMORY流程图在对FLASH或SD卡的读写操作中,该函数需要三个入口参数,第一个是逻辑单元号,用来告诉CPU主机是对哪个磁盘操作(假设有多个磁盘);第二个是逻辑块地址,这里是指第几个扇区,而存储器的地址为字节地址,所以这个地址需要转换;第三个为数据长度,可以是多少个扇区,也可以是多少个字节,这个可以在CBW包中获得。
当数据发送完后,BOT的状态值置为4,进入到状态阶段。
五、 FLASH读写USB对FLASH的操用是任意的,以扇区为单位,由于不是按连续地址写数据,所以FLASH的写函数中要有擦写管理。
这里我是直接移植圈圈的FLASH读写函数,所以这里引用他的说明:(以下文字出自圈圈的BLOG)由于NAND FLASH擦除时,只能按按块擦除,因此在写扇区时,首先要擦除一个块。
在擦除块前,必须将块内其他数据复制出来,由于一个块比较大(128KB),无法在MCU内开辟如此大的缓冲区。
只好借助该NAND FLASH内的页复制命令,将原来的块暂时复制到一个交换用的交换块中。
但是如果仅用一个块作为交换的话,它就会被频繁擦写,因而寿命会大大降低。
所以在该系统中,保留了10个块用来作为交换区,轮流使用。
另外对扇区的连续写进行了优化,当连续写扇区时,就不必每次重复上面的操作,只有当地址跨块时,才需要重新擦除。
连续写扇区的实现原理如下:当检测到扇区地址跨块时,就把原来的整块数据复制到交换块中,然后将该块内当前所写地址的前面部分页面复制到原来的块中,接着就从交换块中取出当前扇区地址所在页(使用页复制-随机写入命令),再把一个扇区的数据写入,并接着写入其他扇区,当扇区地址跨页时,就把该页写入到原来的块中,直到扇区被写完(当然如果写的过程中跨块了,还需要重复前面的块擦除以及复制过程)。
接着把交换块中剩余的页再复制回原来的块中,这样一个连续写过程就完成了。