嵌入式用HTTP请求下载bin文件

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是提交数据。

关于STM32利用移远4G模组HTTPS下载bin文件的AT指令程序,可以分为以下几个步骤: 1. 初始化移远4G模组:使用AT指令初始化移远4G模组,包括设置通信波特率、APN等参数。 2. 建立TCP连接:使用AT指令建立与服务器的TCP连接,确保连接成功。 3. 发送HTTPS请求:使用AT指令发送HTTPS请求,包括请求头、请求体等参数,确保请求成功。 4. 接收HTTP响应:使用AT指令接收HTTP响应数据,包括响应头、响应体等数据,确保接收完整。 5. 解析HTTP响应:解析HTTP响应数据,获取bin文件下载链接。 6. 下载bin文件:使用AT指令下载bin文件,确保下载成功。 具体实现方法可以参考以下代码: ```c #include "usart.h" /* 移远4G模组AT指令 */ const char *AT_Init = "AT+IPR=115200\r\n"; const char *AT_Reset = "AT+CFUN=1,1\r\n"; const char *AT_SetAPN = "AT+CGSOCKCONT=1,\"IP\",\"APN\"\r\n"; const char *AT_SetServer = "AT+QHTTPURL=\"https://www.example.com/binfile.bin\"\r\n"; const char *AT_SetHeader = "AT+QHTTPHEADER=3\r\n"; const char *AT_GetHeader = "AT+QHTTPHEADER?\r\n"; const char *AT_HttpAction = "AT+QHTTPGET=80\r\n"; const char *AT_ReadData = "AT+QHTTPREADFILE=\"/flash/binfile.bin\"\r\n"; /* USART串口发送数据 */ void USART_SendString(USART_TypeDef *USARTx, char *str) { while (*str) { while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); USART_SendData(USARTx, *str++); } } int main(void) { /* 移远4G模组初始化 */ USART_SendString(USART1, AT_Init); USART_SendString(USART1, AT_Reset); USART_SendString(USART1, AT_SetAPN); /* 建立TCP连接 */ USART_SendString(USART1, AT_SetServer); USART_SendString(USART1, AT_SetHeader); USART_SendString(USART1, AT_GetHeader); USART_SendString(USART1, AT_HttpAction); /* 接收HTTP响应 */ USART_SendString(USART1, AT_ReadData); while (1); } ``` 需要注意的是,以上代码只是一个简单的框架,具体实现还需要根据实际情况进行调整和完善。同时,还需要针对移远4G模组的AT指令进行详细了解。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值