STM32F103代码远程升级(五)基于MQTT协议WiFi远程升级代码的实现


在实现了基于YModem和XModem协议的单片机代码更新之后就在琢磨如何真正实现远程升级,直接通过网络就可以更新代码。
参考了网上很多关于WIFI通信升级的帖子,先梳理了一下WiFi通信升级的流程,然后开始着手实现这一功能。
首先是WiFi通信模块的通信工具的选择,我这里选用的是ESP8266。
然后是通信协议的选择,可以选择自定义通信协议,不过因为ESP8266模块有MQTT的库可以直接调用,因此这里我选用的是MQTT协议作为WiFi模块和服务器之间的通信协议。


一、WiFi模块的选用与介绍

我选用的是基于乐鑫esp8266的NodeMcu开发板,具有GPIO、PWM、I2C、1-Wire、ADC等功能,结合NodeMcu 固件为原型开发提供最快速的途径。
官方网站:
NodeMcu --像Arduino一样简单的开源可编程固件
NodeMcu特点
NodeMcu开发板操作起来很简单,使用Lua脚本语言对其进行操作。如果没有入这款开发板,直接用ESP8266接上必要的外围电路,然后利用ESP8266的串口就可进行烧写了。如此要使用NodeMcu的固件只需要将其固件烧写到ESP8266上即可。下面将介绍NodeMcu固件库的烧写过程。


二、ESP8266的固件擦除与烧写
1、ESP8266 Flash擦除工具的安装与使用。

在写ESP8266的控制代码时,偶尔会遇到需要彻底擦除Flash里的内容,然后重新烧写的情况,这里介绍一款比较好用的Flash擦除工具—esptool.py
(1)首先安装python环境,版本不宜过高,最好在2.0~3.0之间;
(2)安装完成后通过cmd输入python,若出现相关版本信息,则安装成功。
(3)使用:先找到安装python的文件夹,看是否该文件夹下存在esptool.py,若存在则通过cmd运行该程序,例如在我的安装情况下运行:
C:\Python27\Lib\site-packages>esptool.py --port COM4 erase_flash
这句话的意思就是擦除串口4连接的ESP8266的Flash。等待擦除完成之后我们就可以往里面重新烧写固件了。

注意:在运行命令前,一定要先将ESP8266置于Flash模式,即必须先将GPIO0引脚拉低。

2、ESP8266固件烧写
(1)在线获取固件文件

NodeMCU custom builds
NodeMcu提供在线生成固件,用户可以根据自己的需要选择模块生成固件,NodeMcu会将集成好的固件文件发送至用户邮箱,只需通过邮箱里的链接即可下载我们所需要的固件。烧写地址(0x00000)
模块选择

(2)获取SDK init数据

在如上所述,通过esptool.py完全擦除芯片之后,需要先给ESP8266烧写SDK之后再烧写NodeMcu固件。
NodeMCU版本是针对Espressif SDK的特定版本编译的。SDK在闪存中保留用于存储校准和其他数据的空间。此数据在SDK版本之间更改,如果它无效或不存在,则固件可能无法正确启动。
Espressif SDK下载
解压该压缩包之后在bin文件夹下就能找到我们所需要的SDK文件。

  • esp_init_data_dedault.bin 初始化其他射频参数区,至少烧录一次。烧写地址(0x3FC000)
  • blank.bin 初始化RF_CAL参数区,烧写地址(0x3FE000)
(3)ESP8266 Flash烧写工具的使用

使用的是ESP8266Flasher.exe
下载安装好,运行该文件,先选择串口,然后配置文件,可以将SDK和固件一次性下载到ESP8266模块中,如图:
烧写固件
然后点击Flash按钮,若出现芯片的MAC地址,则表示开始烧写中,然后等待片刻,当左下角出现绿色的圆标打勾,则表示烧录完毕。


三、NodeMcu基于Lua脚本开发
1、上传代码到ESP8266

选用的上传代码工具为ESPlorer
需要Java运行环境,下载安装之后,通过串口连接ESP8266,打开串口,然后重启ESP8266,若是固件烧写成功,则串口会打印相应的固件模块,并且提示“lua: cannot open init.lua”。
ESPlorer工具的窗口布局如下图所示:
ESPlorer窗口
左侧窗口主要用于查看和编辑Lua脚本,然后通过左下角的按钮可以将编辑好的Lua脚本保存(Save to ESP)、发送(Send to ESP)以及上传(Upload to ESP)到ESP8266上。
最右侧的纵向列表显示了目前ESP8266上所存的lua脚本数量。
运行NodeMcu首先得先写好init.lua脚本,然后上传到板子上,再重启运行。init.lua就相当于C语言中得main()函数,是程序的入口,必不可少的部分。

2、init.lua 连上WiFi

一切准备就绪之后我们就可以开始着手编写我们的lua脚本了。
没有接触过lua,则可以先通过教程简单学习一下lua编程。Lua教程
要运行lua脚本,可以选择命令行运行的lua.exe,或者编译环境友好的SciTE.exe以及LuaStudio。目前我用的最多的是后面两款工具,其中LuaStudio在试用阶段特别的好用。
利用Lua模块,可以直接将WiFi连接配置的部分写成一个模块然后直接在init.lua中调用WiFi连接函数即可。具体代码如下:

--wifi_cfg.lua
local module = {}
local led = require("led")
local function mWifiConfig()
	wifi.setmode(wifi.STATION)
	local station_cfg = {}
	station_cfg.ssid = "WiFi名字"
	station_cfg.pwd = "WiFi密码"
	station_cfg.save = false
	wifi.sta.config(station_cfg)
	
	local cfg = {}
	cfg.ssid = "NodeMCU"
	cfg.pwd = "20180719"
	wifi.ap.config(cfg)
	wifi.sta.autoconnect(1)
end

function module.connectWIFI()   -- timer1
	print('Setting up WIFI date in 20180730...')
	mWifiConfig()
	led.LEDInit()
	--connect to a wireless network 
	tmr.alarm(1, 1000, tmr.ALARM_AUTO, function()
		if wifi.sta.getip() == nil then 
			print('Waiting for IP ...')
			led.RedLED()
		else
			print('IP is ' .. wifi.sta.getip())
			led.GreenLED()
			tmr.stop(1)
		end
	end)
end
return module


-- init.lua
local my_wifi = require("wifi_cfg")

-------main---------
--connect wifi 
my_wifi.connectWIFI()

然后将wifi_cfg.lua和init.lua两个文件一起上传到ESP8266上,上传完成之后,重启板子,然后ESP8266就连上了WiFi了。

3、更多ESP8266 关于lua脚本开发

在学习NodeMcu时,在网上找到了不少好的帖子,里面关于NodeMcu入门lua开发讲得很详细了,这里就不再赘述了,贴出链接供大家学习。

NodeMcu之旅(一):构建、刷入固件、上传代码
NodeMcu之旅(二):断线自动重连,闪烁连接状态
NodeMcu之旅(三):响应配置按钮
NodeMcu之旅(四):实现Web配置页面

看完网上的教程后发现,教程中所用的代码大多数是NodeMcu提供的官方文档中的样例改写来的,所以,多多研究官方的API,想要什么功能自己实现就好了。
NodeMcu官方文档

四、通信协议的选择与使用

在学会了如何用lua脚本控制WiFi模块之后,现在就需要着手选择通信协议了,这里我用的是MQTT。
因为MQTT可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
并且NodeMcu固件库中包含了MQTT模块,其中关于MQTT的客户端与代理服务器的连接,订阅和发布消息的操作都很简单。

1、MQTT协议原理

关于MQTT协议的介绍和原理,网上有许多帖子介绍的,这里就贴出,我学习时看的帖子。
MQTT协议简介及协议原理
MQTT协议解析

2、搭建MQTT代理服务器

在知道了协议通信原理之后,就可以在本地搭建一个MQTT的代理服务器了,方便日后的调试使用。
这里我用的是Apache Apollo 服务器。在安装之前需首先安装JAVA jdk,配置环境变量,注意版本不要太高。
(1)Apollo服务器下载,下载地址 直接下载 apache-apollo-1.7.1-windows 的安装包。下载后解压到一个文件夹,注意路径不要包含中文。安装时参照安装手册 一步一步安装即可。
(2)创建apollo的服务器应用实例,通过cmd进入apache-apollo-1.7.1的目录里面运行apollo.cmd create mybroker,如下:

F:\apache-apollo-1.7.1-windows-distro\apache-apollo-1.7.1\bin\apollo.cmd create mybroker

(3)创建成功之后进入mybroker文件运行服务器,如下:

F:\apache-apollo-1.7.1-windows-distro\apache-apollo-1.7.1\bin\mybroker\bin>apollo-broker run

(4)启动服务后,在浏览器上面输入:https://127.0.0.1:61681/或http://127.0.0.1:61680/使用默认的用户名和密码登录 (admin;password),进入服务器页面,如图:
Apollo服务器

3、安装MQTT客户端

搭建好代理服务器之后,再安装一个MQTT客户端,即可测试MQTT通信协议了。因为MQTT属于订阅/转发类的通信协议,而MQTT的代理服务器只具备信息转发功能,所以我们可以使用ESP8266作为一个客户端,PC即是客户端又是代理服务器,通过ESP8266发布消息,PC端订阅消息,则可以实现两者之间的通信。
这里我安装的PC客户端是MQTT.fx 通过配置代理服务器的IP和端口号即可连接。
mqtt.fx

后面涉及到测试ESP8266通过MQTT接收16进制数,我又使用了另一个串口工具:通信猫调试软件,一款很小但是功能齐全的串口调试工具,也可以连上MQTT代理服务器,并且能够发送16进制数据
通信猫串口工具


五、基于MQTT协议WiFi远程升级的具体实现
1、自定义MQTT文件发送客户端

在测试了ESP8266通过MQTT与代理服务器连接良好,并且之间通信16进制数据也正常之后,此时面临的问题就是,没有合适的MQTT客户端能够直接发送文件。而且因为ESP8266的接收缓存有线,所以一个更新文件我们也不能一次性发送,所以得分包发送。
如此,最好的就是自定义一个可以分包发送文件的客户端,我主要负责单片机方面的开发,所以自定义的客户端具体实现过程我也不太清楚。这里就说下我使用的客户端的满足的要求。
(1)满足TCP连接,能够正常连接上MQTT代理服务器;
(2)能够读取出文件大小及文件名;
(3)能够将文件分成指定大小的数据包,并且加上包头,校验和包尾后通过发布消息发送给代理服务器。

2、客户端与ESP8266的通信过程

完成了以上所有工作之后,最后的就是协调客户端和ESP8266之间的通信了。
这里我通过订阅主题update接收来自客户端的文件数据包,当然这里我上传给客户端的文件是直接可执行的bin文件。
然后客户端通过订阅主题back来接收单片机的反馈信息。
主要通信过程为:
(1)单片机做好更新程序的准备后,发布主题为back,消息为–请求的数据包号给客户端;
(2)客户端收到单片机做好准备的标识和包号之后,通过识别包号,发布主题为update,消息为—包数据给ESP8266;
(3)单片机收到一包数据处理完成之后,请求下一包;
(4)客户端收到请求之后发送下一包数据,直至文件发送完成,发送结束标识。

这里客户端发送的第一包也可包含文件大小和文件名,然后单片机的处理就类似与YModem协议处理即可。
通过ESP8266远程升级单片机程序,除了通信协议不一样,其余部分都可按照之前说的YModem和XModem协议处理即可。


参考链接

STM32远程升级(基于串口本地升级与WiFi通信远程升级)
基于WiFi的车载终端远程软件升级方法

### 回答1: STM32是一款性能优异、功能强大的微控制器。要搭建mqtt_stm32 mqtt协议功能,我们需要先了解MQTT协议MQTT是一种基于发布/订阅模式的轻量级物联网通信协议,可以用于物联网设备之间的互联。 在STM32上实现MQTT协议,我们需要先下载MQTT库文件,并将其导入到STM32工程中。然后,我们可以使用MQTT API函数进行mqtt协议的功能实现MQTT API函数有连接、订阅、发布等多种功能,并可以根据不同的需求进行二次开发。例如,可以实现定时发布数据、自动连接网络等功能。 在实现mqtt_stm32 mqtt协议功能时,我们需要注意以下几点:首先,要确保使用的MQTT库文件版本能够适配当前的STM32芯片;其次,要根据具体的应用场景选择MQTT服务端,而且要保证连接稳定性和安全性;最后,要注意消息质量的控制,如保证消息的可靠传输、避免消息重复发送等。 总结来说,搭建mqtt_stm32 mqtt协议功能需要掌握MQTT协议的基本知识以及使用MQTT库文件和API函数进行开发的技能。通过不断地实践和优化,我们可以实现高效、稳定、安全的mqtt协议功能,在物联网应用中发挥巨大的作用。 ### 回答2: MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种轻量级的消息传输协议,适合于物联网设备和低带宽、不可靠网络的通信。STM32是一款嵌入式微控制器芯片,具有广泛的应用领域和丰富的外设接口,可以方便地搭建MQTT通信功能。下面介绍STM32搭建MQTT协议功能实现的几个关键步骤。 第一步,选择合适的MQTT库。市面上有很多MQTT库可以选择,如Eclipse Paho MQTT、Mosquitto MQTT等。在选择时应根据自身需求选择相应的库。例如,对于运行在STM32上的MQTT客户端应用程序,可以选择具有小内存占用和低功耗特性的Paho MQTT库。 第二步,配置MQTT参数。 MQTT协议中需要配置一些参数来定义客户端唯一标识符和连接的服务器地址等。对于STM32,可以通过定义宏和结构体来配置这些参数。例如,可以定义一个MQTT_InitTypeDef结构体,用于保存MQTT连接配置参数,以便在连接函数中传递。 第三步,编写MQTT连接功能。STM32通过与MQTT服务器建立TCP连接来实现MQTT通信。可以编写一个连接函数,用于初始化TCP连接并完成MQTT连接握手。在连接握手后,STM32可以使用MQTT Pub/Sub发布/订阅功能来进行数据传输。 第四步,编写数据传输功能。在STM32上,可以使用MQTT客户端API发送和接收MQTT消息。例如,可以编写一个数据发送函数,用于MQTT Pub数据,将数据传输到MQTT中心服务器。同时,还可以编写一个数据接收函数,用于MQTT Sub数据,从MQTT中心服务器接收数据。 第步,应用其他STM32外设。STM32还可以与其他外设结合使用,例如通信模块、传感器等,实现更多应用场景。例如,可以使用STM32 ADC采集传感器数据,并通过MQTT发布到MQTT服务器。 通过以上几个步骤,可以快速搭建STM32 MQTT功能。但需要注意的是,MQTT协议通信需要考虑网络环境、数据传输安全性等问题,需要进行充分测试和验证,才能确保可靠运行。 ### 回答3: STM32是一种微控制器,可以用来实现MQTT协议MQTT是一种轻量级的消息协议,适用于物联网应用程序。它可以在较低带宽和不稳定的网络中实现可靠的通信,并且可以在设备之间传输小量的数据。在本文中,我们将学习如何在STM32上构建MQTT实现MQTT协议功能。 首先,我们需要准备一些材料: 1. STM32微控制器 2. MQTT库 3. MQTT服务器 4. 一些连接材料 然后,我们需要安装所需的库文件并设置MQTT服务器。我们可以使用Eclipse或Keil等软件进行开发。 在我们开始构建MQTT之前,我们需要了解一些MQTT协议的关键概念。 1. 代理 代理是一个程序,它可以接收消息并将消息传递给其他代理或设备。在MQTT中,代理可以是客户端,服务器或代理。 2. 主题 主题是消息的地址或标识符。客户端将消息发送到特定主题,并且服务器也会订阅特定主题以接收消息。 3. QoS QoS是消息传递的服务质量等级。在MQTT中,可以使用0、1或2级QoS。 4. 订阅 订阅是客户端将主题与服务器连接的过程。一旦客户端订阅了主题,它就可以接收到该主题的消息。 5. 发布 发布是客户端向服务器发送消息的过程。 接着,我们需要编写代码实现MQTT协议功能。我们可以使用MQTT库API来实现。根据我们的需求,我们可以使用3个级别的QoS来发送和接收消息。 最后,我们连接STM32到MQTT服务器并测试。我们可以从服务器向设备发送消息并检查设备是否正确接收消息。 总之,STM32可以很容易地实现MQTT协议功能。使用MQTT,我们可以建立可靠的连接,并在低带宽和不稳定的网络中进行消息传递。这种技术在物联网应用程序中非常实用。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微芯供氧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值