长沙创意网站建设,80 wordpress,网站建设与实践模板,常用的网络营销方法及效果注#xff1a; 1. 本文所分析的fastboot源码不是android下的源码#xff0c;而是恩智浦芯片厂商在IMX6UL芯片的uboot源码中自己实现的源码#xff0c;二者不同#xff0c;请读者注意区分。一些图片是网上找到的#xff0c;出处不好注明#xff0c;请见谅。 2. 分析fastbo…注 1. 本文所分析的fastboot源码不是android下的源码而是恩智浦芯片厂商在IMX6UL芯片的uboot源码中自己实现的源码二者不同请读者注意区分。一些图片是网上找到的出处不好注明请见谅。 2. 分析fastboot udp 是为了后面设计自定义通信协议打基础在自定义通信协议前要考虑的设计细节有很多借鉴现有的好的设计思路对后续设计是很有帮助的。 一、什么是fastboot fastboot是android系统常用的一种刷机方法。android系统设计了2种刷机方式fastboot和recovery。不论是二者中的哪一个都是用来给设备刷写固件的。而刷机其实就是镜像传输烧录fastboot刷机时使用usb来传输镜像文件然后写入对应分区 可以拿过来用需要芯片厂商在底层提供原始实现 fastboot是一种通信协议。基本工作原理就是上位机pc通过 USB 或以太网UDP与引导加载程序uboot通信。它的设计兼容性很好可以在各种设备上运行如 Linux、 Windows 的主机上使用。 就是一种上位机利用USB或者网口和板子通信的机制 fastboot是uboot中的一个命令。在uboot控制台中执行fastboot命令就可以让uboot进入fastboot模式。要实现fastboot刷机只有开发板端uboot是不行的还需要在主机有fastboot.exe配合。 需要pc这边有一个控制软件配合使用 二、fastboot原理 uboot的fastboot的命令会将开发板伪装成一个usb设备。因为开发板本身并不是一个usb设备所以开发板直接插到电脑是没有反应的。伪装之后开发板就被主机windows识别成一个usb设备。 fastboot在开发板和主机间定义了一套协议fastboot协议这套协议以usb为底层传输物理层协议规定了主机fastbooot软件和开发板fastboot软件之间的信息传输规则。在该规则下消息传递可以实现的功能有主机可以向开发板发送命令、开发板可以向主机发送回复、主机可以向开发板发送文件download Fastboot实现方式 主机的fastboot软件和开发板的fastboot程序是怎样通信来工作的呢。平时工作时开发板端只要执行了fastboot命令进入fastboot模式即可开发板这一侧剩下的就不用管了。之后主机端通过运行fastboot命令传递不同的参数来实现主机端和开发板端的通信。 譬如主机端执行fastboot devices则这个命令通过usb线被传递到开发板中被开发板的fastboot程序接收接收后去处理向主机端发送发送信息主机端接收到反馈信息后显示出来。 Fastboot命令执行过程 三、fastboot udp 源码分析 fastboot代码的分析思路 主机端fastboot.exe的源代码是没有的所以主机端不是分析的重点。 开发板端主要分析点就是uboot如何进入fastboot模式fastboot模式下如何响应主机发送的各种命令。 Uboot控制台输入fastboot命令之后会执行 do_fastboot函数 在do_fastboot函数中有两个分支如果终端输入fastboot usb会使用usb进行更新如果输入fastboot udp会使用网口来进行更新。 如果走udp会调用do_fastboot_udp函数来看一下 在do_fastboot_udp函数中又调用了网络循环发送函数net_loop在这个函数中会匹配我们使用的网络协议从而执行相应的函数。 可以看到这里调用了fastboot_start_server函数定位该函数发现在neet/fastboot.c中打开fastboot.c会发现该文件是对fastboot udp方式的核心实现 在fastboot_start_server 函数中首先会打印出使用的网络设备名称以及正在监听的 IP 地址。 fastboot_our_port 被设置为预定义的常量 CONFIG_UDP_FUNCTION_FASTBOOT_PORT这个端口用于接收控制台输入的 fastboot 命令。 如果配置了 CONFIG_IS_ENABLED(FASTBOOT_FLASH)那么会设置一个进度回调函数 fastboot_set_progress_callback(fastboot_timed_send_info)。会在 fastboot 操作过程中定时向主机发送信息。 接着设置 UDP 包的处理函数使用 net_set_udp_handler(fastboot_handler) 设置了一个 UDP 数据包处理函数为fastboot_handler。到时所有接收到的 UDP 数据包都会被 fastboot_handler 函数处理。 最后清空服务器 MAC 地址。使用 memset 函数将 net_server_ethaddr 数组中的内容全部置零。这是为了在服务器 IP 地址发生变化时清除旧的 MAC 地址信息。 可以看到在fastboot_handler中前半段都是一些必要的初始化和拆包处理注意这里把数据包头部的信息复制到 header 结构体中就行。重点看switch中的执行逻辑这里通过检查数据包的头部信息然后会根据不同的请求类型采取相应的动作。如果是查询请求 (FASTBOOT_QUERY)则直接响应如果是初始化 (FASTBOOT_INIT) 或者执行 (FASTBOOT_FASTBOOT) 请求则根据序列号来确定是否需要发送响应或者重发数据包。如果接收到的数据包类型不被识别则会反馈一个错误信息给对方。 这里面都调用了fastboot_send函数来看看这个函数 在fastboot_send中首先进行了一些初始化准备工作让packet指针偏移到填充数据的地方以及判断是否要重传上一次数据包。接着为待发送的数据做准备工作先将本地字节序转换为网络字节序将response_header回复包的头部信息拷贝到待发送的packet指针所指向的空间中指针继续向后偏移 接着会根据接收到的数据包的头部信息去构造不同的响应数据包如果是查询请求 (FASTBOOT_QUERY)则构造一个包含sequence_number的响应包如果是初始化请求 (FASTBOOT_INIT) 则构造一个包含udp_version和其长度信息的响应包如果是出错请求FASTBOOT_ERROR则会构造一个包含错误信息的响应包 如果是 (FASTBOOT_FASTBOOT) 请求先判断当前命令是否是FASTBOOT_COMMAND_DOWNLOAD是的话再看当前有没有剩余数据没有数据的话调用fastboot_data_complete函数来处理数据下载完成的情况包括发送响应、输出日志、设置环境变量以及重置状态等操作。如果还有数据的话会调用fastboot_data_download函数来接收主机传过来的数据。 如果当前没有待处理的命令则复制命令到 command 并设置 pending_command 为真。 否则调用 fastboot_handle_command 来处理命令并更新 pending_command 如果接收到的数据包类型不被识别则会打印出错误信息。 将响应字符串response拷贝到响应包pkcket中最后调用uboot自带的一个底层udp包发送函数net_send_udp_packet将构建好的响应包发送出去。 如果响应字符串的前四位是“OKAY“会匹配当前cmd去执行对应操作。如果响应字符串以 OKAY 或 FAIL 开头则重置 cmd。 四、fastboot udp中的帧格式 其中id是一个枚举 FASTBOOT_QUERY代表了是一个快速请求类型的数据包告诉我你当前待接收的包序号 FASTBOOT_INIT 代表了是一个获得初始化信息类型的数据包告诉我你的udp版本以及你一包数据是接多大 FASTBOOT_FASTBOOT代表了是一个命令或者文件类型的数据包 flags在发送端发出的包中为1在接收端发出的包中为0 seq代表当前包的一个序号 包的结构大概是这样的 五、fastboot udp中的重传机制 接收端的udp包处理函数fastboot_handler在接收到udp包后会先对比包头中的seq序号和我本地这边等待接收的包序号seq_num做一个对比如果二者一致说明是我想要的包调用fastboot_send0,在send函数中做数据的一个处理并构建相应的反馈包发送给发送端如果seqseq_num – 1则认为发送端没有收到我的反馈包会调用fastboot1在send函数中重发上一次发送的反馈包。在fastboot接收端中从头到尾不论是命令包还是数据包都有包序号都是根据包序号是否匹配来唯一判断是否接收正确虽然拿不到上位机侧的协议源码但可以推测发送端也一定是这样只看序列号对不对。 六、fastboot udp 命令底层怎么执行 在这个函数中会循环对比预先定义的命令结构体数组中是否有传进来的命令相同的如果有则会调用对应结构体中的命令处理函数。 七、fastboot udp中如何扩展指令 可以看到到这是厂商自己添加的两个命令要实现添加自定义指令首先需要在最开始定义指令的结构体数组中添加字节定义的指令名称并填好这个指令的处理函数的入口地址 接着在下面按照厂商的实现形式仿写一个命令处理函数即可。