一抬手写了个论文一般的标题也是把我自个儿吓了一跳,毕业后遗症吧hhh
春节在家躲肺炎,闲着也是闲着,把之前规划的智慧终端拎出来开发一波。
需求大致是,需要具备ai算力,通过串口和第三方数据采集模块交互数据,基于数据进行计算、推理、预测等业务,通过4G(支持后期切换5G)和服务器收发数据,支持在线更新业务代码。
根据需求选型,嘉楠耘智的k210几乎就是为这样的需求量身订制的一样跃入我的视野,sipeed基于k210设计的模组Maix M1如下图:(算了感兴趣自个儿淘宝看吧
4G联网模组选了合宙的air720,外加air530 GPS模块。分别采购了对应的开发板,搭建了原型机验证系统。
接下来就是调代码了。M1模组自带Maixpy固件,源自micropython,采用python作为开发语言可以说非常好上手了,几乎不用面对底层驱动,对于用过freescale、stm32、arduino、altra/xilinx fpga/zynq的我来说,难点(没有)大概就是怎样调通业务代码吧。
第一个点是串口通信,需要用到3组串口,正好k210有3组串口。这里值得提一下k210有一个引脚重分配的功能还是很好使的,省去了找对应功能引脚的功夫。贴代码:
from fpioa_manager import fm
from machine import UART
fm.register(21, fm.fpioa.UART1_TX, force=True)
fm.register(22, fm.fpioa.UART1_RX, force=True)
fm.register(23, fm.fpioa.UART2_TX, force=True)
fm.register(24, fm.fpioa.UART2_RX, force=True)
fm.register(32, fm.fpioa.UART3_TX, force=True)
fm.register(15, fm.fpioa.UART3_RX, force=True)
uart_1 = UART(UART.UART1, 115200,8,0,0, timeout=1000, read_buf_len=4096)
uart_2 = UART(UART.UART2, 115200,8,0,0, timeout=1000, read_buf_len=4096)
uart_3 = UART(UART.UART3, 115200,8,0,0, timeout=1000, read_buf_len=4096)
需要注意的是,maix模组官网的wiki上的demo代码都是基于Maxi Dan开发板的,我用的Maixduino引出的管脚与Dan略有区别,所以demo code不能照抄,尤其board_info这个类基本用不上,引脚编号只能按照实际的来。
第二个点是如何和air720模块交互,让4G模块连上网。遵循合宙提供的用户手册逐条发送AT指令没啥毛病,不过在最后向服务器发送数据内容时如何发送结束符0x1A卡壳了一会儿。在以往嵌入式c的开发中,串口发送一个字节稀松平常,但是python怎么进行字节操作没了解过(python现学现用的),具体到micropython又是否有区别。查了下micropython手册,有个uart.writechar()满足需求,到maixpy里一试,解释器说不认识这个writechar,好吧,固件没移植全。尝试直接write(0x1A)解释器又不认,最后的解决办法是,定义一个char型变量done,然后uart.write(done),贴代码:
done = chr(0x1a)
uart_3.write(done)
网连上了,数据交互实现了,考虑到在线更新业务代码需要传代码文件,决定采用ftp的方式获取新代码。这里要感谢下鑫哥的技术支持,对一个嵌入式工程师来说要临时搭建一个tcp+ftp的服务器调试环境似乎不是一两个小时能搞定的事,况且没有现成的云服务器可以用,就想到了向互联网工程师鑫哥求助,非常给力,下午沟通的需求晚上就上线了。
用合宙4G模块ftp模式获取新代码,遵循用户手册逐条发送AT指令也没啥大毛病,有一点,设置网络承载模式的时候手册里给的命令是AT+SAPBR=3,1,"APN","",实测会报+CGEV: ME DEACT然后挂住,参考了simcom的ftp调试经验贴,发送AT+SAPBR=3,1,"APN","CMNET"就没问题。
调通了ftp,可以收到新代码内容了,接下来就是文件操作保存新代码。关于Maixpy下的文件操作感觉官方wiki给的资料比较少,摸索了一会儿得出一套解决方案,直接上代码吧:
import os
import uos
os.chdir("/flash")
f = open('app.py','w')
f.write(read_str)
f.close()
(代码是截取的,结合业务逻辑取用)
新代码存好了,用一个exec()调用新代码,这样在线更新的动作就算完整了,贴代码:
with open("app.py") as app:
exec(app.read())
至此,能想到的代码瓶颈都解决了,coding部分就慢慢扩充吧,下一步打算用用KiCAD画demo板。用惯了altiumdesigner和cadence,听说KiCAD用起来很轻巧,应该挺适合这个项目的,(主要是它支持mac OS)。这里推荐下电子森林https://www.eetree.cn/ ,里面不仅有KiCAD的教程还有丰富的电子工程师资源。
特别感谢娇妻shawn小妞的情感支持。
祝愿这场疫情尽快好转,放我们出去玩。向全体抗疫工作者致敬,冒牌以及添乱的的不算。
以上。