RM新时代网站-首页

聚豐項(xiàng)目 > 自研Python解釋器

自研Python解釋器

PikaScript是一個完全重寫的超輕量級python引擎,具有完整的解釋器,字節(jié)碼和虛擬機(jī)架構(gòu),可以在少于4KB的RAM下運(yùn)行,用于小資源嵌入式系統(tǒng)。相比同類產(chǎn)品,如MicroPython,LuaOS等,資源占用減少85%以上。 入選2021年度 Gitee最有價值開源項(xiàng)目,加入RT-Thread嵌入式實(shí)時操作系統(tǒng)編程語言類軟件包。 在CH32V103 RISC-V開發(fā)板上完成了PikaScript的部署,并為CH32V103提交了PikaSciprt標(biāo)準(zhǔn)BSP和驅(qū)動模塊包,并完成了交互式運(yùn)行的驅(qū)動。

lyon1998 lyon1998

分享
2 喜歡這個項(xiàng)目
團(tuán)隊(duì)介紹

lyon1998 lyon1998

團(tuán)隊(duì)成員

lyon1998 開發(fā)者

分享
項(xiàng)目簡介
PikaScript是一個完全重寫的超輕量級python引擎,具有完整的解釋器,字節(jié)碼和虛擬機(jī)架構(gòu),可以在少于4KB的RAM下運(yùn)行,用于小資源嵌入式系統(tǒng)。相比同類產(chǎn)品,如MicroPython,LuaOS等,資源占用減少85%以上。 入選2021年度 Gitee最有價值開源項(xiàng)目,加入RT-Thread嵌入式實(shí)時操作系統(tǒng)編程語言類軟件包。 在CH32V103 RISC-V開發(fā)板上完成了PikaScript的部署,并為CH32V103提交了PikaSciprt標(biāo)準(zhǔn)BSP和驅(qū)動模塊包,并完成了交互式運(yùn)行的驅(qū)動。
硬件說明

RT-Thread使用情況概述:

整個方案涉及的技術(shù)棧有:RT-Thread線程和定時器, 編譯原理、字節(jié)碼設(shè)計、虛擬機(jī)設(shè)計、PikaScript部署技術(shù)和驅(qū)動模塊開發(fā)技術(shù)等等。通過這個作品,擴(kuò)充了PikaScript的BSP支持列表,驗(yàn)證了PikaScript和rt-thread的兼容性,驗(yàn)證了PikaScript在小容量(64Kb)RISC-V架構(gòu)的部署能力和兼容性。

內(nèi)核部分:使用了線程、定時器 。

軟件包:

PikaScript軟件包


硬件使用了RTT大賽提供的CH32V103開發(fā)板,使用了板上的LED資源用于指示腳本運(yùn)行狀態(tài),為GPIO硬件開發(fā)了Python腳本模塊,用于測試腳本驅(qū)動拓展功能。

image.png

軟件說明

0.摘要


PikaScript是一個完全重寫的超輕量級python引擎,具有完整的解釋器,字節(jié)碼和虛擬機(jī)架構(gòu),可以在少于4KB的RAM下運(yùn)行,用于小資源嵌入式系統(tǒng)。相比同類產(chǎn)品,如MicroPython,LuaOS等,資源占用減少85%以上。

入選2021年度 Gitee最有價值開源項(xiàng)目,加入RT-Thread嵌入式實(shí)時操作系統(tǒng)編程語言類軟件包。


本項(xiàng)目在CH32V103 RISC-V開發(fā)板上完成了PikaScript的部署,為CH32V103提交了PikaSciprt標(biāo)準(zhǔn)BSP和驅(qū)動模塊包,并完成了交互式運(yùn)行的驅(qū)動。


1.方案選型——CH32V103運(yùn)行Python腳本,并不好辦

首先我們需要選擇一個能夠在CH32上運(yùn)行的嵌入式Python解釋器。


能夠在flash為64Kb的RISC-V MCU上部署Python解釋器,需要有極小的編譯體積,還不能依賴于ARM架構(gòu)的獨(dú)享技術(shù)。

首先排除通用Python解釋器CPython,不說CPython需要依賴linux,單是體積就可以排除。


其次在嵌入式領(lǐng)域大火的MicroPython技術(shù)是有可能選用的備選項(xiàng),但是MicroPython在ARM平臺需要最少128Kb的體積,而RISC-V平臺的GCC編譯器優(yōu)化成熟度不如ARM平臺,所以編譯體積只會更大不會更小,所以MicroPython不能在本次的CH32V103平臺部署。


好了,不賣關(guān)子了,能夠在CH32V103平臺部署的Python解釋器,只有我目前在開發(fā)的PikaScript超輕量級Python解釋器,(如果還有其他方案,請批評指正,我麻溜修改)。雖然相對于MicroPython,PikaScript沒有那么完整的標(biāo)準(zhǔn)庫支持,但基本的運(yùn)行時對象、控制流、交互式運(yùn)行都是可以實(shí)現(xiàn)的,且PikaScript的跨平臺能力非常好,在極限的依賴管理策略下,PikaScript只依賴LibC,在任何平臺都幾乎沒有依賴缺失問題,或許還能夠運(yùn)行在FPGA軟核中(理論上可行,未驗(yàn)證)。


另外感謝Gitee提供的開源平臺,PikaScript剛剛被Gitee評委大佬們選入GVP——最有價值開源項(xiàng)目,所以如果你現(xiàn)在打開Gitee首頁,大概率可以看到PikaScript的金色牌牌。


image.png


PikaScript還入選了rt-thread軟件包,rt-thread真的是非常有活力的開源社區(qū)

image.png

PikaScript嚴(yán)苛的依賴管理策略,使得部署非常輕松,這是跨平臺,易部署的特點(diǎn)。但是單純的易部署并沒有什么用,如果難以拓展功能,就只是一個花瓶而已。我們知道在MCU開發(fā)領(lǐng)域,一直是C語言的天下,C語言的生態(tài)占據(jù)MCU開發(fā)的80%以上,大部分MCU都有廠家提供的C語言開發(fā)套件,因此MCU平臺的Python解釋器,最重要的拓展手段,就是綁定C語言的原生庫,將C語言庫綁定為Python模塊,這通常被稱為Python的C模塊。


為MicroPython綁定C語言模塊與通用的CPython類似,需要將C庫編譯為靜態(tài)庫,再進(jìn)行鏈接,鏈接時需要手動注冊許多全局表,且制作C模塊的過程中需要使用大量linux平臺獨(dú)有的工具,這對于以Windows平臺開發(fā)為主的MCU工程師來說,門檻很高。


而PikaScript可以在MCU工程師熟悉的Windos平臺完成C模塊的開發(fā),通過自研的模塊預(yù)編譯器,能夠自動完成模塊的注冊工作,C模塊的開發(fā)者需要提供的僅僅是一個用Python寫成的模塊的調(diào)用API而已,預(yù)編譯器會自動將這個Python文件預(yù)編譯為C文件,完成模塊的鏈接和注冊。而只要使用正確的命名,原生的C的函數(shù)就能夠被自動注冊進(jìn)模塊中,供解釋器調(diào)用,也不需要編譯靜態(tài)庫。


讓PikaScript在CH32V103跑起來,意思也就是開發(fā)一個能在CH32V103運(yùn)行的PikaScript固件。


我們先看一下一個PikaScript固件有哪些部分。



image.png

在圖中標(biāo)注黃色的部分是我們需要制作的,而綠色部分是跨平臺的,我們只需要拉取源碼進(jìn)行編譯即可,不需要修改。


從下往上看,首先是需要一份PikaScript的BSP,BSP也就是板級支持包,這通常只要將廠商提供的MCU的標(biāo)準(zhǔn)庫稍加整理即可獲得。然后是PikaScript的啟動器,這包含了固件入口main.c,以及基本的設(shè)備初始化代碼,包括對printf的支持。


有了BSP和啟動器,就已經(jīng)可以運(yùn)行PikaScript的固件了,只不過還只能使用PikaScript提供的標(biāo)準(zhǔn)庫功能和Python的基本語法,還不能使用MCU上搭載的外設(shè)資源。


為了使用CH32V103的外設(shè)資源,我們還需要開發(fā)CH32V103的驅(qū)動模塊,在這個項(xiàng)目中,我們開發(fā)了GPIO的驅(qū)動模塊和基于rt-thread tick定時器的延時模塊。


最上層的就是我們要運(yùn)行的Python腳本了,模塊預(yù)編譯器也可以處理Python腳本,根據(jù)腳本中導(dǎo)入的模塊來自動裁剪固件,在腳本中沒有import的固件會被自動裁剪掉,我們可以在main.py中選擇要加入固件的模塊,以及編寫系統(tǒng)初始化后最先運(yùn)行的Python腳本,將其燒錄進(jìn)固件中。


2.制作BSP和啟動器——先跑起來再說

BSP通常是用芯片的原廠提供的例程制作的,在這個項(xiàng)目中,我們就使用CH32V103的官方例程中的uart_printf和MounRiver River Studio生成的rt-thread模板來制作。完成了對rt-thread模板的一些剪裁之后,再加入printf的初始化函數(shù),對項(xiàng)目稍作整理,BSP部分就完成了。


PikaScript的啟動器的制作也比較簡單,在main.c中添加#include “pikaScript.h”并調(diào)用pikaScriptInit()函數(shù)即可啟動PikaScript。pikaScript.h和pikaScriptInit()都是由預(yù)編譯器自動生成的,在制作啟動器之前,需要拉取PikaScript的源碼。


PikaScript官方(其實(shí)就是我自己)提供了一個包管理工具,只需要編寫requestment.txt,就可以從gitee中自動拉取相應(yīng)版本的源碼和模塊。在拉取內(nèi)核源碼時,預(yù)編譯器也會自動被拉取下來,我們在main.py中寫入import PikaStdLib,然后用我們使用拉取下來的預(yù)編譯器進(jìn)行預(yù)編譯,就能得到pikaScriptInit()函數(shù)了。


包管理工具不僅可以拉取內(nèi)核,還可以拉取模塊,也就是說我們自己制作的CH32V103的驅(qū)動模塊,也可以掛到PikaScript模塊庫中,進(jìn)行自動拉取。


BSP和啟動器的制作我錄制了一個視頻教程,想要了解細(xì)節(jié)或者想自己制作BSP的大佬可以看視頻了解。

https://www.bilibili.com/video/BV1Cq4y1G7Tj

image.png


3.制作CH32V103的驅(qū)動模塊


接下來我們制作CH32V103的驅(qū)動模塊,使得CH32V103上面的外設(shè)資源能夠被Python腳本調(diào)用到。


在這個項(xiàng)目中,我們制作了一個PikaScript的標(biāo)準(zhǔn)設(shè)備驅(qū)動,什么是標(biāo)準(zhǔn)設(shè)備驅(qū)動呢?我們先從其他的腳本技術(shù)說起,比如MicroPython,并沒有統(tǒng)一的外設(shè)調(diào)用API,這使得用戶在使用不同的平臺時,都需要重新學(xué)習(xí)API,比如下面這個是MicroPython在STM32F4平臺驅(qū)動GPIO的代碼。

image.png

這個是ESP8266的

image.png

可以明顯看到在選擇pin的管腳時,一個用的是字符串,而另一個用的是整型數(shù),驅(qū)動的API標(biāo)準(zhǔn)很混亂。


有沒有什么辦法,能夠統(tǒng)一外設(shè)的API,使得用戶只需要熟悉一套API,就能夠在任意平臺通用呢?


方法是有的,就是PikaStdDevice標(biāo)準(zhǔn)設(shè)備驅(qū)動模塊!


2e08e56afb970732848d87d438968ef.png


PikaStdDevice是一個抽象的設(shè)備驅(qū)動模塊,定義了所有的用戶API,而各個平臺的驅(qū)動模塊只要從PikaStdDevice繼承,就能夠獲得一模一樣的用戶API,而PikaStdDevice內(nèi)部會間接調(diào)用平臺驅(qū)動,通過多態(tài)特性重寫底層的平臺驅(qū)動,就可以在不同的平臺工作了!


以GPIO模塊為例,以下是PikaStdDevice定義的用戶API


image.png


以下是PikaStdDevice需要重寫的平臺驅(qū)動


image.png


而我們要制作的CH32V103的GPIO模塊,就從標(biāo)準(zhǔn)驅(qū)動模塊中繼承。


image.png


通過這個方法,我們就可以讓STM32的驅(qū)動模塊、CH32的驅(qū)動模塊、ESP32的驅(qū)動模塊有著一模一樣的用戶API!用戶只要熟悉了一套API,就可以輕松使用支持了PikaScript標(biāo)準(zhǔn)驅(qū)動模塊的所有平臺!這才是真正的跨平臺!


下面是部分被注冊在驅(qū)動模塊里面C原生驅(qū)動函數(shù)


image.png


驅(qū)動模塊的開發(fā),我也制作了兩個視頻,供想要了解細(xì)節(jié)的大佬們參考。

https://www.bilibili.com/video/BV1aP4y1L7pi

https://www.bilibili.com/video/BV1Jr4y117Z8

image.pngimage.png


4.支持交互式運(yùn)行


PikaScript不依賴文件系統(tǒng),只要傳入字符串就可以運(yùn)行,所以只要制作支持字符串讀取的串口驅(qū)動,就可以支持交互式運(yùn)行了!

下面是本項(xiàng)目中支持交互式運(yùn)行的驅(qū)動代碼。

814ff1c9b9753da64901baf10be7c7b.png


5.main.py初始化腳本


image.png

最后我們編寫一段用Python寫成的初始化腳本,在固件啟動后運(yùn)行,初始化GPIO,并且獲得一個系統(tǒng)對象,用于提供延時功能。在初始化結(jié)束后,led閃爍10次,并打印hello pikascript!


編寫好初始化腳本后,用預(yù)編譯器就可以集成在固件中了。


下面是預(yù)編譯器生成的初始化函數(shù)


image.png


項(xiàng)目地址:

PikaScript-CH32V103參賽項(xiàng)目倉庫:

https://gitee.com/lyon1998/ch32v103-pika

PikaScript總倉庫:

https://gitee.com/lyon1998/pikascript

https://github.com/pikastech/pikascript

演示效果

在演示視頻中,演示了PikaScript的啟動和交互式運(yùn)行,包括:

  1. 1.測試了PikaScript的Python腳本交互式運(yùn)行功能。

  2. 2.使用led對象的high()方法和low()方法,控制IO的電平,進(jìn)而控制LED燈。

  3. 3.測試了PikaScript解釋器對Python變量的動態(tài)創(chuàng)建的支持。

  4. 4.測試了PikaScript對Python標(biāo)準(zhǔn)庫函數(shù)print的支持,包括打印整型數(shù)和字符串?dāng)?shù)。

  5. 5.測試了PikaScript解釋器對運(yùn)算符以及組合運(yùn)算的支持。

  6. 6.測試了PikaScript解釋器對條件運(yùn)算符的支持和對控制流的支持。

  7. 7.測試了PikaScript對多行Python腳本交互式運(yùn)行的支持。

  8. 8.測試了sys對象的delay()系統(tǒng)方法,該方法基于rt-thread延時函數(shù),驗(yàn)證了與rt-thread操作系統(tǒng)的兼容性。

  9. 9.循環(huán)打印1-1000整型數(shù),測試了腳本的運(yùn)行速度。

評論區(qū)(0 )
RM新时代网站-首页