python 轻应用开发|学习笔记

简介: 快速学习python 轻应用开发

开发者学堂课程【AliOS Things 物联网开发教程python 轻应用开发】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/835/detail/13992


python 轻应用开发


内容介绍

一、Python 在 IOT 设备上的实现以及原理

二、应用案例: Python 轻应用打造播报音箱

一、Python 在 IOT 设备上的实现以及原理

这里详细地对每个步骤进行解释。

1.解析:

①Tokenize:使用词法分析法(lexer),将语句拆分成令牌(Token)

②Parser:将令牌(Token)生成解析树(Parse Tree)

例如目前要执行这样两条 Python 语句,第一个是import math,第二个是math.log10(100)。

在执行这两条语句的时候,首先会去根据词法分析器来分析输入词法,词法分析器把语句拆分成令牌。如下:

MP_TOKEN_ KW_IMPORT MP_TOKEN_NAME  

MP_TOKEN_NEWLINE MP_TOKEN_NAME

MP _TOKEN_ DEL_PERIOD MP_TOKEN_NAME

MP_TOKEN_DEL_PAREN_OPEN MP_TOKEN_NAME

MP_TOKEN_DEL_ PAREN_CLOSE MP_TOKEN_NEWLINE

MP_TOKEN_END

可以依次分析,第一个是 MP_TOKEN_KW_IMPORT 这是由输入的 import 语句转化而来的,而math是一个math 库的名字,所以在这里转化为 MP_TOKEN_IMPORT。接下来有 NEWLINE,因为第二行空了一行,所以有了 NEWLINE 的这样的 TOKEN,再然后是下面的函数调用, math 转化为 MP_TOKEN_IMPORT,“.”转化为 MP_TOKEN_DEL_PERIOD。“(”转化为 MP_TOKEN_DEL_PAREN_OPEN 后面是参数和“)”的转换。最后则是结束转化为 MP_TOKEN_END。

从这里可以看出,其实是语句中的每一个词都转华为了代码一样的可以识别的令牌(TOKEN)。下面为 TOKEN 的声明,也就是 mp_token_kind_t. 这些都是列在结构体当中。

ypedef enum_mp_ token_kind_t{

MP_ TOKEN_END,  

MP_TOKEN_ INVALID,

MP_TOKEN_DEDENT_MISMATCH,

MP_TOKEN_LONELY_STRING_OPEN  

MP_TOKEN_NEWLANE,

MP_TOKEN_INDENT,

MP_TOKEN DEDENT,

生成 TOKEN 后,接下来要生成一个解析树,上面的代码从令牌变成解析树。解析树最上层为 file_input_2,这个表达的是执行上文中 python 文件中的一层文件层,下面一层的两个则是内容,接下来的是代码的这部分。那么 input 会将其解析为 QSTR math 这样来作为 input_math 的一个参数。另一个则是调用 QSTR log10这样的一个函数,下方是它的一个参数100,最后解析成下图这样可以直观看到的样子。

 image.png

这些实际在内存中的表现形式则是像下图这样。  

其中 parse_tree.root 为函数的入口,最下面两行是两个地址,第 一个地址指向了上面的 input 的地方,下面的一个地址则是指向了 执行函数,所以再解析之后,根据解析树在内存中找到应该执行的部 分来进行执行。  

下面是代码的一些实现,这里可以看出有 DEL_RULE 以及 DEL_RULE_NC,这个就是其对文件的解析,首先看 DEL_RULE 这个函数,这个函数中有 file_input_2,generic_all_nodes(节点),这里包括它的一些输入包括下面的 input_name,input_from和它的一些 token、rule。主要用到 RULE_NC 和 RULE。  

image.png

●rule: 规则名

●comp :针对该规则要执行的编译动作,在后面的编译环节会用到

●kind :表示后面各个子规则的关系,可能是“或”、“与” 等

●...:当前规则的各个子规则,可能为 rule、opt_rule 或 tok.  

2.编译:

生成一种与平台无关的 bytecode。

MP_PASS_SCOPE- 确定标识符 ID 和种类以及标号数  

MP_PASS_STACK_SIZE- 确定需要的最大栈大小

MP_PASS_ CODE_SIZE- 确定 bytecode 的大小

MP_PASS_EMIT- 生成 bytecode

这里同样实际操作演示,将前文实操数据的解析树转化为 bytecode。 首先可以根据 MP_BC_IMPURT qstr_math推断就是 import 的 math。下面则是把 MP_BC_LOAD_METHOD qstr_log10 加载进来调用的一个方法,这就是在编译的过程中生成的一种和平台无关的 bytecode。 编译返回参数结构体

●kind 为 MPCODE BYTECODE

●fundata 为生成的 bytecode 相关信息,包括了与源代码相关的信息,比如源文件名、跳行信息等,还有实际的 bytecode MP_BC_LOAD_CONST_SMALL_INT_MULTI+MP_BC_LOAD_CONST _SMALL_INT_MULTI_EXCESS  

MP_BC_LOAD_CONST_FALSE+(MP_TOKEN_KW_NONE-MP_TOKEN_KW_FALSE) MP_BC_IMPORT_NAME qstr_math[0:7] qstr_math[8:15]  

MP_BC_STORE_NAME qstr_math[0:7]qstr_math[8:15 ]

MP_ BC_LOAD_NAME gstr_math[0:7]qstr_math[8:15]

MP_BC_LOAD_METHOD qstr_log10[0:7]qstr_log10[8:15]

MP_BC_CALL_METHOD 0 MP_BC_POP_ TOP MP_BC_LOAD_CONST_FALSE+(MP_TOKEN_KW_NONE-MP_TOKEN_KW_FALSE)  

MP_BC_ RETURN_ VALUE

image.png

主要还是利用 MP_COMPILE_TO_RAW_CODE 这样一个方向来实现的,并且使用这个 mp_parse_tree(解析树)作为输入函数,来完成目的。    

3.执行:

(1)利用编译生成的 bytecode,生成 mp_type_fun_bc 对象

(2)在 mp_call_function_0 传入该对象

(3)最终 bytecode 在 mp_execute_bytecode 函数中被虚拟机解释执行

QSTR 是 unique string 的简称,是一种字符串内存驻留方法。我们知道同一个标识符可能在源代码中出现多次,如果我们在每个出现的地方都要保留一份这个标识符的拷贝,就会相当占用存储空间。

MicroPython 采取的方式是在存储空间内仅保留一份标识符主体,而每个标识符主体都有一个索引号,代码中凡是使用这个标识符的地方,都使用其索引号代替。而最终执行时就通过这个索引号去内存中寻找对应的标识符。这就是 MicroPython 中所谓的 QSTR。

刚才可以看到,函数生成之后调用了一个 math 的 log10的方法,实际上就是用了一个 MP_QSTR_log10对应的索引号来进行代替,最终的实现是调用了 mp_cmath_log10_obj 这样一个方法来进行最后实现,也就是在输入这个函数最终回调用到下图的最右方来进行一个处理和执行。  

image.png

4.Micro Python 原理解析总结

总结一下 Micro python 的原理,其实就是分为简单的三步。第一步是解析,就是将输入的 python 语言变成解析树。第二步是进行编译,编译就是生成一种与平台无关的 bytecode。最后一步是执行,就是将 bytecode  里面的一条条的语句最终找到在函数当中的一个个实现来进行执行。

image.png

若想看 python 实现,可以登录 gitee,找到“components”组件,再点击“py_engine”可以找到包括解释器,解释、编译、执行各个步骤,可以找到所有的 python 相关实现。  


二、应用案例: Python 轻应用打造播报音箱

1.阿里云 IoT HaaS 轻应用实验设备介绍

集成阿里专用高性能 MCU-HaaS1000。

支持双频2.4G/5G Wi-Fi, BT5.0/BLE5.0。

丰富的传感器,包含9轴运动传感器,磁力计,温湿度,大气压,光照,声音等传感器。

双屏配置,适应各种场景。

自带1200mA可充电锂电池,可脱离外接电源使用标配 type c 接口,充电/烧录/串口调试一口搞定。

在实验播报音响,需要外界喇叭,其里面传感器等功能非常丰富,很多功能可以直接使用。

2.实操

首先打开 Visual Studio Code,在侧边的插件安装中搜索安装 hass studio。

image.png

安装完成后,可以看到主页下方有三个选项,分别是 C/C++ 开发、JavaScript 轻应用开发、python 轻应用开发。选择 python 轻应用开发下方的python轻应用开发文档。这里有介绍关于 Haas 物联网终端的设备(Haas 100、Haas 200、Haas EDU K1、Haas 506)。本次实验主要针对 Haas EDU K1,所以找到 Haas EDU K1。

image.png

这里有对设备进行完备的介绍,包括环境的搭建、固件下载和烧录。因为是基于 python 应用做一个开发,所以这里需要下载 python 新应用的固件,这里有 python 新应用的下载链接。有 macos 苹果的和 Windows 的固件下载链接。下载好之后,按照这个文档的操作步骤一步一步的进行,就可以将固件烧录到设备中。 这里是已经烧录完成的设备,烧录完成后,开机运行需要通过 USB线连接 PC 端,通过串口,对设备进行连接,这里使用 picocom - b 1500000连接到设备,连好之后,点击回车,可以看到目前在此 python 新应用模式下面的一个 ipo,这就是 python 的命令行,这与在PC端上直接的 python 命令行 一样。例如可以直接输入1+1,点击回车输入结果为2。

image.png

这时返回文档,文档中点击编程接口,可以看到“语法入门”,在其中可以看到 python 的一些基础语法(注释、常见数据类型和运算符、变量申明、控制语句、函数定义、类定义、模块)都有做解释。还有一些基础库的介绍。例如数学函数 math ,点击可以看到关于数学函数的使用示例,可以对照使用示例做实验。

先输入 import cmath,然后调用 cmath.log10然后输入参数100,可以得出结果,也可以输入 cmath.pi 可以查看Π的值,是3.141593。这整个的路径是python的命令行,在后面的实际当中会以直接 python 的文件的一种形式来进行执行。

image.png

接下来展示 python 文件的执行和 python 文件的创建编写工作,首先返回 Visual Studio Code 的快速开始页面,在 python 轻应用开发去创建项目。选择项目名称和创建路径,然后选择 Haas EDU K1 应用作为硬件类型,最后选择解决方案,解决方案里的是示例代码,选择示例代码后,会从云端直接将代码拉下来,可以不用重复做一些代码的麻烦工作。先展示一些使用 eduk1_temp_humi 来进行演示。

image.png

创建好之后会再次弹出 Visual Studio Code 的窗口,这其实是更新了当前的页面,可以发现代码便在页面的左边,点击 solutions 的文件夹,再点击 main.py,这是当前的温湿度传感器的 C 代码,目前仅仅需要在本地执行,所以将这些用不到的代码删掉,并手动编写一些文档。

image.png

打开文档中的应用案例中的参考案例,可以找到,例如传感器数据采集,目前可以做这样的实验,数据采集可以看到 Haas EDU K1内置了 SI7006 温湿度传感器,目前可以通过温湿度传感器记录温湿度的数据,下面是一些温湿度传感器的简介,再下面是代码实现(对 SI7006温湿度传感器的驱动的封装),那要采集温度的话,直接调用这个驱动的封装就可以实现。具体的代码详细的实践就在下方的代码里。

接下来试着编写实践操作:

# -*- coding:UTF-8 -*-

from driver import SPI  

from si7086 import SI7006

Si7006dev=SI7006()

Si7006dev.open(“si7006”)

for i in range(5):

temperature=si7006dev.getTemperature()

print(“temperature=”,temperature)  

humidity=si7006dev.getHumidity()

print(“humidity=”, humidity)  

因为是通过 SPI 进行读取,故输入:from driver import SPI。因为使用的是 si7006传感器,所以接着输入:from si7006 import si7006。准备好之后可以实体化设备,输入:si7006dev = si7006()。实体化之后打开传感器,输入:si7006.open(“si7006”),打开后让其读取五次for循环,输入:for i in range(5),首先读取其温度:temperature = si7006dv.getTemperature(),再将其打印出来:print(“temperature = ”,temperature)。然后读取其湿度:humidity = si7006.getHumidity(),再将其打印出来:print(“humidity = ”,humidity)。目前的测试代码就书写成这样。

image.png

完成之后需要在对代码进行一个基础的检查,检查完毕则接下来进行烧录,烧录的进行目前有两种方式:本地烧录和在线更新。而在线更新需要我们的设备可以连接到我们的网络,将代码可以直接发送到云端,在从云端更新到设备,适用于设备不在身边,远程调试的情况。本次实操使用本地烧录的功能进行演示,本地更新其实是根据串口来进行传输,所以在烧录之前需要先退出串口,不能对烧录串口进行占用,否则串口的数据会在终端控制处进行打印,就无法直接传输到设备上。

这里点击烧录之后,点击本地更新,在选择串口的端口号,接着选择波特率,选好之后终端就开始执行,然后按照提示重启设备,可以看到 amp 以及传输成功的提示(ymodem transfer file finish)就说明当前文件已经传输成功。之后就可以在设备上看到文件,接着重启设备,因为目前的在固定路径执行文件其实会自动运行,这里可以看到,再进入系统之后,系统会自动执行 data/pyamp/main.py 文件,执行之后其实就是将刚才的 log 打印出来,也就是温度、湿度等一些数值循环打印5次。  

温度偏高主要是因为传感器是直接在板上,离 ic 等比较近,对其热量会有一定影响,导致其温度偏高。其湿度处于正常范围。查看现在目前 python 的执行路径,回到 coin 模式下,可以看到在 data 的路径下有 pyamp 文件夹的路径,进入此路径查看,发现文件里包含有 main.py 文件。

可以将其 cat 出来,可以发现 cat 出来的文件,就是刚才做实验编写的代码,可以看出来测试代码实际是将其放在了 data/pyamp 下面,但其实还有 pyamp.zip 的压缩包。

这个压缩包是在开发的时候可能有其他 py 文件或者其他一些资源文件,在传输的时候会把所有 solutions 文件夹下面的文件都进行打包,然后传输到设备端上再全部进行解压,在开机时会自动寻找 data/pyamp 路径下的 main 函数,这是 py 文件下的一个入口,如果存在这样的一个函数,每次启动都会自启动这样的一个文件,这就使得每次进行代码更新或者程序变更后可以自动执行而不需要手动操作。

相关文章
|
9月前
|
索引 Python
Python基础快速入门
Python基础快速入门
78 0
|
11月前
|
存储 数据可视化 索引
Python全栈开发(二)——python基础语法(一)
昨天我们提到了python的环境搭建和入门,今天我们简单说说python的一些语法,因为全栈开发是需要一定的基础的,我们就不过多详细介绍它,如果想了解更多基础的,可以看我写的21天学习python专栏。接下来进入到我们今天的主题。
77 0
|
11月前
|
C语言 开发者 Python
Python全栈开发(三)——python基础语法(二)
我们昨天说了python的数据类型,今天说说python的缩进规则和函数、python的顺序语句结构,条件和分支语句以及循环语句。缩进不规范会报错(IndentationError: unexpected indent),python的函数使用,从定义到实参形参再到分类。
92 0
|
11月前
|
IDE 关系型数据库 MySQL
Python全栈开发(一)——环境搭建和入门
今天是2023年的第一天,接下来的一个月里,我将持续更新关于python全栈开发的相关知识,前面一段时间都是基础语法。主要分成四大块:基础、面向对象、MYSQL数据库、Django框架。话不多说,进入到今天的主题。
188 0
|
11月前
|
存储 SQL NoSQL
Python全栈开发(五)——python数据库MySQL
今天简单说说MySQL,我们存储数据,直接用本地文件即可,但是,本地文件不利于存放海量数据,也不利于用程序对文件的数据进行查询与管理,我们可以使用数据库。
130 0
|
11月前
|
存储 关系型数据库 MySQL
Python全栈开发(四)——python面向对象编程
Python全栈开发(四)——python面向对象编程
90 0
|
存储 数据采集 IDE
一篇文章带你入门python基础开发(1)
一篇文章带你入门python基础开发(1)
158 0
一篇文章带你入门python基础开发(1)
|
索引 Python
一篇文章带你入门python基础开发(2)
一篇文章带你入门python基础开发(2)
97 0
一篇文章带你入门python基础开发(2)
|
JSON JavaScript 数据格式
一篇文章带你入门python基础开发(3)
一篇文章带你入门python基础开发(3)
93 0
一篇文章带你入门python基础开发(3)
|
JSON 自然语言处理 IDE
python 轻应用开发|学习笔记
快速学习python 轻应用开发
108 0
python 轻应用开发|学习笔记