开箱体验
试用背景
去年年初,有新项目要让移动式容器设备的监控数据上云,选型时主要考虑三个系列STM32L0、STM32G0和STM8。最初有意向选用STM32L052RB,主要是为了满足低功耗需求。恰逢G0系列上市,价格亲民,性能却要高很多,但顾虑G0推出不久,生态不够成熟,项目周期又赶得紧,综合考虑,最终采用STM8。但用过之后,发现STM8不适合这个项目,最尴尬的,就是AD采样不准和主频太低,16MHz主频下,无法实现快速的IO翻转。
2019年底,电堂发起了G0试用活动,申请到一块,用来完善一下这个移动式容器设备监控数据上云的项目。配合移远的BC28模块,STM32G0+BC28,实现数据上云。
开箱检验
NUCLEO-64的板子,外形尺寸都差不多,如图。
报告组成
之前做过G4的试用,流程是先使用后整理报告,整理报告的时候又重新看了一遍当时设计的手稿,消耗时间长,且要点容易遗忘。本次优化一下试用流程,一边使用,一边记录,把最原始的体验记录下来,以免时间一过,又忘了干净。
试用分为两部分:① NUCLEO-G071RB + IOT-AT3080V1.0 + X-NUCLEO-IKS01A2连接阿里云;② NUCLEO-G071RB + BC28 + X-NUCLEO-IKS01A2连接阿里云。为什么采用这样的方式,前面学习过L4连接阿里云IoT的教程,当时是在NUCLEO-L4R5ZI上调试的,想先把相应的工程移植到G0上来,实现上行链路打通,之后再将WiFi模块替换为BC28,这样调试起来也会方便。
试用过程
NUCLEO-G071RB通过WiFi连接阿里云
项目的软件框架、IAR工程及文件结构与L4的Demo类似,只是底层将L4的HAL改成了G0的HAL。
一、MCU外设的使用
使用的外设包括:与WIFI扩展板的接口、与传感器扩展板的接口、虚拟串口接口、USER按键接口和LED等。下面将NUCLEO-L4R5ZI接口与NUCLEO-G071RB接口做一个对比展示,方便后续移植时对比参考。
1、与WIFI扩展板的接口
2、与传感器扩展板接口定义
3、虚拟串口接口
4、按键与LED灯
同时,Systick提供系统延时,并未Paho协议栈提供Timer。
二、使用CubeMx生成原始工程
CubeMx生成原始工程的过程不详述,按照2.1.1的外设配置,配置对应的引脚、接口即可。系统主频配置为64MHz,TIM2_PWM控制灯以0.5s间隔闪烁,故预分频为:1280-1;分频后计数时钟为50KHz,自动重载寄存器值为50000-1,捕获/比较寄存器值为25000。配置界面如下:
三、软件移植与调试
移植Paho MQTT协议栈、移植mbedtls,调试温湿度传感器,适配Paho MQTT的过程在L4的教程中有详细描述,从L4上将代码移植到G0上,主要是Flash读写有写不一样。L4是双bank的Flash,Flash的操作较麻烦,相对而言,G0的操作要简单很多,参考SDK中的Flash例程修改flash_l4R.c文件,(路径:STM32Cube_FW_G0_V1.3.0ProjectsNUCLEO-G071RBExamplesFLASHFLASH_EraseProgram),主要是修改FLASH_unlock_erase()函数和FLASH_get_bank()函数,修改后,编译无误。
下载调试过程,没有想象中那么顺畅,输入wifi信息时,一切正常,连接wifi也正常,但输入三元组信息,一直报错:
Error erasing at 0x08018000
调试①:Wifi信息用默认的,软件执行到三元组保存的位置,仍然同样的错误。数据是保存的同一个位置的,应该不是Flash函数读写的问题。
调试②:注释掉net_if_init()函数中wifi信息获取相关代码,即不运行wifi信息获取及wifi初始化过程,只运行三元组信息保存的过程,保存正确;
调试③:重新开启wifi初始化过程,用已经设置正确的参数配网、连接阿里云,软件运行正常;可以在云端看到上报的数据。
这进一步证明三元组保存的相关函数,是没有问题的,但为何加上wifi配置相关的代码后,会影响三元组信息保存呢,单步调试发现,当运行到EMW3080_GetVersionInfo()函数的*temp=0时,FLASH的SR寄存器的BIT CFGBSY就会置位,进一步排查发现,执行完temp = strstr(Token, ",")后,没有查到到“,”,temp为0x00,此时给地址0x00的位置赋值,导致FLASH的SR寄存器的BIT CFGBSY置位。
解决方法:判定temp值,如果不为空,才执行赋值操作,如下图示:
问题到这里已经完美解决了,指针跑飞,导致运行异常。那为什么在L4的板子上没有出现这个问题呢?(具体的表现:执行完EMW3080_GetVersionInfo()函数后,三元组信息及后续的Flash保存操作都无法完成,因为CFGBSY一直为1)
分析L4和G0的HAL_FLASHEx_Erase()→FLASH_WaitForLastOperation(),有如此的不同:
L4没有CFGBSY位,仿真发现,当执行*temp=0语句时,FLASH状态寄存器并没有发生变化,但这并不能说L4就是没有问题的,给地址为0x00000000的位置写数据0,可能会带来不可预期的结果。
四、Demo演示与现象
正常运行的效果截图,包括云平台日志和终端日志截图。
终端日志:
云端日志:
终端日志:
云端日志:
终端日志
云端日志:
终端日志:
云端日志:
NUCLEO-G071RB通过NB连接阿里云
在NUCLEO-G071RB通过WiFi连接阿里云基础上,修改网络设备层的相关配置,将WIFI改为NB模组(BC28),外设和CubeMx的原始工程都之相似。
一、软件移植与调试
有NUCLEO-G071RB通过WiFi连接阿里云的基础后,移植过程相对来说简单。Demo运行时,每5s的数据上报是正常的,但是温度异常报警上传后,会导致软件跑飞,分析程序发现,软件是在发送完报警信息,再发送下一条正常上报信息时,发送不成功,触发重新连接,重新连接三次失败后软件跑飞。
重连的机制是有问题的,就算是重连失败,程序也不应该跑飞;经查实,发现网络层操作了一个零指针,增加了防护机制;
导致数据发送失败是跑飞的原因,为何数据会在发送完一条异常报警信息后,在下一次的正常数据帧中报错?我在L4的程序上运行,是正常的,问题肯定是由G0导致的。
软件上排查了一大圈,排查的过程就不描述了,最终定位到,在发送完异常报警帧后,NB模块重启了,BC28这个模块有个特点,必须发送AT+CFUN=1后才能响应后续的联网指令,因而网络一直连接不成功。
比较坑的是,买完BC28模组后,在官网上并没有下载到原理图,因而不清楚各个引脚的分配布局(Arduino接口的UART、供电是固定的,所以调试还是没有问题的),找店家询问也一直没有响应,最终,通过前项目的FAE拿到了原理图,发现用于报警状态指示的LED灯(PA5),连接到了Arduino接口的D13上,而在BC28的板子上,D13是RESET引脚,当发送完报警信息后,会控制LED状态变化,此时就相当于复位了BC28!禁用掉点灯相关操作,问题解决。
关于这个调试,前后忙活了两个礼拜(当然只有下班和周末零碎的时间弄),开始一直怀疑是软件移植带来的bug,拼命的查软件问题,弄错了方向。
二、Demo演示与现象
Demo运行效果,云平台日志与NUCLEO-G071RB通过WiFi连接阿里云相似,终端日志如下:
总结
整体说来,本次试用还算比较顺利,除了移植3080B、BC28外,还尝试移植了ESP8266的驱动,STM32G0无论是速度还是外设资源,都要比8位机强大的多。将云连接移植到G0上实现还是有意义的,G0比其他系列更有性价比,也能跑起Paho等轻量级的协议栈。在以后的应用中,采用G0上云的方案会更有用武之地。
点击链接观看更多相关课程:
电堂科技c.51diantang.com