精华内容
下载资源
问答
  • PC与Android设备进行USB文件传输

    热门讨论 2014-10-17 16:22:44
    上位机c#源代码:在PC上实现与Android设备的数据传输,完美使用ADB命令 功能包括: 1.上传文件 2.上传文件夹 3.下载文件 4.下载文件夹 5.删除Android文件 6.删除Android文件夹 7.创建Android文件夹
  • Android使用usb线传输文件笔记

    千次阅读 2019-04-21 00:54:46
    使用usb线传输文件 参考资料: 使用USB数据线连接PC端和Android端进行数据的交互 安卓设备通过USB接口实现与pc端的简单数据通信 Socket TCP/IP协议数据传输过程中的粘包和分包问题 【Android学习】socket长连接,...

    使用usb线传输大文件

    参考资料:

    1. 使用USB数据线连接PC端和Android端进行数据的交互
    2. 安卓设备通过USB接口实现与pc端的简单数据通信
    3. Socket TCP/IP协议数据传输过程中的粘包和分包问题
    4. 【Android学习】socket长连接,数据粘包问题

      由于客户应用使用的场景比较特殊。明确要求不能使用网络进行数据交互,所以不得不研究了一下使用usb通信这方面。原理就是当连上usb线后,通过socket进行数据通信。只不过android设备作为socket服务端,pc作为socket的客户端。pc端在与服务端建立连接之前需要使用adb命令设置转发端口(具体可参考参考资料1和参考资料2)。
      端口这玩意随便填,不跟别人冲突就行。

    adb shell am broadcast -a NotifyServiceStop
    adb forward tcp:9999 tcp:9000
    adb shell am broadcast -a NotifyServiceStart

    ##使用代码调用命令行
      如果想要完善android通过usb先进行数据交互,这里应该有不少的命令能用到,这里先记录一下调用命令的基本使用。

    import java.io.BufferedReader
    import java.io.InputStreamReader
    
    fun main() {
    
      //读取连接设备
      val process = Runtime.getRuntime().exec("adb devices")
      val devices = BufferedReader(InputStreamReader(process.inputStream))
      val stringBuilder = StringBuilder()
      var line: String? = null
      while (devices.readLine().apply { line = this } != null) {
        stringBuilder.append("$line\n")
      }
      println(stringBuilder.toString())
    
      //读取安装的应用
      val process2 = Runtime.getRuntime().exec("adb shell pm list packages")
      val packages = BufferedReader(InputStreamReader(process2.inputStream))
      val sb = StringBuilder()
      var line2: String? = null
      while (packages.readLine().apply { line2 = this } != null) {
        sb.append("$line2\n")
      }
      println(sb.toString())
    
    }
    

      打印结果如下图所示:
    在这里插入图片描述
      上面运行结果不错就是代码量有点多,用python简化一下就清晰不少。

    import subprocess
    
    if __name__ == '__main__':
        # 读取连接设备
        subprocess.call("adb devices", shell=True)
        # 读取安装的应用
        subprocess.call("adb shell pm list packages", shell=True)
    
    

    Android端

      Android端作为Socket的服务端,用来接收文件。为了防止分包的问题这里我定义了一个封包和解包方式。
    在这里插入图片描述
      在文件传输的时候,数据的收发都会以这种结构去发送或者接收。(实际情况下肯定跟这个不一样,我这为了方便携带参数用的就是json格式的数据)。理论上就是每次读取的字节大小都在携带信息中。如果在循环读取中有一次没有读满,那就把它应当读取的字节都读取出来,再循环下一次数据读取,省着出现粘包的现象。(byte也别设太大,要不内存溢出)

    package com.lyan.usbtestphone
    
    import android.annotation.SuppressLint
    import android.support.v7.app.AppCompatActivity
    import android.os.Bundle
    import android.os.Environment
    import android.os.Handler
    import com.blankj.utilcode.constant.PermissionConstants
    import com.blankj.utilcode.util.GsonUtils
    import com.blankj.utilcode.util.LogUtils
    import com.blankj.utilcode.util.PermissionUtils
    import com.blankj.utilcode.util.ToastUtils
    import kotlinx.android.synthetic.main.activity_main.*
    import java.io.*
    import java.net.ServerSocket
    import java.net.Socket
    
    class MainActivity : AppCompatActivity() {
    
        @SuppressLint("SetTextI18n")
        private val handler = Handler(Handler.Callback {
            when (it.what) {
                1 -> progressTv.text = "${it.obj}%"
            }
            false
        })
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            testBtn.setOnClickListener {
                startSocketServer { LogUtils.i("${Thread.currentThread().name} : $it") }
            }
        }
    
        private fun startSocketServer(callback: (name: Socket) -> Unit) = Thread {
            val file = File(Environment.getExternalStorageDirectory(), "copy.db3")
            if (file.exists()) {
                if (file.delete()) {
                    file.createNewFile()
                }
            } else {
                file.createNewFile()
            }
            ServerSocket(9000).apply {
                logI("移动服务端等待客户端的连接...")
                val client = this.accept()
                callback.invoke(client)
                val bufferedOutputStream = BufferedOutputStream(DataOutputStream(FileOutputStream(file)))
                val bufferedInputStream = BufferedInputStream(DataInputStream(client.getInputStream()))
                val tagBytes = ByteArray(6)
                val infoBytes = ByteArray(4)
                var hTag: String//标记头
                var fTag: String//标记尾
                var infoSize: Int//携带数据的一些信息
                var jsonBytes: ByteArray//携带数据的byte数组
                var sendInfoData: SendInfoData//解析后的携带信息
                var readBytes: ByteArray//真正传输的数据的byte数组
                var readSize: Int//真正传输的数据的byte长度
                while (true) {
    
                    val len = bufferedInputStream.read(tagBytes)
                    if (len == -1) {
                        break
                    }
                    hTag = String(tagBytes, 0, len)//标记头
                    //读取进度信息
                    infoSize = bufferedInputStream.read(infoBytes).run { bytesToInt(infoBytes) }
                    jsonBytes = ByteArray(infoSize)
                    sendInfoData = bufferedInputStream.read(jsonBytes).run {
                        val infoJson = when (infoSize) {
                            this -> {//读取数据完整
                                LogUtils.i("读取数据完整")
                                String(jsonBytes, 0, this)
                            }
                            else -> {//读取数据不完整(此处只要将分包处理后、粘包的问题自然就不会出现了)
                                LogUtils.i("读取数据不完整")
                                bufferedInputStream.read(jsonBytes, this, infoSize - this).run {
                                    String(jsonBytes, 0, infoSize)
                                }
                            }
                        }
                        LogUtils.i("其他信息 ------> $infoJson")
                        GsonUtils.getGson().fromJson(infoJson, SendInfoData::class.java)
                    }
                    handler.obtainMessage(1, sendInfoData.percent).sendToTarget()
                    //读取数据信息 传输数据大小 解析数据长度
                    readBytes = ByteArray(sendInfoData.sendSize)
                    readSize = bufferedInputStream.read(readBytes)//已读数据大小
                    LogUtils.i("读流的长度:$readSize")
                    if (readSize < sendInfoData.sendSize) {
                        LogUtils.w("读取数据不完整!已读数据少于应读取数据的大小……",
                                "应读:${sendInfoData.sendSize}", "实读:$readSize")
                        bufferedInputStream.read(readBytes, readSize, sendInfoData.sendSize - readSize)
                    }
                    fTag = bufferedInputStream.read(tagBytes).run { String(tagBytes, 0, this) }
                    LogUtils.w("header:$hTag", "携带信息的字节数:$infoSize", "携带信息内容:$sendInfoData",
                            "每次应读取的数据字节数量:${sendInfoData.sendSize}", "footer:$fTag")
                    bufferedOutputStream.write(readBytes)
                    bufferedOutputStream.flush()
                }
            }
        }.start()
    
        //请求权限(文件读写权限)
        override fun onResume() {
            super.onResume()
            PermissionUtils.permission(PermissionConstants.STORAGE).callback(object : PermissionUtils.SimpleCallback {
                override fun onGranted() {
                    ToastUtils.showShort("获取文件读写权限成功!")
                }
    
                override fun onDenied() {
                }
            }).request()
        }
    
        private fun bytesToInt(bytes: ByteArray): Int {
            return (0 until bytes.size).sumBy { (bytes[it].toInt() and 0xFF) shl it * 8 }
        }
    
        //每次接收数据的信息 进度 和 要保存的数据字节大小
        data class SendInfoData(val percent: String, val sendSize: Int)
    }
    
    

    pc端(正常应该是后台)

      在这种情况下后台就成客户端了。这里为了减少socket客户端的代码量,所以使用ptyhon来写:

    import subprocess
    import socket
    import time
    import copy
    import json
    import os
    
    
    class SendInfoData(object):
    
        def __init__(self, percent="", sendSize=0):
            self.__percent = percent
            self.__sendSize = sendSize
    
        def toJson(self):
            return json.dumps({
                "percent": self.__percent,
                "sendSize": self.__sendSize,
            })
    
    
    # int转byte数组
    def intToBytes(intNumber=0): return intNumber.to_bytes(4, "little")
    
    
    # str转utf-8 byte数组
    def strToUtf8Bytes(value): return bytes(value, encoding="utf-8")
    
    
    if __name__ == '__main__':
    
        subprocess.call("adb shell am broadcast -a NotifyServiceStop", shell=True)
        subprocess.call("adb forward tcp:9999 tcp:9000", shell=True)
        subprocess.call("adb shell am broadcast -a NotifyServiceStart", shell=True)
    
        client = socket.socket()
        result = client.connect(("127.0.0.1", 9999))
    
        # 文件路径
        filePath = "/Users/apple/Downloads/base.db3"
    
        # 文件大小
        allSize = os.path.getsize(filePath)
        fileSize = copy.deepcopy(allSize)
        print("%s\n" % fileSize)
        defaultReadSize = 1024 * 10
        progress = 0
    
        h = time.time()
        # 读取 文件
        with open(filePath, mode="rb") as readFile:
            while True:
                if fileSize <= 0: break
                readSize = defaultReadSize if fileSize > defaultReadSize else fileSize
                progress += readSize
                percent = '{: .2f}'.format(progress * 1.0 / allSize * 100)
                print("进度:%s" % percent)
                # 读取内容
                readBytes = readFile.read(readSize)
                if not readBytes: break
                tagH = strToUtf8Bytes("@tag:h")
                tagF = strToUtf8Bytes("@tag:f")
                # 携带信息
                infoJson = SendInfoData(percent, readSize).toJson()
                print("json:%s\n" % infoJson)
                infoBytes = strToUtf8Bytes(infoJson)
                infoSize = intToBytes(len(infoBytes))
                # 包裹传输数据
                client.send(tagH)  # 标记开头
                client.send(infoSize)  # 携带参数byte数据长度
                client.send(infoBytes)  # 携带参数内容
                client.send(readBytes)  # 真实传输的内容
                client.send(tagF)  # 标记结尾
                fileSize -= readSize
    
        client.close()
    
        f = time.time()
        print("用时:{: .0f}s".format((f - h)))
    
    

      这个例子的界面比较简单,就一个按钮和一个文本。手上测试的文件是一个900多兆的文件,在单位的时候试过一个4个多G的sqlite文件。而且文件在传输后一样可以正常使用。说明这个方式还是可行的。(当然在实际项目中这个例子仅仅是证明这个方式可行而已,具体优化部分肯定不带少的)
    在这里插入图片描述
    在这里插入图片描述

    笔记:byte[]未写满,补全的方式

      目的是验证,这里以读取文件的内容为例,文件是txt格式的这里放了一段字符串“一二三四五六七八九十”。一共是10字符(一个字符2个字节,也就是20个字节)。定义一个byte数组长度为20。先读一半,然后再读剩下的一半。

    import java.io.File
    import java.io.FileInputStream
    import java.nio.charset.Charset
    
    fun main() {
    
        val path = "/Users/apple/Downloads/O.txt"
        val file = File(path)
        val inputStream = FileInputStream(file)
        //available()这个方法本质的意义是 剩余未被读取的字节数量
        println("文件的字节总数:${inputStream.available()}")
    
        val byte = ByteArray(20)
    
        val read1 = inputStream.read(byte, 0, 10)
        println(read1)
        println("read1后剩余字节数量:${inputStream.available()}")
        val read1Msg = String(byte, 0, read1, Charset.forName("GBk"))
        println(read1Msg)
    
        inputStream.read(byte, 10, 20 - read1)
        println("read2后剩余字节数量:${inputStream.available()}")
        val read2Msg = String(byte, 0, byte.size, Charset.forName("GBk"))
        println(read2Msg)
    
    }
    

      这块结合Android端那段代码看正好(一旦索引那想不明白,真不如运行代码来的实在),运行结果如下。
    在这里插入图片描述

    展开全文
  • USB传输文件源代码

    2010-08-20 14:50:56
    通过U口通讯,传输数据及文件源代码 vc.net 工程
  • usb 批量传输测试工具

    2018-03-30 16:54:47
    usb程序由seatrix@126.com创建 使用双缓冲发送数据,做到速度快且不丢失数据,测试平均在700KB/s左右,几乎达到全速 运行 端点1 为读取端点 ...发送内容数值递增,可以通过记录到文件内查看是否丢失数据
  • USB DNS arm板文件传输

    2018-10-28 12:28:09
    zadig-2.3.exe dnw_100ask.exe JZ2440 USB_DNW下载使用手册.pdf
  • USB_DEMO传输文件

    2011-04-10 16:18:47
    USB_DEMO传输文件 提供大家学习用
  • 可用于向开发板传输文件,比如裸机程序,支持Kermit、Xmodem、Ymodem、Zmodem等协议。
  • Android Studio开发的代码,可以通过USB往U盘传输数据,经过测试,可以使用。
  • 为了在无网络的情况下,安全、方便地传输文件,设计一个采用具有USB2.0接口的PIC18F4550单片机和高速无线收发器件nRF24L01构建的无线文件传输系统,介绍了其硬件电路和软件程序设计,并详细阐述了单片机与计算机间的...
  • 在公司做嵌入式的实习,让我讲一个U盘识别成WinUSB设备,实现无驱动。在网上找了很多资料,也下过一些,但是我还是懵里懵懂。借到公司的USB分析仪,抓取了枚举过程中的命令,再...由于是公司的项目,只能上传一些文件
  • 该模块旨在允许您与任何 USB 游戏手柄/控制器交互,只需要一个简单的配置文件。 ##用法 要使用这个模块,你首先需要为你的控制器制作一个 JSON 配置文件。 您需要考虑两种类型的输入,按钮和操纵杆(任何在轴上...
  • NS-USBloader移动 NS-USBloader mobile是Android实现。 请注意:您将需要USB-OTG电缆。 否则,您将要给手机充电。 有时,我会添加有关此项目的新帖子。 执照 源代码许可证或任何更高版本。 标志字体:由乔纳斯...
  • 由于USB最初在设计时,即是为了能够针对具备如传输率、响应时间以及错误帧错等特性的... 控制传输是USB传输中最重要的传输类型,只有正确执行完控制传输,才能进一步执行其他的传输类型。这种传输是用来提供给介于主
  • 文件为MFC的USB通讯例程,开发工具为VS2010,采用BULK传输,通过VID和PID打开USB设备,STM32的程序链接如下: https://download.csdn.net/download/d4l6c8/13092884 本资源为编译后的源代码,包含可执行程序。
  • 嵌入式 usb二进制文件

    2013-11-10 14:13:30
    在嵌入式开发领域中的一个入门机的小资源,用于usb启动开发板
  • android手机如何通过USB和pc互相传输文件啊,使用代码传输,比如在pc上的web浏览器点击某个按钮导入数据至sd卡,或者点击手机app上的某个按钮将文件传到pc硬盘上
  • 下载如下工具即可,可能会以来adb,基于adb方式传输的 下载地址https://www.android.com/filetransfer/#tips 传输速度还可以吧。具体看USB。理论是25Mb每秒,跟adb push 方式差不多。 ...

    下载如下工具即可,可能会以来adb,基于adb方式传输的
    下载地址 备用地址需要科学上网功能

    云盘下载:https://pan.baidu.com/s/1ASqVqkkfDo6agayQEs-8eg 链接:密码:xs28
    在这里插入图片描述
    传输速度还可以吧。具体看USB。理论是25Mb每秒,跟adb push 方式差不多。
    在这里插入图片描述

    展开全文
  • 前面讲过USB一个传输由多个事务组成,一个事务由多个包实体组成。传输又分为控制传输、同步传输、批量传输、中断传输四种,上一节我们讲了控制传输,今天我们主要讲解批量传输。 批量传输和同步传输类似,是使用...

    目录

    1.前言

    2.批量传输的结构

    3.抓包分析

    3.1批量读传输抓包分析

    3.2批量写传输抓包分析

    4.批量传输各速率下支持最大包长度

    5.批量传输事务组成

    6.传输、事务、包组成学习架构图


    声明:前面和后续提到的OUT和IN都是对主机而言的。

    1.前言

    前面讲过USB一个传输由多个事务组成,一个事务由多个包实体组成。传输又分为控制传输、同步传输、批量传输、中断传输四种,上一节我们讲了同步传输细节及事务组成,今天我们主要讲解批量传输及事务组成,批量传输也叫大容量传输

    批量传输和同步传输类似,是使用批量事务(Bulk Transactions)来传输数据。批量读使用批量输入事务,批量写使用批量输出事务。批量传输通常在数据量大、对数据的实时性要求不高的场合,例如USB打印机扫描仪大容量存储设备等,批量传输可以占用任意可用的数据带宽。

    批量传输主要包括批量读传输批量写传输两种,传输事务如下图。

    2.批量传输的结构

    批量传输的事务和同步传输一样,都有只有1个阶段,数据阶段。

    主机如果是批量读数据请求,则数据阶段为一个或者多个IN事务(批量传输事务,事务到后面讲解)

    主机如果是批量写数据请求,则数据阶段为一个或者多个OUT事务;
        
    数据阶段是由一到多个IN/OUT事务组成。这是由于有时候存在一个事务传不完的数据,所以可能存在多个连续IN/OUT事务的情况,在同一次数据传输阶段中事务类型(读写)必定相同。

    注:批量传输的事务和同步传输类似,都有只有1个数据阶段,都是使用IN事务或者OUT事务进行传输,只是两种传输的事务的组成有很小的区别,后期详细讲解。

    3.抓包分析

    3.1批量读传输抓包分析

    因为是设备给主机传输数据,所以是数据阶段是IN事务。

    3.2批量写传输抓包分析

    因为是主机给设备传输数据,所以是数据阶段是OUT事务,如下图。

    4.批量传输各速率下支持最大包长度

    批量传输不支持在低速下,高速最大包长度为512字节,全速下为64字节。

    5.批量传输事务组成

    6.传输、事务、包组成学习架构图

    本架构图后期再学习中会一步一步更新,每一节之后也会逐步完善并更新,最后会完整的展示出来传输、事务、包的结构,让大家在学习过程中对协议框架不混乱。


    1.本文部分素材来源网络,版权归原作者所有,如涉及作品版权问题,请与我联系删除。

    2.未经原作者允许不得转载本文内容,否则将视为侵权;

    3.转载或者引用本文内容请注明来源及原作者;

    4.对于不遵守此声明或者其他违法使用本文内容者,本人依法保留追究权等。

    下面是我的个人微信公众号,关注【一个早起的程序员】精彩系列文章每天不断。

    展开全文
  • USB文件系统

    千次阅读 2016-05-12 10:53:39
    一.U盘的逻辑结构 U盘可以看作以扇区(1扇区 = 512Bytes)为单位线性排列的实体,即0号扇区,1号扇区,2号扇区……U盘也是Flash...对各种USB外设按功能划分大类(class),大类下又再细分小类(subclass),每个类别给予一串特

    一.U盘的逻辑结构

    U盘可以看作以扇区(1扇区 = 512Bytes)为单位线性排列的实体,即0号扇区,1号扇区,2号扇区……U盘也是Flash,对Flash的操作总是以块为单位,因此对U盘的操作是以扇区为单位,整个扇区地读取或整个扇区地写入.

    二 .USB描述符

    对各种USB外设按功能划分大类(class),大类下又再细分小类(subclass),每个类别给予一串特定的符号(Descriptor)供主机辨识。

    每个USB设备只能有一个DEVICE描述符,它指明了该设备属于哪一个大类,是海量存储器,还是人机交互设备,或者打印机扫描仪之类.

    每个DEVICE下可以有一个或多个配置描述符(configuration),以说明该设备含有哪些功能,有几个功能就有几个配置描述符configuration。

    每种配置对应若干个接口描述符(Interface),以描述该配置使用哪些接口与主机进行通信.

    每个Interface又都是端点(Endpoint)的集合,端点就是设备与主机交换数据的最原子单位,每个Interface用到的端点可以是一个或多个.


    三.USB枚举过程

    <1>集线器检测新设备

    主机集线器监视着每个端口的信号电压,有新设备接入时即可察觉.(集线器端口的两根信号线的每一根都有15千欧的下拉电阻,而每一个设备在D+都有一个1.5千欧的上拉电阻,当用USB线将设备和主机接通后,设备的上拉电阻使信号线的电位升高,因此被主机的集线器检测到).

    <2>主机集线器检测到设备之后用中断传输来报告主机,主机收到该中断后会给集线器发送一个GetStatus请求以了解更多的消息。返回的消息告诉主机更多内容。

    <3>集线器重新设置这个新设备

    当主机知道有一个新的设备时,主机给集线器发送一个Set_Feature请求,请求集线器来重新设置端口,集线器使得设备的USB数据线处于重启(RESET)状态至少10ms.

    <4>主机发送一个Get_Status请求来验证设备是否激起重启状态。返回的数据有一位表示设备仍处于重启状态,当集线器释放了重启状态设备就处于默认状态了,即设备已经准备好通过Endpoint 0的默认流程响应控制传输。即设备现在使用默认地址0x0与主机通信.

    <5>集线器检测设备速度

    集线器通过测定那根信号线(D+或D-)在空闲时有更高的电压来检测设备是低速还是高/全速设备(高/全速设备D+有上拉电阻,低速设备D-有上拉电阻)。

    <6>获取最大数据包长度

    主机向address 0 发送USB协议规定的Get_Device_Descriptor命令,以取得缺省控制管道所支持的最大数据包长度,并在有限的时间内等待USB设备的响应,该长度包含在设备描述符的bMaxPacketSize0字段中,其地址偏移量为7,所以这时主机只需读取该描述符的前8个字节。注意,主机一次只能列举一个USB设备,所以同一时刻只能有一个USB设备使用缺省地址0.

    <7>主机分配一个新的地址给设备

    主机通过发送一个Set_Address请求来分配一个唯一的地址给设备。设备读取这个请求,返回一个确认,并保存新的地址,从此开始所有通信都使用这个新地址.

    <8>主机向新地址重新发送Get_Device_Descriptor,此次读取其设备描述符的全部字段,以了解该设备的总体信息,如VID,PID。

    <9>主机向设备循环发送Get_Device_Configuration命令,要求USB设备回答,以读取全部配置信息。

    <10>主机发送Get_Device_String命令,获得字符集描述(unicode),比如厂商,产品描述等等.

    <11>根据Device_Descriptor和Device_Configuration应答,主机判断是否可以提供驱动.

    <12>加载了USB设备驱动以后,主机发送Set_Configuration(x)命令请求为该设备选择一个合适的配置(x代表非0的配置值)。如果配置成功,USB设备进入”配置”状态,并可以和客户软件进行数据传输。

    至此设备开始可以使用.

    四.USB协议

    4.1 数据格式

    USB是一种主从的结构,所有传输由HOST发起.主机发起一次传输的时候,这次传输的包(Packets)中通常包括三个阶段.主机

    首先是发送一个令牌包(Token Packet),可分为输入包(用于设置输入命令)、输出包(设置输出命令)、设置包和帧起始包,其中包含本次传输的命令类型(type),方向(direction),设备的地址(device address)以及端点号(Endpoint).输入包、输出包和设置包格式一样如下:


    帧起始包格式:

    SYNC+PID+11位FRAM+CRC5+EOP

    紧接着是数据包(data packet),就是包含数据了.分为DATA0 包和DATA1包,当USB发送数据的时候,一次发送的数据长度大于相应端点的容量时,就需要把数据包分为几个包,分批发送,DATA0和DATA1包交替发送。但是在同步传输中所有的数据包都是DATA0,格式如下:


    最后将由device返回握手信号包(handshake packet),表示是正确收到了(ACK),还是其他的失败原因.格式:



    同步域(SYNC):8位,值固定为0000 0001,用于本地时钟与输入同步。

    标识域(PID):由四位标识符和四位标识符的反码构成,表明包的类型和格式

    地址域(ADDR):七位地址,代表了设备在主机上的地址,地址0000 0000 被命为零地址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址

    端点域(ENDP):四位

    帧号域(FRAM):11位,每一个帧都有一个特定的帧号,帧号域最大容量0x800,对于同步传输有重要意义。

    数据域(DATA):长度为0~1023个字节,在不同的传输类型中,数据域的长度各不相同,但必须为整数个字节的长度.

    校验域(CRC):对令牌包和数据包中非PID域进行校验的一种方法。

    包结尾域(EOP):发送方在包的结尾发出包结尾信号,主机根据EOP判断数据包的结束.

    USB的传输模型:HOST和设备的某个端点之间可以看成有一条逻辑管道(pipe).Pipe分两种:业务数据流和信令消息.业务流即指纯粹的数据,信令流指控制信息。在信令管道中,有一条默认的管道,就是零地址的零号端点,这条管道在USB设备上电复位或者总线复位后就存在了,便于HOST利用这个地址向USB设备进行配置。

    USB的传输类型有四种:

    控制传输(control transfer):通常只用于在设备复位后HOST通过端点0进行配置.

    块传输(Bulk transfer):譬如U盘的大量数据传输即用此方式。

    中断传输(Interrupt transfer):一般用于人机设备如USB鼠标键盘等.

    等时传输(Isochronous transfer):可以进行带宽控制的实时传输形式.

    4.2 事务

    在USB上数据信息的一次接收或发送的处理过程称为事务处理(Transaction).事务处理的类型包括输入(IN),输出(OUT),设置(SETUP)和帧开始,帧结束等类型.在输出(OUT)和设置(SETUP)事务处理中,紧接着SETUP和OUT包后的是DATA包,DATA0和DATA1交互发送。在DATA包之后设备将回应一个握手信号,如果设备可以接收数据回应ACK包,如果设备忙回应NAK,出错回应STALL。

    输入(IN)事务处理:表示主机从USB设备接收一个数据包的过程



    输出(OUT)事务处理:



    设置(SETUP)事务处理:


     


    五.FAT16文件系统简介

    文件系统的作用是对文件在介质上的存储进行管理,并为操作系统提供操作函数



    大多数情况下的FAT16格式U盘结构如上图所示,如果U盘带有boot功能,则在保留区前还将有MBR和若干个隐含扇区。

    引导扇区(DBR):存储本分区的BPB信息.

    FAT1是文件分配表主表(FAT=File Allocation Table),记录数据区中每个簇的使用情况,其大小根据U盘的实际大小而定。

    FAT2是FAT1的备份,大小与主表一致.

    根文件夹存储文件名目录名等目录信息,固定占据32个扇区大小.

    剩下的数据区就是真正存储数据文件内容的区域.

    在操作一个U盘的文件系统前必须先获取其文件系统信息,可以根据引导扇区计算出FAT1\FAT2、根文件夹以及数据区等的起始地址(对扇区的访问依照其绝对扇区号寻址,绝对扇区号=逻辑扇区号+隐含扇区号,逻辑扇区号是指不计算MBR等隐含扇区的号,DBR的逻辑扇区号总是0,即总是逻辑分区的第一个扇区.)

     

    保留区:若U盘被格式化成boot分区,保留区前含有MBR和若干个隐含扇区。MBR是主引导记录的缩写(Master Boot Record),是物理上第一个扇区(如果它存在的话),因而绝对扇区是0,它就独立于任何一个分区(或者称“卷”)。MBR的前446字节是系统引导程序,接着的64个字节就是分区表DPT(Disk Partition Table),最后两字节是扇区有效标志55 AA.


    DPT以每分区16个字节的大小存放着最多四个主分区的信息。对于U盘来说因为一般只有一个分区,所以其分区信息就存在DPT的第一个16字节中,最重要的是偏移地址为0x1C6 处的信息,它指示着引导记录DBR相对于MBR的偏移地址.上图中该值是0000003F(双字节存放),0x3F=63,即DBR的绝对扇区号是(0) + 63 = 63(意即DBR前面有63个隐含扇区).

    鉴于MBR有的情况下存在有的情况下不存在,在初始化U盘时可以判断扇区号0的内容,然后判断偏移地址54,55和82,83处的ASCII值,如果是DBR,偏移位置54和偏移位置82的内容都会是”FAT”这个字符串,而MBR则不会出现这个字符串.

    DBR扇区(DOS Boot Record)总是位于逻辑分区的第0扇区(逻辑分区第一个),DBR从第一个字节开始就依序存储了重要的分区信息,称为BPB(Bios Parameter Block)


    其中红色部分是计算FAT1起始地址,根目录起始地址、数据区起始地址的重要参数.

    文件分配表 =保留扇区数

    根目录 = 文件分配表起始号+FAT的个数 x 每个FAT的扇区数

    数据区 = 根目录逻辑扇区号 + 32


     

    FAT区:该区包含主表和备份表,两者的内容是完全一致的。FAT表的作用是记录数据区中每个簇的使用情况以及维护簇链的链式关系,是FAT文件系统的核心. 簇是文件系统固定若干个连续的扇区定义为一簇



    文件系统中为了存储每个文件,最小分配单位是簇(以扇区为单位会增加fat表的项数,对大文件存取增加消耗),也就是说即使一个只有几字节大小的文件也是分配一个簇的空间来存放。

    FAT16系统下的FAT表以16bit宽度的数值记录每个簇的使用情况,即数据区中的每一簇在FAT表中占据2个字节以存放信息,所以FAT16最大可以表示的簇号为0xFFFF,以32k为簇的大小的话,FAT16可以管理的最大磁盘空间为32k x 65535 = 2048MB,所以FAT16支持最大2GB分区。

    FAT表实际上是一个数据表,以2个字节为单位,可以称作FAT记录项,通常情况下其第1,2个记录项(前4字节)用作介质描述,从第3个记录项开始记录除数据区文件存储的簇链情况,每簇的使用情况用32位二进制填写,未被分配的簇相应位置写零;坏簇相应位置填入特定值;已分配的簇相应位置填入非零值,具体为:如果该簇是文件的最后一簇,填入的值为FFFFFF0FH,如果该簇不是文件的最后一簇,填入的值为该文件占用的下一个簇的簇号,这样,正好将文件占用的各簇构成一个簇链,保存在FAT表中。0000000H、00000001H两簇号不使用,其对应的两个DWORD位置(FAT表开头的8个字节)用来存放该盘介质类型编号。FAT表的大小就由该逻辑盘数据区共有多少簇所决定,取整数个扇区。




    如上图:FAT表以F8 FF FF FF开头,此2字节为介质描述单元,不参与FAT表簇链关系,小红字标出的是FAT扇区每2字节对应的簇号。相对偏移0x4~0x5偏移为第2簇(顺序上第1簇),此处为FF表示存储在第2簇上的文件(目录)是个小文件,只占用一个簇就结束了。第3簇中(偏移0x6,0x7)存放的数据是0x0005,这是一个文件的首簇。其内容为5,是指接下来的内容位于第5簇,查看第5簇(偏移0xA,0xB)内容为0xFF,0xFF,表示此文件已至尾簇。第4簇(偏移0x8,0x9)存放的数据是0x0006,这又是一个文件的首簇,其内容为6,表示接下来的簇位于第6簇,然后依次第7簇->第8簇->……->第14簇,其内容为0xFF,0xFF,至此该文件尾簇.后面与此类同.

     

    根文件夹,也称文件目录表FDT(File Directory Table),主要存放文件和目录的信息,文件名,创建时间,文件大小等信息即存放于此。文件目录分为两类:根目录和子目录。FAT16的根文件夹固定占有32个扇区的空间,它使用32字节存储每笔记录项,因此FAT16系统中最多只能处理32x512/32 = 512个目录项。

    32字节的目录项数据结构定义如下:


    全部32字节的定义如下:

    ⑴ 0-- 7字节 文件正名。

    ⑵ 8--10字节 文件扩展名。

    ⑶ 11字节文件属性,按二进制位定义,最高两位保留未用,0至5位分别是只读位、隐藏位、系统位、卷标位、子目录位、归档位。

    ⑷ 11--13字节 仅长文件名目录项用,用来存储其对应的短文件名目录项的文件名字节校验和等。

    ⑸ 13--15字节 24位二进制的文件建立时间,其中的高5位为小时,次6位为分钟。

    ⑹ 16--17字节 16位二进制的文件建立日期,其中的高7位为相对于1980年的年份值,次4位为月份,后5位为月内日期。

    ⑺ 18--19字节 16位二进制的文件最新访问日期,定义同⑹。

    ⑻ 20--21字节 起始簇号的高16位。

    ⑼ 22--23字节 16位二进制的文件最新修改时间,其中的高5位为小时,次6位为分钟,后5位的二倍为秒数。

    ⑽24--25字节 16位二进制的文件最新修改日期,定义同⑹。

    ⑾26--27字节 起始簇号的低16位。

    ⑿28--31字节 32位的文件字节长度。

    六,FAT32与FAT16的主要区别


    (1)保留扇区数,FAT16只有引导扇区即DBR,而FAT32除了引导扇区外还有31个保留扇区,主要是留给操作系统进行DBR的备份以及存放其它配置.

    (2)FAT表项从16bit增加到32bit,即数据区的每簇占据FAT表4个字节

    (3)取消了根文件夹区,把文件目录项信息放入数据区,等同普通文件一样.

     

    DBR(DOS Boot Record)引导记录区,其中重要的是BPB(Bios 参数快),定义如下:

    序号 偏移地址 意义
    1 03H~05H OEM号
    2 0BH~0CH 每扇区字节数
    3 0DH 每簇扇区数
    4 0EH~0FH 保留扇区数
    5 10H FAT备份数
    6 11H~12H 根目录项数
    7 13H~14H 磁盘总扇区数
    8 15H 描述介质
    9 16H~17H 每FAT扇区数
    10 18H~19H 每磁道扇区数
    11 1AH~1BH 磁头数
    12 1CH~1FH 特殊隐含磁扇区
    13 20H~23H 总扇区数
    14 24H~25H 物理驱动器数
    15 26H 扩展引导签证
    16 27H~2AH 卷系列号
    17 2BH~35H 卷标号
    18 36H~3DH 文件系统号

    参考:http://wenku.baidu.com/view/2f7f18e2e009581b6bd9eb44.html

    http://wenku.baidu.com/view/3c94d6edb8f67c1cfad6b880.html

    FAT32 Spec from Microsoft FAT32 Spec from Microsoft


    转:http://blog.sina.com.cn/s/blog_4c02ba150101nhaj.html

    展开全文
  • 一款C#开发的Usb单向传输工具,通过LibUsbDotNet.dll动态库进行数据read和write,以及usb设备检测拔插。
  • 1、测试机连接电脑会弹窗提示USB选项,选择USB用于"传输文件",有些手机不支持设置默认USB选项,手机重新连接电脑时都需要手动点击选择USB选项; 2、使用adb命令在真机上安装app时,需要手动点击确认安装按钮。 二...
  • USB过滤驱动框架U盘读写控制,com01串口过滤拦截字符及文件传输。自己编译,支持x86 x64 winxp-win10系统。方便驱动进阶人员使用。
  • usb无法传输大于4g文件怎么办?

    千次阅读 2017-08-29 22:52:52
    win+R快捷键在命令行模式下输入: convert g:/fs:ntfs 其中g为u盘所在盘符
  • USB通信协议——传输

    2020-11-13 06:27:35
    PC主机为了能下达命令,或是传输数据给外围设各,基本上,就必须有一套标准的USB通信协议来实现这个目的。如图所示,为PC主机与设备执行通信协议的整体结构。这个结构相当重要。图中显示了一个通信协议所需包含的...
  • PC 和开发板之间传输文件

    千次阅读 多人点赞 2020-10-21 19:12:15
    传输,方法有多种:网络传输、串口传输USB 传输,当然,还有最笨的方法:U 盘拷贝。 一般的日常开发流程为: a. 在 Windows 上阅读修改代码,然后通过 FileZilla 把代码传到 VMWare 中的 Ubuntu; b. 在 Ubuntu 上...
  • imx6 usb bluetooth的连接与文件传输

    千次阅读 2017-01-10 12:06:23
    hciconfig hci0 iscan 设置蓝牙设备可以被扫描到。 hciconfig hci0 pscan 可以使用hciconfig –help查看帮助。 3.连接设备 启动蓝牙后台进程 root@imx6dlsabresd:~ # /usr/lib/bluez5/bluetooth/...
  • 通过设置系统属性(System Property)[persist.sys.usb.config]即可实现关闭或打开USB调试和文件传输功能,其中mtp表示文件传输,adb表示adb调试,none表示都不启用。
  • Linux下用USB传输文件到开发板

    千次阅读 2013-07-05 19:07:11
    以往用FS2410时用的是minicom+usb2ram,功能比windows下的dnw更强,因为minicom支持彩色显示,不会像dnw一样出现很多乱码,这一点上超级终端做的也不错,可惜不能支持USB传输,加上我们用的是Linux嵌入式系统,平时...
  • usb的bulk传输

    2019-05-11 10:51:19
    bulk endpoint是可选择的。 当USB设备需要传输大量数据的时候,bulk传输可以...例如,传输文件到闪存设备,或者扫描仪,打印机的数据收发。 USB的full speed,high speed,和super speed设备可以支持bulk endp...
  • Android 4.1+通过USB 连接Ubuntu进行文件传输方案

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,081
精华内容 18,032
关键字:

usb怎么设置传输文件