亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        編譯型嵌入式Python的設(shè)計與實現(xiàn)

        2024-01-22 06:03:52李春亭王宜懷施連敏
        計算機工程與設(shè)計 2024年1期
        關(guān)鍵詞:嵌入式

        李春亭,王宜懷,施連敏,2,張 露

        (1.蘇州大學(xué) 計算機科學(xué)與技術(shù)學(xué)院,江蘇 蘇州 215000;2.武夷學(xué)院 認知計算與智能信息處理福建省高校重點實驗室,福建 武夷山 354300)

        0 引 言

        近年來,人工智能行業(yè)發(fā)展迅速,尤其是機器學(xué)習(xí)算法已被廣泛運用在各種領(lǐng)域中[1],Python隨著人工智能的潮流成為了熱門編程語言之一。在嵌入式編程領(lǐng)域中,以往都是使用C語言進行編程,然而在Python成為熱門語言后[2],也出現(xiàn)了MicroPython[3]解釋器。

        MicroPython[4]是一款能夠運行于Windows系統(tǒng)、Unix系統(tǒng)和部分微控制器上的超小型Python解釋器,它把龐大的Python解釋器壓縮到256 KB以內(nèi)并且能夠支持大部分的Python3功能。文獻[5]中提到Python語言有著比C語言更優(yōu)秀的可讀性和可靠性,使用MicroPython能夠有效提高編程效率。然而解釋器特點使得它占用了Flash空間和更多的計算資源,不適合用于開發(fā)有著低資源占用和高實時性要求的嵌入式應(yīng)用。因此目前使用MicroPython編寫的應(yīng)用大多都是實時性要求不高的,比如教育機器人[6,7]。要在微控制器上真正使用Python編寫嵌入式應(yīng)用,必須找到一種提高Python運行效率的方法。

        因此本文針對上述問題提出了編譯型嵌入式Python方案,該方案基于類型注釋和靜態(tài)分析實現(xiàn)了Python轉(zhuǎn)C++的翻譯器,并將翻譯器集成到了蘇州大學(xué)與ARM公司聯(lián)合出品的嵌入式開發(fā)集成開發(fā)環(huán)境AHL-GEC-IDE中。將Python翻譯成C++的方法,能夠大幅降低Python類型判斷所消耗的時間,減少不使用的功能所占用的Flash空間,是提高Python實時性、減少Flash占用并增強可移植性[8]的有效方法。

        1 相關(guān)原理

        1.1 抽象語法樹

        抽象語法樹(abstract syntax tree,AST)[9]是源代碼到目標代碼的一種中間表示,用樹狀結(jié)構(gòu)描述了程序構(gòu)造。Python的AST可以表示為一個結(jié)點對象列表[10],每個對象包含多個子列表或其它對象的引用,每個列表或子列表包含任意數(shù)量的結(jié)點對象。

        Python的AST[11,12]通過調(diào)用ast模塊的parse()方法獲取,并且可以使用dump()方法將其轉(zhuǎn)為自然語言形式。圖1展示了一個Python函數(shù)及其調(diào)用的抽象語法樹。

        圖1 Python函數(shù)定義和調(diào)用的抽象語法樹

        其中根節(jié)點Module表示代碼整體,列表body包含一個函數(shù)定義FunctionDef和一個表達式語句Expr。函數(shù)定義結(jié)點中有函數(shù)名name、參數(shù)列表args、函數(shù)體子列表body和返回值注釋returns。表達式語句包括了一個函數(shù)調(diào)用結(jié)點Call,函數(shù)調(diào)用結(jié)點中有函數(shù)名func和參數(shù)列表args。

        編譯型嵌入式Python通過遍歷Python源碼的AST獲取程序的語義信息,并根據(jù)其語義生成對應(yīng)的C++代碼。在遍歷過程中主要處理的語法樹結(jié)點及其表示的內(nèi)容見表1。

        表1 Python抽象語法樹的結(jié)點類型和表示內(nèi)容

        1.2 類型注釋

        類型注釋是指在變量、函數(shù)定義時注釋出其類型信息。為了簡化Python代碼的靜態(tài)分析和重構(gòu),并支持潛在的運行時類型檢查,Python組織提出了PEP 484[13]和PEP 526[14]兩個類型注釋規(guī)范,將類型注釋加入了Python語法中。這兩個規(guī)范規(guī)定了在變量后用冒號加類型的方式對變量進行類型注釋,在函數(shù)定義語句末尾用“->”加類型的方式對函數(shù)返回值進行類型注釋,見表2。

        表2 類型注釋舉例

        類型注釋支持的類型分為基礎(chǔ)類型和復(fù)合類型兩種。基礎(chǔ)類型包括了整型int、浮點型float、字符串str、布爾值bool和字節(jié)數(shù)組bytes。復(fù)合類型包括了列表List、元組Tuple、集合Set和字典Dict,它們必須配合基礎(chǔ)類型一起使用,如:整型列表List[int],<整型,字符串>字典Dict[int,str]等。

        使用類型注釋聲明靜態(tài)變量能夠有效減少對Python程序進行靜態(tài)分析時的復(fù)雜性,并且能提高代碼的可讀性,對設(shè)計實現(xiàn)嵌入式Python和使用嵌入式Python編寫程序來說都是非常有益的。

        2 嵌入式Python設(shè)計

        《國家標準GB/T 22033-2017信息技術(shù)——嵌入式系統(tǒng)術(shù)語》中給出嵌入式系統(tǒng)的定義:置于應(yīng)用對象內(nèi)部,起信息處理或控制作用的專用計算系統(tǒng)。根據(jù)嵌入式系統(tǒng)的定義,嵌入式系統(tǒng)的軟件設(shè)計主要是面向過程的,因此嵌入式Python總體上設(shè)計為一個面向過程的翻譯器。嵌入式Python在要求使用類型注釋的基礎(chǔ)上,實現(xiàn)了Python的基本程序結(jié)構(gòu)轉(zhuǎn)換成C++的程序結(jié)構(gòu),并且提供與C++混合編程的方法從而實現(xiàn)IO操作以及快速接入已有的C++庫函數(shù)。以翻譯器為核心,將Python源文件翻譯成C++源文件再與芯片相關(guān)的頭文件、啟動文件和鏈接文件等放在一起編譯鏈接最后生成.hex文件,總體流程如圖2所示。

        圖2 編譯型嵌入式Python總體流程

        2.1 語法要求

        編譯型嵌入式Python要求變量先定義類型后再使用,函數(shù)必須使用函數(shù)注釋,示例見表2,對應(yīng)的語法描述如下:

        2.2 翻譯器設(shè)計

        2.2.1 翻譯文件的內(nèi)容結(jié)構(gòu)

        從Python代碼的執(zhí)行流程與C++的執(zhí)行流程中抽取共性,可將翻譯內(nèi)容的結(jié)構(gòu)分為頭文件包含區(qū)、命名空間定義和源碼區(qū)3部分,見表3。在頭文件包含區(qū)中“builtin.h”必須被包含,該文件內(nèi)聲明了Python的內(nèi)置函數(shù)的C++實現(xiàn)。命名空間用來模擬Python的模塊,也就是將Python中的按模塊調(diào)用函數(shù)、變量轉(zhuǎn)換成使用C++作用域限定符調(diào)用函數(shù)、變量。源碼區(qū)必須包含當前模塊的初始化函數(shù) _init(), 該函數(shù)用于存放Python源文件中全局作用域內(nèi)的代碼翻譯結(jié)果。

        表3 頭文件和源文件的結(jié)構(gòu)

        2.2.2 基本類型映射關(guān)系

        除了程序的基本結(jié)構(gòu)外,Python基本類型到C++類型的映射關(guān)系也是保證程序能夠正確編譯的重要部分。一方面,在翻譯過程中,遇到函數(shù)和變量定義時需要生成帶變量類型聲明的C++定義語句。另一方面,靜態(tài)庫中的內(nèi)置函數(shù)需要根據(jù)映射后的類型來實現(xiàn)其功能。

        Python的類型分為基礎(chǔ)類型和復(fù)合類型兩種,基礎(chǔ)類型包括了整型、浮點型、字符串、布爾型和字節(jié)數(shù)組,復(fù)合類型包括了列表類型、元組類型、集合類型和字典類型。設(shè)基礎(chǔ)類型集為T={int,float,str,bytes,bool}, 設(shè)Python類型到C/C++的映射關(guān)系為f,映射關(guān)系見表4,其中x,y∈T。

        表4 基本類型映射關(guān)系

        2.2.3 翻譯實現(xiàn)過程

        翻譯過程是自底向上對語法樹進行語義分析并生成C++代碼的過程,生成的代碼最終按翻譯文件的內(nèi)容結(jié)構(gòu)進行拼接。按表1中給出的結(jié)點類型可以分為表達式結(jié)點的翻譯和語句結(jié)點的翻譯兩類過程。

        (1)表達式翻譯過程

        表達式翻譯是語句翻譯的基礎(chǔ),它將構(gòu)成某種語句的Python表達式翻譯成C++表達式后返回給語句翻譯過程。表1已經(jīng)描述了Python表達式結(jié)點的類型,一個表達式expr的形式化描述如圖3所示。

        圖3 表達式及其子結(jié)點的形式化描述

        表達式由于存在遞歸定義,所以其翻譯過程是一個自底向上的子結(jié)點訪問過程,設(shè)表達式翻譯函數(shù)名為visit_expr,則其內(nèi)容就是將傳入的表達式結(jié)點參數(shù)代入對應(yīng)類型的訪問函數(shù)中,見表5。

        表5 表達式翻譯偽代碼

        限于篇幅,下面主要描述二元運算和方括號運算的翻譯過程。

        1)二元運算翻譯過程

        二元運算包括算數(shù)運算和位運算,都是只包含兩個操作數(shù)的運算類型。抽象語法樹用樹的深度來描述運算優(yōu)先級,翻譯時需要按后序遍歷先處理層數(shù)更深的運算結(jié)點,并且每層在返回翻譯結(jié)果時需要為翻譯后的表達式用括號括住來還原運算優(yōu)先級。翻譯規(guī)則主要分為:C++中有對應(yīng)運算符和無對應(yīng)運算符兩類。當有對應(yīng)運算符時,只需要將表達式還原成“操作數(shù)1 運算符 操作數(shù)2”的形式;當無對應(yīng)運算符時,需要翻譯成輸入?yún)?shù)為二元運算的兩個操作數(shù)的運算函數(shù)調(diào)用。設(shè)操作數(shù)1為l,操作數(shù)2為r,二元運算的翻譯規(guī)則見表6。

        表6 二元運算表達式翻譯偽代碼

        2)方括號運算翻譯規(guī)則

        方括號運算包括了按下標訪問數(shù)組元素和切片兩種運算。Python的按下標訪問數(shù)組元素在語法上與C++中的一致,翻譯時只需要按翻譯規(guī)則將數(shù)組對象和下標翻譯成C++方括號運算。Python的切片運算是C++所沒有的,因此需要將其翻譯成運算函數(shù)調(diào)用。設(shè)切片數(shù)組為arr,切片運算的翻譯規(guī)則見表7。

        表7 切片運算表達式翻譯偽代碼

        (2)語句翻譯過程

        語句是關(guān)鍵字和表達式的有序排列,用來表示程序執(zhí)行的操作,因此語句翻譯過程是根據(jù)語法樹結(jié)點內(nèi)容對表達式與關(guān)鍵字的重新組合。Python中常用的語句有賦值類語句、程序結(jié)構(gòu)控制類語句、函數(shù)定義語句、模塊導(dǎo)入語句和表達式語句。設(shè)Python的單句語句為stmt,語句塊為stmt_list,回車換行符、語句和語句列表的形式化描述如圖4所示。

        圖4 Python各類語句及語句列表的形式化描述

        語句翻譯或語句列表翻譯,是對模塊內(nèi)的程序代碼逐行翻譯成C++代碼的過程。翻譯過程中需要將函數(shù)定義語句與非函數(shù)定義語句分開,函數(shù)定義語句的翻譯結(jié)果填入其它作用域語句區(qū)域,非函數(shù)定義語句則填入所在作用域的函數(shù)體內(nèi)。設(shè)語句翻譯函數(shù)名為visit_stmt,輸入是一個語句列表L,輸出是函數(shù)定義翻譯列表func_result和其它語句翻譯列表other,其偽代碼描述見表8。

        表8 語句翻譯偽代碼

        限于篇幅,下面主要描述流程控制類語句和函數(shù)定義語句的翻譯過程。

        1)流程控制類語句的翻譯

        Python的程序結(jié)構(gòu)分為順序結(jié)構(gòu)、選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)3類。順序結(jié)構(gòu)即按從上到下的順序執(zhí)行兩句行語句。選擇結(jié)構(gòu)使程序按某個條件執(zhí)行分支程序,在Python中即為if語句,相比C++少了switch語句。循環(huán)結(jié)構(gòu)使程序在某個條件內(nèi)重復(fù)執(zhí)行一段代碼,在Python中有while和for兩種循環(huán)。下面是選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)從Python語法翻譯成C++語法的方法。

        if語句由分支條件、if主體代碼塊和else代碼塊3部分構(gòu)成。分支條件是一個表達式,主體代碼塊和else代碼塊都是語句列表。

        翻譯if語句需要將分支條件condition、主體代碼塊body和else代碼塊orelse代入對應(yīng)的翻譯函數(shù),然后將翻譯結(jié)果按C++語法拼接。對于任意的If語句結(jié)點i,翻譯過程函數(shù)visit_if可以描述為:

        while語句由循環(huán)控制條件和循環(huán)體代碼塊構(gòu)成。循環(huán)控制條件是一個表達式,循環(huán)體代碼塊是語句列表。

        翻譯while語句需要將循環(huán)條件condition、循環(huán)體代碼塊body代入對應(yīng)的翻譯函數(shù),然后將翻譯結(jié)果按C++語法拼接。對于任意的While語句結(jié)點w,翻譯過程函數(shù)visit_while可以描述為:

        ?w∈While→
        c←visit_expr(condition),b←visit_stmt(body),visit_while(w)=while(c)

        for語句由循環(huán)變量、序列對象和循環(huán)體代碼塊構(gòu)成。循環(huán)變量和序列對象都是表達式,循環(huán)體代碼塊是語句列表。

        該類循環(huán)實現(xiàn)的是從序列對象seq第一個元素循環(huán)到最后一個元素,每次循環(huán)都用循環(huán)變量iter表示當前元素,與C++的迭代器相似。由于序列類型翻譯后都使用STL容器類型來表示,因此for語句也是翻譯成C++的迭代器語法。對于任意的For語句結(jié)點f,翻譯過程函數(shù)visit_for可以描述為:

        ?f∈For→
        i←visit_expr(iter),s←visit_expr(seq),b←visit_stmt(body),visit_for(f)=for(autoi=s.begin();i!=s.end();i++)

        2)函數(shù)定義的翻譯

        函數(shù)定義由函數(shù)名func、參數(shù)列表args、返回值注釋returns和函數(shù)內(nèi)容body構(gòu)成,嵌入式Python要求參數(shù)和返回值都必須加上類型注釋,因此函數(shù)定義可以描述為:

        |List[typeid]|Tuple[typeid],

        翻譯函數(shù)定義需要將第一個返回值類型作為函數(shù)類型,將后面的返回值類型對應(yīng)的引用類型插入到參數(shù)列表中。設(shè)按基本類型映射關(guān)系映射后的參數(shù)類型為ta1~tan,返回值類型為tr1~trn,f.stmt_list是函數(shù)內(nèi)的語句塊,函數(shù)定義的翻譯函數(shù)visit_func可以描述為:

        2.3 與C/C++混合編程的實現(xiàn)

        由于Python不具有指針操作功能,不能直接按地址訪問存儲器,所以Python都是借助C或其它語言封裝的模塊實現(xiàn)IO操作。IO操作是嵌入式應(yīng)用的基礎(chǔ),因此必須設(shè)計與C/C++的混合編程方法,從而實現(xiàn)嵌入式Python的IO操作。

        2.3.1 函數(shù)和變量的聲明規(guī)則

        函數(shù)和變量需要使用一個Python源文件聲明,該文件第一行內(nèi)容是“#Extern Definition”,翻譯器遇到該類源文件時,只對其生成標識符信息表而不進行內(nèi)容翻譯。

        函數(shù)和變量的聲明語法需要符合2.1節(jié)中的F和V,并且函數(shù)體的內(nèi)容是“pass”,表示空內(nèi)容。

        設(shè)用來存放函數(shù)和變量聲明的Python源文件(模塊)名為Module.py,則其內(nèi)容C可以描述為:

        2.3.2 函數(shù)和變量的實現(xiàn)規(guī)則

        函數(shù)和變量使用C++語法進行實現(xiàn),需要使用一個擴展名為“.cpp”的文件作為源文件,和一個文件名為“Module.hpp”的文件作為頭文件。

        (1)變量

        全局變量的實現(xiàn)需要對Module.py中聲明的變量按C++語法加上前綴“Py_”。設(shè)Module.py中有名稱為v變量聲明V,它的類型注釋為type,經(jīng)過類型映射后得到t,則該變量的在Module.hpp中的內(nèi)容E和在源文件中的內(nèi)容T可以描述為:

        (2)函數(shù)

        函數(shù)的實現(xiàn)需要對函數(shù)名、參數(shù)名添加“Py_”前綴,并且將第一個返回值作為函數(shù)類型,第二個以后的返回值的引用類型加入到參數(shù)列表中。

        設(shè)Module.py中有函數(shù)名為func的函數(shù)聲明F,有k個參數(shù)arg1~argk并且它們的類型經(jīng)過映射后為t1~tk,有z個返回值,并且映射后的類型為r1~rz,函數(shù)內(nèi)容為S(使用C++編寫),則Module.hpp中需要的函數(shù)聲明H和源文件中需要的函數(shù)實現(xiàn)C可以描述為:

        在確定函數(shù)和變量的實現(xiàn)內(nèi)容后,最后對這些內(nèi)容按翻譯文件的結(jié)構(gòu)進行排布,即可完成混編的C++實現(xiàn)部分。表9描述了源文件和Module.hpp的內(nèi)容,&符號表示文法的與運算,includes是混編中使用的其它文件中定義的函數(shù)、變量所需要包含的頭文件語句列表。

        表9 混合編程的C++實現(xiàn)內(nèi)容

        3 對比實驗分析

        實驗選取了STM32L431RC為硬件平臺,通過對比嵌入式Python和MicroPython進行斐波那契數(shù)列運算的效率和程序大小來驗證嵌入式Python能夠有效提高Python在微控制器上運行的時間和空間效率。斐波那契數(shù)列第n項的計算是典型的分治思想算法,而其遞歸實現(xiàn)有著O(2n)時間復(fù)雜度,隨著計算項數(shù)的增大,會增加大量的函數(shù)調(diào)用過程,通過計算函數(shù)調(diào)用消耗的時間可以衡量出CE-Python的實時性。下面從實驗流程設(shè)計和實驗結(jié)果分析敘述斐波那契數(shù)列遞歸實現(xiàn)應(yīng)用下的CE-Python實時性。

        3.1 硬件平臺介紹

        STM32L431RC是基于高性能Cortex-M4內(nèi)核的32位精簡指令集超低功耗微控制器,工作頻率最高達80 MHz。它有256 KB的Flash和64 KB的RAM,并提供了一個低功耗RTC、一個通用32位定時器、一個專用于電機控制的16位PWM定時器、4個通用16位定時器和兩個16位低功耗定時器[15]。

        3.2 實驗程序及移植

        實驗程序選取了斐波那契數(shù)的遞歸算法,在STM32L431RC芯片上進行,利用定時器打樁法來取得計算斐波那契數(shù)列第n項所消耗的時間,并通過串口輸出到PC機。整體流程為:首先,開啟定時器,并取定時器計數(shù)值;接著,計算斐波那契數(shù)列第n項的值;然后,再次取定時器計數(shù)值;最后,計算兩次計數(shù)值的差值并通過串口輸出到PC機。程序見表10。

        表10 計算斐波那契數(shù)Python源碼

        3.2.1 MicroPython程序移植

        MicroPython移植的是最小解釋器,其程序移植分為6步:①在Windows環(huán)境下安裝Cygwin,安裝過程中勾選make和gcc;②打開Cygwin終端并進入到MicroPython工程目錄下的mpy-cross文件夾,使用make命令生成mpy-cross.exe;③在mpy-cross文件夾下新建Python源文件,名稱為frozentest.py,并將實驗程序粘貼到該源文件中,使用mpy-cross frozentest.py命令生成frozentest.mpy文件;④進入MicroPython根目錄下的ports文件夾,復(fù)制該文件夾下的Minimal文件夾,并重命名為STM32L431RC;⑤將STM32L431RC的官方芯片文件、內(nèi)核文件和鏈接文件復(fù)制到STM32L431RC文件夾下,修改main.c中的啟動代碼,修改uart_core.c中使用的串口,修改Makefile,將frozentest.mpy文件復(fù)制到該文件夾下;⑥Cygwin終端進入STM32L431RC文件夾,使用make CROSS=1命令編譯并生成可移植到STM32L431RC上的MicroPython程序。

        3.2.2 嵌入式Python程序移植

        嵌入式Python直接將實驗用的源程序翻譯成3個文件,將這3個文件與STM32L431RC的官方芯片頭文件、內(nèi)核文件、啟動文件和鏈接文件放在一起使用arm-none-eabi-g++工具進行編譯和鏈接即可生成可移植到STM32L431RC上的嵌入式Python程序。翻譯生成的3個文件見表11、表12。

        表11 嵌入式Python翻譯出的頭文件和主函數(shù)源文件

        表12 嵌入式Python翻譯出的源文件

        3.3 實驗結(jié)果與分析

        實驗在48MHz系統(tǒng)時鐘下進行,通過對比嵌入式Python和MicroPython計算斐波那契數(shù)列第n項所需要的時間來分析兩者的時間效率。

        為了提高定時器打樁法的測量精度并保證程序在可測量范圍內(nèi),實驗選取了計算斐波那契數(shù)列第20項到第30項的計算時間。當計算小于第20項時,計算機時間較短,對比效果不明顯,而當計算大于30項時MicroPython無法繼續(xù)運行。實驗使用毫秒(ms)為最小計量單位,而CPU時鐘運行精度是微秒級(μs),所以由精度造成的輸出誤差小于1 ms,每一項計算的時間結(jié)果都取20次測試中的眾數(shù),實驗結(jié)果見表13,其中第25~30項的計算時間對比柱狀圖如圖5所示。

        表13 斐波那契數(shù)列實時性測試結(jié)果

        圖5 計算斐波那契數(shù)列第25-30項對比結(jié)果

        由于計算第n項斐波那契數(shù)的程序只需要更改一個參數(shù),不需要增加或減少參數(shù),所以實驗中計算不同的斐波那契數(shù)程序的Flash占用基本不變,嵌入式Python的.bin文件大小平均為12 KB,MicroPython的.bin文件大小平均為47 KB。

        由實驗結(jié)果可得,將Python翻譯成C++代碼的方法能夠有效提高Python代碼在微控制器上的運行效率,并減少了Flash占用。

        4 結(jié)束語

        本文針對MicroPython實時性差、Flash占用空間大和可移植性不高導(dǎo)致Python不適合用于嵌入式編程的問題,分析了將Python轉(zhuǎn)化為非解釋型化的方法,將Python語言轉(zhuǎn)化為C++語言并將構(gòu)件層與應(yīng)用層分離,設(shè)計了抽象語法樹以及類型注釋的源碼機制,提出了編譯型嵌入式Python的方案。實驗測試結(jié)果表明,該方法能夠充分發(fā)揮靜態(tài)類型語言的優(yōu)勢,大幅度提高了Python在微控制器上的運行效率,能夠滿足在微控制器上使用Python編寫高實時性和低資源占用的嵌入式應(yīng)用程序的要求。就目前而言,已經(jīng)實現(xiàn)了高實時性和低存儲占用的嵌入式系統(tǒng)設(shè)計,完成了預(yù)定的研究目標。但是仍然存在改進空間,即編譯型嵌入式Python暫不支持像C語言那樣的單步調(diào)試功能,因此未來需要基于C語言的調(diào)試機制,通過指令級映射實現(xiàn)單步調(diào)試。

        猜你喜歡
        嵌入式
        Focal&Naim同框發(fā)布1000系列嵌入式揚聲器及全新Uniti Atmos流媒體一體機
        TS系列紅外傳感器在嵌入式控制系統(tǒng)中的應(yīng)用
        電子制作(2019年7期)2019-04-25 13:17:14
        基于嵌入式Linux內(nèi)核的自恢復(fù)設(shè)計
        嵌入式系統(tǒng)通信技術(shù)的應(yīng)用
        電子制作(2018年18期)2018-11-14 01:48:16
        嵌入式PLC的設(shè)計與研究
        電子制作(2018年16期)2018-09-26 03:27:18
        搭建基于Qt的嵌入式開發(fā)平臺
        基于嵌入式系統(tǒng)Windows CE的應(yīng)用程序開發(fā)
        嵌入式單片機在電機控制系統(tǒng)中的應(yīng)用探討
        電子制作(2017年8期)2017-06-05 09:36:15
        嵌入式軟PLC在電鍍生產(chǎn)流程控制系統(tǒng)中的應(yīng)用
        Altera加入嵌入式視覺聯(lián)盟
        国产一区二区资源在线观看| 久久成年片色大黄全免费网站| 色噜噜狠狠狠综合曰曰曰| 国产精品igao视频网 | 久久精品国产9久久综合| 亚洲国产成人无码电影| 久久精品中文字幕免费| 亚洲国产精品久久久婷婷| 久久99精品久久久久久噜噜| 伊人久久大香线蕉av网禁呦| 成人做爰69片免费看网站| 一级午夜视频| 人妻一区二区三区免费看| 人妻在线有码中文字幕| 精品九九人人做人人爱| 精品国模一区二区三区| 亚洲精品6久久久久中文字幕| 二区三区亚洲精品国产| 亚洲精品中文字幕不卡| 久久伊人少妇熟女大香线蕉| 亚洲精品无码人妻无码| 国产女主播强伦视频网站 | 风骚人妻一区二区三区| 久久精品国产亚洲av香蕉| 国产又黄又猛又粗又爽的a片动漫 亚洲精品毛片一区二区三区 | 亚洲一区二区观看播放| 视频女同久久久一区二区三区 | 丝袜美腿av在线观看| 人妻夜夜爽天天爽一区| 9191在线亚洲精品| 国产一区不卡视频在线| 亚洲国产av无码精品无广告| 亚洲国产成人片在线观看无码 | 18成人片黄网站www| 永久无码在线观看| 国产高清精品在线二区| 亚洲精品一品区二品区三区| 高清偷自拍第1页| 久久99精品免费一区二区| 淫秽在线中国国产视频| 国产精品白丝久久av网站|