1、使用场景
单片机OTA的bin文件,一般是通过无线下载,电脑端用http将bin文件上传到服务器,单片机再将bin文件从服务器下载,一般能通过网页下载的文件都可以用http请求文件。
2、从套接字开始建立http请求
lz在亚马逊的s3服务器实现了bin文件的下载处理,下面通过rt-thread的txt文件举例,bin文件也是一样请求方式,数据处理相对可能不同。
浏览器输入以下2个网址,都可以访问到文本。
http://www.rt-thread.com/service/rt-thread.txt
https://www.rt-thread.com/service/rt-thread.txt
https的意思是加密传输,浏览器的处理方式是http格式。
单片机访问一般是从建立套接字开始,建立套接字不同的区别是,一个是普通的tcp套接,一个是建立ssl的套接,ssl连接一般是用mbedtls来加密。
建立套接字,需要ip和端口,从这个网址,要提取出域名是www.rt-thread.com,http的端口一般都是80。
再举个例子,亚马逊的文件,假如浏览器访问文件下载如下。
http://xxxx.s3-us-west-2.amazonaws.com/xxxx.bin
提取出的域名是s3-us-west-2.amazonaws.com,端口80,其他内容是建立套接字,http的请求头要包含的内容,
3、建立套接字
以esp8266的AT指令举例,连上网wifi后,建立tcp套接字,然后发2个指令开启透传。u0是调试串口,用于将接收的内容转发到u6,u6是连接esp8266的串口。
u0 len = 42.data = AT+CIPSTART="TCP","www.rt-thread.com",80
u6 len = 57.data = AT+CIPSTART="TCP","www.rt-thread.com",80
CONNECT
OK
u0 len = 14.data = AT+CIPMODE=1
u6 len = 20.data = AT+CIPMODE=1
OK
u0 len = 12.data = AT+CIPSEND
u6 len = 21.data = AT+CIPSEND
OK
>
收到<,意味着开启透传,退出透传发送+++,退透传不带回车换行,正常的AT指令要带回车换行(\r\n)
4、HEAD请求
请求头信息的使用,一般OTA的时候,命令需要带长度和CRC,如果只知道文件的名字,而不知道大小,可以用HEAD请求。
格式如下,注意2条指令都需要回车换行,发给esp8266时,还需要再加回车换行。
HEAD /xxx/xxx.bin HTTP/1.1
Host: www.xxx.com
xxx是从浏览器能访问到的网址中提取,举例如下,
发送
HEAD /service/rt-thread.txt HTTP/1.1\r\n
Host: www.rt-thread.com\r\n\r\n
收到了rt-thread.txt的头部信息,GET请求的时候,每次请求都会带有这个头部信息,加一些格式信息,不同文件的头部信息可能不同,要留意的是
”Content-Length: 267“,表示文件的大小,GET分段请求的时候,表示实际请求到的大小。
u0 len = 65.data = HEAD /service/rt-thread.txt HTTP/1.1
Host: www.rt-thread.com
u6 len = 299.data = HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:19:00 GMT
Content-Type: text/plain
Content-Length: 267
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
5、GET 请求
通过头部请求,我们能知道大小,如果一次可以接收完,可以用以下格式请求,将HEAD改为GET。
GET /xxx/xxx.bin HTTP/1.1
Host: www.xxx.com
举例发送
GET /service/rt-thread.txt HTTP/1.1\r\n
Host: www.rt-thread.com\r\n\r\n
返回如下
u0 len = 64.data = GET /service/rt-thread.txt HTTP/1.1
Host: www.rt-thread.com
u6 len = 566.data = HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:33:17 GMT
Content-Type: text/plain
Content-Length: 267
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
RT-Thread is an open source IoT operating system from China, which has strong scalability: from a tiny kernel running on a tiny core, for example ARM Cortex-M0, or Cortex-M3/4/7, to a rich feature system running on MIPS32, ARM Cortex-A8, ARM Cortex-A9 DualCore etc.
提取内容的时候,需要将267提取出来,然后查找2个连续\r\n\r\n,找到数据内容,开始存储267个字节。
bin文件一般比较大,所以需要分段请求,格式如下,加一个如下字符串,从xxx字节请求到xxx字节,字节计算0为第一个字节。
GET /xxx/xxx.bin HTTP/1.1
Host: www.xxx.com
Range: bytes=xxx-xxx
举例,请求前100个字节
GET /service/rt-thread.txt HTTP/1.1\r\n
Host: www.rt-thread.com\r\n\r\n
Range: bytes=0-99\r\n
返回如下
u0 len = 82.data = GET /service/rt-thread.txt HTTP/1.1
Host:www.rt-thread.com
Range:bytes=0-266
u6 len = 420.data = HTTP/1.1 206 Partial Content
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:39:21 GMT
Content-Type: text/plain
Content-Length: 100
Connection: keep-alive
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Range: bytes 0-99/267
RT-Thread is an open source IoT operating system from China, which has strong scalability: from a ti
请求100字节到267,返回如下
u0 len = 84.data = GET /service/rt-thread.txt HTTP/1.1
Host:www.rt-thread.com
Range:bytes=100-266
u6 len = 490.data = HTTP/1.1 206 Partial Content
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:43:35 GMT
Content-Type: text/plain
Content-Length: 167
Connection: keep-alive
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Range: bytes 100-266/267
ny kernel running on a tiny core, for example ARM Cortex-M0, or Cortex-M3/4/7, to a rich feature system running on MIPS32, ARM Cortex-A8, ARM Cortex-A9 DualCore etc.
当请求字节大于实际字节时候,会返回从开始字节到剩余的字节大小。
一般请求OTA的bin文件,可能是1024大小,需要有重新请求的逻辑设计,可能请求出去了,没收到包的返回,也不要漏了最后一包不够1024字节时候的重新请求,再根据实际获得的返回,来做一些flash的存储,存储完成后读取出来算下crc对不对,不同编译器编译出来的bin文件可能是大端存储,如果是小端MCU烧写时,需做字节处理。
举例请求超过剩余字节返回如下
u0 len = 83.data = GET /service/rt-thread.txt HTTP/1.1
Host:www.rt-thread.com
Range:bytes=0-1023
u6 len = 588.data = HTTP/1.1 206 Partial Content
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:45:28 GMT
Content-Type: text/plain
Content-Length: 267
Connection: keep-alive
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Range: bytes 0-266/267
RT-Thread is an open source IoT operating system from China, which has strong scalability: from a tiny kernel running on a tiny core, for example ARM Cortex-M0, or Cortex-M3/4/7, to a rich feature system running on MIPS32, ARM Cortex-A8, ARM Cortex-A9 DualCore etc.
POST的用法和GET一样,将GET替换成POST就好,举一个例子。
u0 len = 82.data = POST /service/rt-thread.txt HTTP/1.1
Host:www.rt-thread.com
Range:bytes=0-10
u6 len = 330.data = HTTP/1.1 206 Partial Content
Server: nginx/1.10.3 (Ubuntu)
Date: Thu, 28 Apr 2022 11:48:07 GMT
Content-Type: text/plain
Content-Length: 11
Connection: keep-alive
Last-Modified: Tue, 18 Sep 2018 03:55:48 GMT
ETag: "10b-5761d43d95900"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Range: bytes 0-10/267
RT-Thread i
GET和POST的区别用法,可以搜下其他大佬的说法。一般来说GET是获取数据,POST是提交数据。