MicroPython入坑记(一)(ESP8266 ESP32)
手上有块基于ESP8266的NodeMCU板子,没错,就是那个10块钱的带WIFI的芯片,当时感觉又便宜又又有wifi,并且可以用脚本lua写代码,果断买买买,然后玩了一下WIFI跟树莓派通讯(树莓派开Http Server,然后用lua通过socket模拟http指令定期获取树莓派的指令)。控制了个继电器加灯泡玩了玩,手头上的dht11也能直接读出来(nodemcu内置驱动了),然后就没有然后了,感觉lua不是我的菜,用惯了python,写lua还是十分别扭的.嗯对lua的吐槽开始:
1.没有高层次的封装,缺少轮子,虽然有cjson,socket等可用,然而没有httpclient之类更高层次的封装,搞个rest 请求还得自己写http头,虽然也不麻烦,然而用惯了urllib的python用户自然不是很爽。lua本身是作为C的嵌语言设计的,所以基本库太有限,虽然网上配合lua的C库众多,然而想搞进nodemcu的固件里,我这半吊子水平还是有难度的,一句话就是nodemcu提供的功能,可以很好的搞,没提供的功能干瞪眼。
2.一些语法上的吐槽,比如默认全局变量,局部变量要加local之类的,年代久远,记不清了总之用惯了python习惯了优雅的设计,就不习惯丑陋了(引战了引战了)
3.固件开发不活跃,现在github上的代码基本都是几年前的了,虽然最新的2.1.0发布于2017年8月,看看changelog,其实就是一个18B20驱动的重写,没有什么大改进。这也是国人类似项目的一贯作风:为了卖板子然后找个大神移植下固件,然后能把东西卖出去就OK了,至于固件的演进,看大神的的心情了……
4.nodemcu只能用在esp8266上,当然esp32也可以跑了,然而也就这样了,参照上边那条,开发不活跃啊,不像micropython或者espruino(一个跑在单片机的javascript固件),官方就支持好多的MCU
所以后来有了Arduino for ESP8266,就用Arduino IDE耍去了,那个支持的MCU多(lll¬ω¬),以前其实也知道有MicroPython,但大神说因为8266资源有限,被裁减的太厉害(其实当然完全不是那么回事)啥也干不了,不如等ESP32(然后我就真等ESP32了)。
经过漫长的等待,ESP32的板子终于价格降到心理价位,然后果断入坑,当然是刷MicroPython了,然后为了对比,顺便把手上的8266也刷上了MicroPython固件,搞起来,先看可用内存:
ESP8266:
>>> micropython.mem_info()
stack: 2112 out of 8192
GC: total: 35968, used: 9376, free: 26592
No. of 1-blocks: 50, 2-blocks: 10, max blk sz: 264, max free sz: 1261
嗯,8K的的栈,36K的堆确实小了些,然而……esp32也好不到哪儿去
>>> micropython.mem_info()
stack: 736 out of 15360
GC: total: 111168, used: 6864, free: 104304
No. of 1-blocks: 26, 2-blocks: 8, max blk sz: 264, max free sz: 6402
纳尼?说好的400+Kb的内存呢,怎么只有110K左右?(虽然比8266是好多了)
经过探索gayhub上的代码,终于明白了原因:
因为esp8266的资源太有限,所以用的是non-os的SDK,这样能最大化的分配内存的使用,而ESP32用的是基于FreeRTOS的ESP-IDF。micropython只是作为一个线程跑在FreeRTOS上,所以分配的堆就小了些(110K)并且有个哥们现在写了个Multi-Heap的补丁,通过多次申请堆内存,能让可用内存达到200K+,不过因为改动量比较大,暂时没有合并进MicroPython的主线。所以想写大量的程序,现阶段还是用Arduino或者直接C+ESP-IDF撸代码比较靠谱,当然我是当玩具玩,其实8266的35K也可以玩玩了。
更新:micropython写大量的逻辑也是可以的,就是把代码写成库,编译为mpy文件并集成到固件中在代码中调用,因为集成在固件中的库是直接在ROM执行的,可以节省大量的RAM空间。