chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

LuatOS腳本開發(fā)入門:嵌入式運行框架全解析!

合宙LuatOS ? 來源:合宙LuatOS ? 作者:合宙LuatOS ? 2025-09-26 17:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

想搞懂LuatOS如何運行Lua腳本?本文深入剖析其嵌入式運行框架,涵蓋虛擬機加載、任務協(xié)程、系統(tǒng)初始化等關鍵環(huán)節(jié),適合初學者。

一、LuatOS 編程起步

1.1 底層固件怎么啟動 LuatOS 腳本

1.1.1 腳本入口執(zhí)行文件

簡單來說,底層固件首先就是要找到 main.lua 這個文件,然后啟動它。

所有的其他功能,都需要在 main.lua 發(fā)起。

1.1.2 LuatOS 啟動腳本的詳細流程

進一步詳細的說,LuatOS 的底層固件啟動腳本的流程如下:

1,系統(tǒng)上電或者復位后,底層固件(core)首先啟動,進行硬件初始化、內(nèi)存分配、文件系統(tǒng)掛載等系統(tǒng)底層的基礎操作。

2,加載 Lua 虛擬機:底層固件加載 Lua 虛擬機,為執(zhí)行 Lua 腳本提供運行環(huán)境;

3,自動查找并加載存儲在設備上的主腳本 main.lua;

4,按順序執(zhí)行 main.lua 腳本中的代碼,通常包括任務創(chuàng)建(如sys.taskInit)、功能初始化等,從這一步,已經(jīng)正式開始運行用戶邏輯。

5,進入任務調(diào)度:腳本最后通常調(diào)用sys.run(),進入事件循環(huán)和多任務調(diào)度。

1.1.3 怎么把固件和腳本燒錄到硬件:

1,使用LuatTools ,將底層固件和用戶 Lua 腳本燒錄到模組或者引擎硬件;

2,上電后,底層固件自動完成上述啟動和腳本加載流程,無需手動干預。

1.2 main.lua 需要包含哪些部分?

1.2.1 項目信息聲明

在 main.lua 的文件開頭,需要聲明項目名和版本號,便于管理和調(diào)試。后續(xù)的遠程升級,也需要用到項目名和版本號。

例如:

wKgZO2jWUOGAIwzMAABxJMLKJJ8624.png


1.2.2 核心庫,擴展庫以及如何加載

在 main.lua 需要加載 LuatOS 的基礎庫和擴展庫(如 zbuff,onewire,gnss 等)用來實現(xiàn)具體的業(yè)務邏輯。

核心庫和擴展庫的內(nèi)容,在后續(xù)的章節(jié)里面介紹。

核心庫在底層固件加載Lua虛擬機的時候,在底層固件已經(jīng)自動加載,不需要在用戶腳本中再去加載,例如sys,rtos等;

擴展庫是Lua腳本文件寫的庫,需要在用戶腳本中,使用require語句加載,例如libnet,httpplus等,加載方式如下:

wKgZO2jWUXiAV6SBAABY1MvYK9s803.png

1.2.3 至少啟動一個任務

在 main.lua 里面,至少需要啟動一個任務,否則這個 main 就無所事事,是一個沒什么實際用處的主腳本了。

啟動一個任務的方法,分為 2 個步驟:

1,創(chuàng)建一個函數(shù),把要做的事情,放在這個函數(shù)里面使用。這個函數(shù)必須是無限循環(huán)的,防止很快結束生命,不妨把這個函數(shù)命名為 task1(),

2,調(diào)用 sys.taskInit(task1),啟動這個函數(shù),于是這個任務,就放在待運行的任務列表里面了。

1.2.4 初步理解 sys.run()

sys.run() 是一個無限循環(huán)的函數(shù)。

main.lua 的最后一行, 只能是 sys.run(),代表 sys.run() 接管了 LuatOS 的所有的執(zhí)行調(diào)度工作。

sys.run() 是 LuatOS 的運行中樞。

在本文的 3.3 節(jié)和 7.3 節(jié),還會繼續(xù)介紹 sys.run()這個函數(shù)。

1.3 LuatOS 腳本編程的核心要點

1.3.1 LuatOS 實現(xiàn)的典型功能

LuatOS 腳本是利用了 Lua 的語法,以及基于 LuatOS 的核心庫和擴展庫提供的 API,進行簡便的編程,實現(xiàn)如下功能:

1,實現(xiàn)和云端服務器通信;

2,采集外設的數(shù)據(jù),控制外設設備;

3,實現(xiàn)人機交互,包括圖形交互和語音交互;

1.3.2 LuatOS 的學習要點

要想寫好 LuatOS 的軟件,實現(xiàn)上述三個功能,除了逐漸掌握 Lua 的基本語法之外,還需要熟悉 LuatOS 的核心庫和擴展庫,這樣才能開發(fā)出優(yōu)質(zhì)的基于 LuatOS 的物聯(lián)網(wǎng)設備軟件。

學習的方法有如下幾個:

1, 運行各個功能模塊的 demo 代碼;

2, 閱讀 docs.openluat.com 的教程文檔;

3, 遇到不懂問 AI

1.3.3 一個典型的 LuatOS 實現(xiàn)

一個典型的 LuatOS 實現(xiàn),包含 main.lua 入口文件和若干個功能模塊文件。

這里用 Air780EPM 模組的蜂鳴器的代碼為例, 有兩個腳本文件以及一個管腳描述 json 文件:

1, main.lua 文件, 作用是啟動一個任務,讓蜂鳴器響一秒鐘,再停頓一秒鐘,如此往復;

2, airbuzzer.lua 封裝了驅(qū)動蜂鳴器的功能實現(xiàn);

3, pins_Air780EPM.json 描述了本例使用到的管腳的功能,780EPM 的 26 管腳,用作 PWM4。

main.lua 內(nèi)容如下:

wKgZO2jWUn-AWJRaAAKAcy3IaWY302.png

airbuzzer.lua 內(nèi)容如下:

wKgZPGjWUr2AQOdjAAIMsxtcII8010.png

pins_air780EPM.json 內(nèi)容如下:

wKgZPGjWUviAAvadAADh8uf_JqA979.png

把上述幾個文件,連同 airr780EPM 最新的固件版本,用 Luatools 建立一個工程,燒錄到 780EPM 開發(fā)板,就可以聽到蜂鳴器的播放聲音了。

二、幾個要熟悉的常識

2.1 匿名函數(shù)

在 Lua 代碼里面,經(jīng)??吹?jīng)]有名字的函數(shù)。

這種函數(shù)定義之后, 要么馬上運行,要么作為另一個函數(shù)的返回值賦給其他變量,所以并不需要一個函數(shù)名字。

這種函數(shù),稱為匿名函數(shù)。

匿名函數(shù)可以某些時候簡化代碼,初學者寫代碼可以先不考慮匿名函數(shù)。

但是由于匿名函數(shù)在你能閱讀到的 Lua 代碼里面出現(xiàn)的頻次實在是太高了,所以你也不得不重視和習慣匿名函數(shù)。

2.2 閉包

閉包的實現(xiàn)通常是通過在外部函數(shù)內(nèi)部定義一個函數(shù),并將這個內(nèi)部函數(shù)作為外部函數(shù)的返回值。

這樣一來,內(nèi)部函數(shù)就可以訪問外部函數(shù)作用域中的變量,即使外部函數(shù)已經(jīng)執(zhí)行完畢,這些變量依然可以被內(nèi)部函數(shù)訪問,從而形成閉包。

常見的閉包實現(xiàn)模式如下:

wKgZPGjWU8yAJPlrAAEZPBSMJ6A664.png

這樣的好處是,可以定義一個函數(shù),能夠在一定范圍內(nèi),訪問外部的變量,實現(xiàn)可控的持續(xù)行為。

很多初學者會被這段代碼迷惑,會被繞暈。

這里做一下解釋:

(1)z 不是函數(shù)里面聲明的變量,z 是函數(shù)的參數(shù);

所以 在代碼里面, 因為 f=outer(10), 所以, f(5)就意味著是調(diào)用了 兩次函數(shù),傳入了兩個函數(shù)的參數(shù): outer(10)(5)。

第一次調(diào)用,out(10) ,意味著 在 outer 函數(shù)里面, y = x 這句, x 換成 10, 就是 y = 10;

outer(10)(5)意味著 5 是內(nèi)部匿名函數(shù)的參數(shù),就是替代 z 的;

匿名函數(shù)返回 y+z, 這里 y 是 10,z 是 5, 返回的就是 10+5=15.

這里比較繞的,就是給了兩次參數(shù),一個是 10 對應 x, 一個是 5 對應 z。

匿名參數(shù)和閉包,對初學者有點繞,很多讀者不明白為什么 z 為什么是 outer 的第二個參數(shù),

這里需要特別搞清楚的是, outer 這個函數(shù)的返回值是個函數(shù), 而且這個函數(shù)是有參數(shù)的。

那么,這個帶參數(shù)的函數(shù)賦值給 f 之后, f 就是個函數(shù)了, 于是給 f 一個參數(shù) 5, 這個 5 自然就是返回的函數(shù)的參數(shù)了,也就是 z 了。

雖然并不是所有的閉包都是上面這種代碼的實現(xiàn)形式,但是初學者可以先記住這樣的閉包形式。

如果不習慣閉包,初學者可以先避免在代碼里面體現(xiàn)閉包的代碼形式。

2.3 回調(diào)函數(shù)

2.3.1 回調(diào)函數(shù)是什么


回調(diào)函數(shù)是在 LuatOS 編程過程中經(jīng)常用到的一個技術。

理解 LuatOS 的回調(diào)函數(shù),可以從“事件驅(qū)動”和“函數(shù)作為參數(shù)”兩個角度來把握:

回調(diào)函數(shù)(Callback)是在特定事件發(fā)生時,由系統(tǒng)或框架自動調(diào)用你事先定義好的函數(shù)。你只需要把自己的函數(shù)注冊給系統(tǒng),等事件觸發(fā)時,系統(tǒng)就會幫你調(diào)用它。

本質(zhì)上,回調(diào)函數(shù)就是一個普通函數(shù),但它被作為參數(shù)傳遞或注冊到其他地方,由系統(tǒng)或其他代碼在合適的時機自動執(zhí)行。

回調(diào)函數(shù)的作用是實現(xiàn)事件響應,異步處理。

消息到來,定時器到點,網(wǎng)絡收發(fā)等功能都經(jīng)常會用到回調(diào)函數(shù)的處理。

總之,LuatOS 的回調(diào)函數(shù),就是你注冊給系統(tǒng)的,在特定事件發(fā)生時自動被調(diào)用的函數(shù)。

回調(diào)函數(shù)讓事件響應、異步處理、任務解耦變得簡單靈活,是 LuatOS 事件驅(qū)動編程的核心機制之一。

2.3.2 回調(diào)函數(shù)做消息訂閱與發(fā)布

LuatOS 支持通過sys.subscribe訂閱消息并注冊回調(diào)函數(shù),消息發(fā)布時自動調(diào)用回調(diào):

wKgZPGjWVH-AXceZAAEn-P9VxJQ823.png

當sys.publish("TEST", 123)被調(diào)用時,"TEST"消息以及攜帶的參數(shù)123會被插入到用戶消息列表中,LuatOS 內(nèi)部的sys.run()調(diào)度中樞會遍歷訂閱者列表,找到所有訂閱了 "TEST" 的回調(diào)函數(shù),并自動把參數(shù) 123 傳給這些回調(diào)函數(shù)。

通過這樣的處理,事件觸發(fā)和處理邏輯就被解耦,方便擴展和維護。

2.3.3 回調(diào)函數(shù)做定時器和異步操作

定時器到點后自動調(diào)用注冊的回調(diào)函數(shù):

wKgZPGjWVLKAQFO-AACcCSIndd0859.png

2.3.4 任務和協(xié)程場景的回調(diào)函數(shù)使用

在多任務,也就是 LuatOS 的協(xié)程場景下,回調(diào)函數(shù)也常用于任務喚醒、事件響應等。

解耦調(diào)用者與被調(diào)用者:調(diào)用者只需知道“有回調(diào)”,不用關心回調(diào)具體做什么,提升靈活性。

你只需更換回調(diào)函數(shù),就能實現(xiàn)不同的處理邏輯,無需修改底層框架代碼。

任務和協(xié)程的詳細信息,在下一章講解。

三、LuatOS 的多任務并行實現(xiàn)詳解

3.1 LuatOS 的多任務是怎么實現(xiàn)的

3.1.1 通過協(xié)程實現(xiàn)多任務的效果

LuatOS 使用一種協(xié)程(coroutine)的機制,實現(xiàn)多任務。

協(xié)程并不是真的多任務,也不是多線程,而是通過同一時間只可能有一個協(xié)程執(zhí)行,來等價實現(xiàn)多任務的效果。

和 RTOS 的搶占式多任務方式不同,協(xié)程不能搶占其他任務的時間片,只能由一個獨立的調(diào)度器來判斷是哪個協(xié)程占用 CPU 時間來運行。

一個 LuatOS 可以創(chuàng)建多個任務,每一個任務都是協(xié)程,為了簡化描述,后續(xù)我們經(jīng)常會用”任務“這個詞來指代協(xié)程。

LuatOS 創(chuàng)建的任務無法設定優(yōu)先級, 所以 LuatOS 的每個任務的優(yōu)先級都是相同的。

每一個 LuatOS 的任務在做運算的時候,是 100% 占用了 CPU 時間片的。

執(zhí)行完運算之后,要主動調(diào)用 yield() 函數(shù),讓自己掛起,其他任務才能獲得時間片運行。

如果某個任務, 持續(xù)進行運算,不做 yield() 調(diào)用,其他任務是無法獲取 CPU 時間片的。

協(xié)程掛起后,自己是無法恢復的,只能其他的任務調(diào)用 resume 系統(tǒng)函數(shù)來恢復。

我們在寫代碼的時候,不需要調(diào)用 yield() 把自己掛起,只需要調(diào)用 sys.wait() 做時延,由調(diào)度器統(tǒng)一在 sys.wait()里面把任務掛起。

在 LuatOS 里面,所有掛起的協(xié)程,都由一個獨立的調(diào)度器通過調(diào)用 resume 來恢復。

這個獨立的調(diào)度器, 在 LuatOS 里面是 sys.run() 函數(shù)。

3.1.2 LuatOS 的任務函數(shù)怎么掛起和恢復

LuatOS 的每一個通過 sys.taskInit() 發(fā)起的任務函數(shù),都不會直接調(diào)用 yield 把自己掛起,因為直接調(diào)用 yield 掛起的話,并不知道什么時候恢復這個任務。

LuatOS 的做法是,每個任務在執(zhí)行完自己的事情之后,都必須是調(diào)用一個等待函數(shù), 這樣的等待函數(shù)有如下幾個:

1,sys.wait(timeout)

這個函數(shù),會在掛起任務的同時,啟動一個定時器,定時器的觸發(fā)時間就是 timeout,并且把任務 id 跟這個定時器綁定。

到定時器觸發(fā)之后,sys.run 會根據(jù)該定時器綁定的任務 id,重新恢復該任務的運行。

2,sys.waitUntil(topic, timeout)

在掛起任務的同時,訂閱一個名為 topic 的消息。待到有其他的任務發(fā)布這個消息后,sys.run 恢復這個任務。

如果沒有等到其他任務發(fā)布這個topic 消息,超時timeout 了,sys.run()也會恢復任務的運行。

總結來說,LuatOS 的任務在掛起自己之前,會在系統(tǒng)的表里面,放一個讓自己恢復運行的條件,這個條件或者是一個超時時間,或者是其他任務發(fā)布一個消息。sys.run() 函數(shù)會去判斷這些恢復運行的條件是否滿足,一旦滿足條件,就會恢復對應的任務。

3.2 怎么實現(xiàn)單個任務

在 LuatOS 里面,一個任務,可以理解為一個無限循環(huán)的函數(shù),啟動一個任務,有如下步驟:

1,定義這個無限循環(huán)的函數(shù) task1;

2,調(diào)用 sys.taskInit(task1), 在 taskInit 函數(shù)里面,先為 task1 函數(shù)創(chuàng)建一個協(xié)程,同時把這個協(xié)程注冊到系統(tǒng)的協(xié)程列表,這樣 sys.run() 就會去運行這個協(xié)程。

這樣就新增了一個持續(xù)運行,永不退出的協(xié)程了。

一個在 LuatOS 系統(tǒng)里面合法的任務, 必須運行很少量的時間,執(zhí)行完自己的操作之后,馬上就把自己掛起。 掛起的方式就是 調(diào)用 sys.wait 或者 sys.waitUtil 函數(shù)。

一個正常的 LuatOS 任務,執(zhí)行計算的時間是很短暫的,絕大部分的時間,都是在掛起狀態(tài)。

在掛起狀態(tài), 是不消耗 CPU 資源的。

所以, LuatOS 的協(xié)程機制,具備了實現(xiàn)低功耗系統(tǒng)的前提。

3.3 進一步理解 sys.run()

LuatOS 的sys.run()函數(shù)是系統(tǒng)任務調(diào)度器的啟動入口,其主要工作流程如下:

3.3.1 進入任務調(diào)度主循環(huán)

當執(zhí)行到sys.run()時,LuatOS 會啟動任務調(diào)度器,正式進入事件驅(qū)動和多任務調(diào)度階段。

此后,所有通過sys.taskInit注冊的任務都會被納入系統(tǒng)統(tǒng)一調(diào)度。

3.3.2 循環(huán)處理底層消息與事件

sys.run()會不斷從底層(如硬件中斷、驅(qū)動、系統(tǒng)內(nèi)核,定時器等)獲取消息或事件,并將這些消息分發(fā)到相應的任務或回調(diào)函數(shù)進行處理。

這包括定時器到期、外設事件、網(wǎng)絡數(shù)據(jù)到達、用戶自定義消息等。

3.3.3 定時器與任務切換

sys.run 會周期性檢查所有注冊的定時器,并在定時器到期時喚醒相應的任務協(xié)程。

同時,系統(tǒng)會根據(jù)任務的掛起或喚醒狀態(tài),合理切換協(xié)程,實現(xiàn)多任務并發(fā)。

3.3.4 任務間消息通信與同步

sys.run()支持任務間通過消息發(fā)布/訂閱、等待/喚醒等機制進行通信與同步。

例如,任務可以通過sys.publish發(fā)布消息,其他任務通過sys.waitUntil或sys.subscribe等方式等待或響應這些消息。

3.3.5 持續(xù)運行,直至系統(tǒng)重啟或退出

sys.run()會持續(xù)運行,不會主動退出。

sys.run() 系統(tǒng)的主循環(huán),確保所有任務和事件都能被及時處理。

只有在系統(tǒng)重啟、腳本異常終止或手動退出時,sys.run() 這個調(diào)度循環(huán)才會結束。

3.3.6 簡要流程圖

(1)啟動任務調(diào)度器;

(2)進入主循環(huán)

(3)輪詢底層消息、定時器

(4)喚醒/調(diào)度任務協(xié)程

(5)分發(fā)和處理事件、消息

(6)返回主循環(huán),直到系統(tǒng)重啟或退出

3.4 怎么實現(xiàn)多個任務

3.4.1 協(xié)程大多數(shù)時間應該是掛起狀態(tài)

由于協(xié)程的運行原理是,同一時間只有一個協(xié)程在運行,其他協(xié)程在掛起狀態(tài)。

所以如果有多個協(xié)程存在的話,多個協(xié)程的運行,只可能有兩種情況:

第一種情況, 所有的協(xié)程都在掛起狀態(tài),這時候系統(tǒng)有可能進入低功耗;

第二種情況, 有一個協(xié)程在運行,其他協(xié)程在掛起。這時候系統(tǒng)是喚醒狀態(tài),不可能是低功耗狀態(tài)。

3.4.2 LuatOS 多任務的核心是掛起和恢復的調(diào)度

一個協(xié)程運行的時間越長,掛起的就越慢,其他的協(xié)程就無法得到時間片運行。

只有所有的協(xié)程都盡量減少時間占用, 都盡快掛起自己,這樣的多任務的調(diào)度的效率才能更高。

因此, LuatOS 多任務的編程核心,是使得每個任務函數(shù)的執(zhí)行時間盡可能的短,盡可能快速的掛起自己,整個系統(tǒng)的多任務并發(fā)處理的效率才會更高。

如果某個協(xié)程的運算時間很長,導致自己無法很快掛起,就會拖累整個系統(tǒng),使得整個系統(tǒng)的實時響應的性能降低。

3.4.3 怎么防止某個協(xié)程長時間不掛起

為了防止某個協(xié)程長時間做運算,不把自己掛起,LuatOS 設計了 watchdog 機制,起一個定時器,幾秒鐘喂狗一次。

如果超時沒有喂狗,系統(tǒng)就會被重啟。

把下面這段代碼放到 main.lua,即可實現(xiàn)喂狗的功能:

wKgZO2jWVcmAa_SdAAESSQ3Vh5s064.png

3.5 多個任務之間怎么分配時間片

LuatOS 系統(tǒng)里面,是沒有給某個任務分配時間片這樣的動作的。

LuatOS 的任務,必須盡快把自己掛起,釋放出 CPU,才能夠讓整個系統(tǒng)實時運行。

當所有任務都把自己掛起后,系統(tǒng)就就可能會低功耗休眠狀態(tài)。

只要有任何一個任務沒有掛起,系統(tǒng)都不可能進入低功耗休眠狀態(tài)。

通過 sys.run()函數(shù), 對多個任務按照業(yè)務需要進行恢復運行的調(diào)度,保證整個系統(tǒng)的順暢運行。

sys.run()調(diào)度的依據(jù),一個是定時器機制,一個是消息機制。

四、LuatOS 的定時器機制

LuatOS 的定時器機制是實現(xiàn)多任務系統(tǒng)的核心組件之一。

支持單次觸發(fā)和周期循環(huán),適用于物聯(lián)網(wǎng)設備中的定時任務、數(shù)據(jù)采集、狀態(tài)監(jiān)測等場景。

4.1 定時器類型與適用場景

類型
特點
適用場景
單次定時器
延遲指定時間后觸發(fā)一次
初始化延時、事件超時處理
循環(huán)定時器
周期性觸發(fā),可指定次數(shù)
心跳包發(fā)送、傳感器輪詢

4.2 核心 API 與用法

4.2.1 單次定時器

功能: 延遲 timeout 毫秒后執(zhí)行函數(shù), 可傳多個參數(shù)local timerId = sys.timerStart(callback, timeout, arg1, arg2, ...) 參數(shù)說明: callback: 定時器觸發(fā)時執(zhí)行的函數(shù) timeout: 延遲時間(毫秒) argN: 傳遞給回調(diào)函數(shù)的參數(shù) 代碼示例:

wKgZO2jWVwOARKTCAADhw2Ctp_4116.png

wKgZPGjWVxyAIP0RAABBwYdnhcU843.png

4.2.2 循環(huán)定時器

功能: 每隔 timeout 毫秒重復執(zhí)行函數(shù)localtimerId = sys.timerLoopStart(callback, timeout, arg1, arg2, ...)

代碼示例:

wKgZPGjWV0aAVZ-IAAFMek5u5pg503.png

運行結果為:

wKgZPGjWV4eAfnDVAADWuw8Xi3A944.png

4.2.3 定時器停止

LuatOS 有兩個 API 用于停止正在生效的定時器:

1, 停止制定 timerid 的單個定時器

sys.timerStop(timerId)

2,停止制定回調(diào)函數(shù)的所有定時器。

sys.timerStopAll(callback)

4.3 典型代碼示例

4.3.1 組合使用單次與循環(huán)定時器

wKgZPGjWV7-AFHXuAAH8jz32Ur4983.png


4.3.2 動態(tài)管理定時器

wKgZO2jWV-uAMIiPAAFtHLuYLI0354.png

4.3.3 5 秒后重連網(wǎng)絡

wKgZO2jWWC2ARvk7AADrz3Ro-tM440.png

4.4 定時器的數(shù)量限制

LuatOS 最多支持 64 個定時器。

由于任務里面的 sys.wait()、帶timeout參數(shù)的sys.waitUntil()、帶timeout參數(shù)的sys.waitMsg()調(diào)用也會引發(fā)調(diào)度器啟動一個定時器管理該任務的運行恢復,所以用戶實際能夠啟用的定時器,會比 64 個更少。

所以,在開發(fā)過程中, 需要注意這一點,不要無節(jié)制的使用定時器。

4.5 為什么 LuatOS 的定時器不太準

LuatOS 的定時器往往“不太準”,主要原因在于其定時器機制依賴于消息總線(Message Bus)和系統(tǒng)調(diào)度,而不是直接精準地控制硬件定時。具體來說有如下幾點原因:

4.5.1 定時器基于消息機制

LuatOS 的定時器設計是基于 RTOS 的 timer API。

當定時器超時時,系統(tǒng)只是在消息總線中插入一條定時器消息,由主循環(huán) sys.run()消費和處理,這會帶來兩種可能的時延:

1,當調(diào)度器在處理消息時,可能會因為其他任務、消息隊列長度、系統(tǒng)負載等原因出現(xiàn)延遲。

2,定時器回調(diào)的實際執(zhí)行時機,取決于消息被調(diào)度和消費的時刻,而不是定時器超時的精確時刻。

4.5.2 系統(tǒng)調(diào)度與任務競爭

LuatOS 采用事件驅(qū)動和多任務協(xié)作,主循環(huán)需要處理各種消息(包括定時器、外設、網(wǎng)絡等);

如果系統(tǒng)中有大量任務或消息,定時器消息可能會被延后處理,導致定時精度下降。

4.5.3 軟件定時器的局限

(1)軟件定時器本質(zhì)上依賴于系統(tǒng) tick(通常為 1ms),但 tick 的處理、消息入隊、Lua 虛擬機調(diào)度等環(huán)節(jié)都會引入微小延遲。

(2)在高負載或消息堆積時,這種延遲會被放大,表現(xiàn)為“定時器不準”。

4.5.4 Lua 腳本無法實現(xiàn)高精度定時器

LuatOS 定時器不太準的根本原因是:定時器只是觸發(fā)消息,實際執(zhí)行依賴消息總線和主循環(huán)調(diào)度,受系統(tǒng)負載、任務數(shù)量、消息堆積、網(wǎng)絡中斷優(yōu)先級最高等多因素影響。

LuatOS 定時器不能實現(xiàn)高精度定時器(例如微秒級別,幾十毫秒級別,甚至幾百毫秒級別也會有誤差)。

如果要實現(xiàn)高精度定時器,只能外掛單片機實現(xiàn),或者后續(xù)有可能推出集成單片機,專門用來實現(xiàn)高精度定時器和其他對實時性和精度要求比較高的需求。

4.6 sys.lua 里面的 timerPool 變量

如果你有興趣查看 sys.lua 的話,會發(fā)現(xiàn) timerPool 這個 table 類型的變量,在 0-0x1FFFFF 范圍內(nèi)存儲 恢復運行協(xié)程的定時器消息 ID, 在 0x200000-0x7FFFF 范圍內(nèi)存儲有回調(diào)函數(shù)的定時器消息 ID。

所以,凡是某個協(xié)程調(diào)用 sys.wait()延時函數(shù),都會在注冊一個定時器,定時器超時后,就會由調(diào)度器重新恢復這個協(xié)程的運行;

當使用 timerStart 函數(shù)注冊的定時器超時后, 調(diào)度器會調(diào)用定時器回調(diào)函數(shù)。

這兩種情況的超時處理,都是在 timerPool 這個變量實現(xiàn)的。

4.7 LuatOS 定時器總結

LuatOS 的定時器機制通過sys庫提供了消息驅(qū)動架構,合理運用定時器可顯著提升物聯(lián)網(wǎng)設備的自動化程度和能效比。

在使用定時器機制的時候,需要注意如下幾點:

4.7.1 避免阻塞回調(diào)

1, 定時器回調(diào)函數(shù)中禁止使用sys.wait操作

因為定時器回調(diào)函數(shù)是由調(diào)度器直接調(diào)用的,如果在定時器回調(diào)函數(shù)里面使用 sys.wait 操作,會使得調(diào)度器阻塞,從而使得整個系統(tǒng)停止運行。

2, 定時器回調(diào)函數(shù)禁止進行長時間阻塞操作

這樣會極大的降低系統(tǒng)效率,使得系統(tǒng)的反應變慢。

4.7.2 注意資源釋放

任務退出時,如果在任務運行過程中創(chuàng)建的定時器不再需要,需調(diào)用sys.timerStop()或者sys.timerStopAll()清理關聯(lián)定時器,防止內(nèi)存泄漏,或者引起定時器資源耗盡。

如果不想主動寫代碼清理關聯(lián)定時器,只能等待定時器時間到了之后,自動清除,這時就會多占用了一個沒有任何實際功能的定時器,如果定時器資源非常緊張的情況下,創(chuàng)建新的定時器有可能會失敗。

4.7.3 不要期待有高精確度的延時和定時

由于消息機制和虛擬機的運行限制,導致延時函數(shù)和定時器的精度都不會很高,在實現(xiàn)業(yè)務邏輯的時候,一定要注意這一點。


五、 LuatOS 的消息機制

LuatOS 的消息機制是其多任務協(xié)作的核心,通過sys庫實現(xiàn)事件驅(qū)動編程。以下從消息發(fā)送、消息接收、消息訂閱三個維度詳細解析:

5.1 發(fā)送消息

5.1.1 廣播式消息(一對多)

API:sys.publish(topic, arg1, arg2, ...)

功能:向所有訂閱者廣播消息,無目標標識。

代碼示例:

wKgZO2jWWSSAYyl7AADHbohWgA0000.png

5.1.2 定向消息(點對點)

API:sys.sendMsg(taskName, target, arg2, arg3, arg4)

功能:向指定任務發(fā)送消息,支持目標標識和參數(shù)。

代碼示例:

wKgZO2jWWVuAawNVAADJAGxZKmo453.png

5.2 消息接收

5.2.1 等待消息

在協(xié)程內(nèi)部等待:sys.waitUntil(topic, timeout)

特別提醒: 該 API 只能在協(xié)程內(nèi)執(zhí)行

代碼示例:

wKgZPGjWWYqAAmOPAAEo-23-at8768.png

5.2.2 定向接收

API:sys.waitMsg(taskName, target, timeout)

特點:按任務名和目標標識精準接收,支持超時,該代碼只能在協(xié)程內(nèi)執(zhí)行。

注意,該 API 的第一個參數(shù) taskName, 是指等待消息的任務名稱,也就是自己的任務名稱,不是發(fā)送消息的任務名稱。

調(diào)用該 API 的任務,和接收任務,不一定是同一個任務。

當接收消息的任務在掛起的時候,可以由其他任務或者調(diào)度器通過 WaitMsg API 喚醒掛起的任務。

代碼示例:

wKgZPGjWWcCADlyMAAEuAc6Uu0Q065.png

5.3 消息訂閱

5.3.1 全局訂閱

API:sys.subscribe(topic, func)

特點:如果訂閱了同一主題有多個回調(diào)函數(shù),這些回調(diào)函數(shù)都會被觸發(fā)。

代碼示例:

wKgZO2jWWfGAVDYpAACtu1ef4is485.png

5.3.2 任務私有訂閱

實現(xiàn)方式:通過sys.taskInitEx創(chuàng)建任務時注冊回調(diào)。

當有其他的任務發(fā)送消息給目標任務的時候, 但是目標任務并沒有通過 WaitMsg 函數(shù)設定消息處理,這時候該消息的處理就交給回調(diào)函數(shù)處理。

代碼示例:

wKgZPGjWWiGAeqbIAAJL_UPBeFM687.png

5.4 LuatOS 消息機制的典型應用場景

5.4.1 網(wǎng)絡模塊與主任務通信

wKgZO2jWWk-AVlj0AAJy1EAXiWY350.png


5.4.2 全局事件通知(sys)

wKgZPGjWWneANOX8AAIZITPbR1I878.png

5.5 消息機制設計要點

5.5.1 消息機制的不同設計

(1)處理全局事件,sys.publish發(fā)布的消息,已經(jīng)訂閱這個消息的所有sys.subscribe對應的處理函數(shù)都能收到。 (2)處理模塊間通信(如網(wǎng)絡請求-響應),sys.sendMsg發(fā)布的消息,會攜帶一個task name參數(shù),只有sys.waitMsg時也攜帶同樣的task name參數(shù),才能收到消息。

5.5.2 避免消息風暴:

高頻消息(如傳感器數(shù)據(jù))建議合并發(fā)送或降低頻率。

5.5.3 消息機制的核心目的之一是軟件解耦

通過合理運用sys庫的消息機制,可構建高效、解耦的物聯(lián)網(wǎng)應用架構。

六、多任務之間的信息交換

6.1 用全局變量做信息交換

如果信息量很小,比如就一個字符串或者標志位,任務之間可以通過共享全局變量來通信,一個任務去對這個全局變量賦值,其他任務讀取這個全局變量,任務之間就達到了通信的目的了;

6.2 用消息做信息交換

但是如果想要交換多個數(shù)據(jù),每個數(shù)據(jù)都用全局變量的話,就有點過于累贅了。

這時候,可以通過發(fā)送消息來通信。

任務之間怎么發(fā)送消息,接收消息,參考第五章的內(nèi)容。

七、再次理解調(diào)度器 sys 庫

LuatOS 的 sys 庫是系統(tǒng)調(diào)度和多任務管理的核心庫,提供了豐富的 API 用于任務創(chuàng)建、延時、消息通信、定時器管理等。

7.1.1 任務與協(xié)程管理

API: sys.taskInit(func, arg1, arg2, ...)功能: 創(chuàng)建一個新的任務(協(xié)程),并傳遞參數(shù)給任務函數(shù)。

7.1.2 延時與等待

(1) sys.wait(timeout)功能: 任務延時掛起指定毫秒數(shù),只能在任務函數(shù)中調(diào)用。

(2)sys.waitUntil(topic, timeout)功能: 任務掛起,直到收到指定 topic 的消息或超時,只能在任務函數(shù)中調(diào)用。

7.1.3 定時器相關

(1) sys.timerStart(func, timeout, arg1, ...)創(chuàng)建單次定時器,到時后執(zhí)行回調(diào)函數(shù)。

(2)sys.timerLoopStart(func, timeout, arg1, ...)創(chuàng)建循環(huán)定時器,周期性執(zhí)行回調(diào)函數(shù)。

(3)sys.timerStop(timerId)停止指定 ID 的定時器。

(4)sys.timerStopAll(func)停止所有與指定回調(diào)函數(shù)相關的定時器。

(5)sys.timerIsActive(timerId)判斷定時器是否處于激活狀態(tài)。

7.1.4 消息通信

(1)sys.publish(topic, arg1, ...)發(fā)布(廣播)一個消息,喚醒等待該 topic 的任務或觸發(fā)訂閱回調(diào)。

(2)sys.subscribe(topic, callback)訂閱指定 topic 的消息,消息到來時自動執(zhí)行回調(diào)。

(3)sys.unsubscribe(topic, callback)取消訂閱。

7.1.5 主循環(huán)控制

sys.run()功能: 是 LuatOS 的調(diào)度器,是系統(tǒng)主循環(huán),調(diào)度所有注冊的任務和定時器。

7.1.6 典型用法示例

wKgZO2jWWwaAKFFTAANU3gIj2mM923.png

7.1.7 任務與協(xié)程管理

(1)sys.taskInitEx(func, taskName, cbFun, ...)

功能:創(chuàng)建一個具名任務線程,并注冊任務函數(shù)和非目標消息回調(diào)。

(2)sys.taskDel(taskName)

功能:刪除由taskInitEx創(chuàng)建的任務線程,釋放資源。

7.1.8 消息通信機制

(1)sys.waitMsg(taskName, target, timeout)

功能:等待接收一個目標消息(可指定超時),任務會掛起直到收到目標消息或超時。

(2)sys.sendMsg(taskName, target, arg2, arg3, arg4)

功能:向目標任務發(fā)送一個消息,可攜帶最多 4 個參數(shù)。

(3)sys.cleanMsg(taskName)

功能:清除指定任務的消息隊列,防止消息堆積。

7.1.9 sys.run() 怎么實現(xiàn)多個任務的協(xié)同工作

sys.run()函數(shù)的實現(xiàn)過程是這樣的:

1, 查看消息隊列里面是否有未處理的消息, 如果有,就根據(jù)消息的處理類型,調(diào)用回調(diào)函數(shù)或者是喚醒對應的任務進行消息處理;

2, 等待底層 RTOS 操作系統(tǒng)的定時器消息;等待的過程,就是低功耗的過程;

3, 定時器消息等到之后, 調(diào)用定時器回調(diào)函數(shù)或者喚醒對應的任務。

4, 循環(huán) 1-3 步。

通過以上過程,我們可以看到,這個 LuatOS 系統(tǒng), 大多數(shù)時間都是在等待底層 RTOS 操作系統(tǒng)的定時器消息,在等待期間,系統(tǒng)是可以處于低功耗休眠狀態(tài)的。

當任務的時延很短, 或者定時器非常頻繁,或者是消息太多,是會影響到系統(tǒng)的低功耗性能的。

八、怎么封裝一個 LuatOS 的軟件功能模塊

在 LuatOS 中封裝功能模塊為單獨 Lua 文件的標準做法:

1、新建一個 Lua 文件,定義一個 table,比如名字為 myflib,所有對外接口作為其字段。

2、用 local 修飾內(nèi)部變量和函數(shù),實現(xiàn)信息隱藏。

3、定義 myflib 的成員變量,成員函數(shù),用作對外的接口。

4、文件末尾用returnmyflib ,導出模塊 table。

5、外部的文件,用require("模塊名")加載和復用模塊。

這樣可以讓你的功能模塊獨立、可維護、易擴展,是 Lua 及 LuatOS 推薦的開發(fā)范式。

代碼示例:

wKgZPGjWW4SAYcqyAAb3zMmZzHE881.png

九、LuatOS 的核心庫和擴展庫

LuatOS 在 Lua 5.3 版本的基礎上, 封裝了 74 個核心庫,17 個擴展庫,提供了極其強大的通信和硬件的開發(fā)功能。

9.1 LuatOS 核心庫

LuatOS 核心庫,提供了 LuatOS 系統(tǒng)的核心功能。 不同的硬件型號,支持不同的核心庫的子集。

LuatOS 的核心庫, 是不需要用戶 require,可以直接調(diào)用的。

780EPM 對這些核心庫的支持情況參見如下鏈接:

http://docs.openluat.com/air780epm/common/lutos_coreapilist/

9.2 LuatOS 擴展庫

除了用戶可以直接使用的核心庫之外, LuatOS 還提供了豐富的擴展庫。

使用擴展庫,需要用戶在代碼里面做 require 動作,Luatools 看到 require 關鍵字后,會把用到的擴展庫合并入燒錄包,一起燒錄到硬件里面。

如果用戶不做 require 的動作, luatools 就不會合并這個擴展庫的代碼。

所有的擴展庫,都是用 Lua 代碼實現(xiàn)的。

當前 LuatOS 已經(jīng)支持的擴展庫參見如下鏈接:

http://docs.openluat.com/air780epm/common/lutos_coreapilist/

十、LuatOS 實際工程代碼解讀

780EPM 1.3 開發(fā)板的出廠固件代碼, 是一個實際的 LuatOS 開發(fā)的簡單案例。

代碼的位置在:

780EPM 開發(fā)板 V1.3 出廠固件源碼

這個固件分為幾個部分:

1, 780EPM core 固件: 目前最新的固件是 2005 版本,后續(xù)更新的固件版本也可以繼續(xù)使用;

最新的 780EPM 固件在這里下載:

http://docs.openluat.com/air780epm/luatos/firmware/version/

2,管腳復用描述文件

wKgZO2jWXC6AXcg7AABBziyXB5U106.png

3, 資源圖片

實現(xiàn)開機固件所需的圖片。(詳見780EPM 開發(fā)板 V1.3 出廠固件源碼的pic目錄下的圖片 )

4, 實現(xiàn)腳本。

下面重點講解一下腳本實現(xiàn)的邏輯。

10.1 編碼要求

為了降低用戶理解成本,這份開機固件的代碼有如下要求:

(1)不允許用云編譯擴大腳本區(qū),不允許用云編譯擴大文件系統(tǒng),保持腳本 + 資源總體尺寸不能大于 256K 字節(jié);

(2)main.lua 作為邏輯主線,其他的功能代碼封裝成子模塊,提供成員函數(shù),也可以提供成員變量, 被 main.lua 調(diào)用;

(3)不允許使用匿名函數(shù);

10.2 已實現(xiàn)功能

如下代碼,已經(jīng)實現(xiàn)了如下功能:

(1)主界面九宮格的按鍵切換,

(2)長按進入具體功能界面;再長按回到主界面;

(3)圖片顯示功能,

(4)攝像頭預覽,

(5)俄羅斯方塊,

(6)天氣數(shù)據(jù)獲取,并顯示不同的天氣圖標;

使用的是 780EPM 默認 2005 固件,不需要擴大文件系統(tǒng)和代碼區(qū)。

其中,airlcd.lua, camera780epm_simple.lua, russia.lua,statusbar.lua, 分別用 table 的方式,封裝了 LCD 的參數(shù)初始化,camera 的初始化,預覽,退出,俄羅斯方塊的初始化,更新數(shù)據(jù),響應按鍵等事件。

在 main.lua 調(diào)用這些封裝好的 table 的函數(shù)即可,不需要過度關心子模塊的實現(xiàn)細節(jié)。

10.3 待實現(xiàn)功能

(1)以太網(wǎng) LAN

(2)以太網(wǎng) WAN

(3)硬件自檢

(4)modbus TCP

(5)modbus RTU

(6)CAN 總線

10.4 main.lua 解讀

10.4.1 系統(tǒng)初始化

整個系統(tǒng),做了兩個全局初始化:

1, 看門狗的初始化,wdt.Init()防止系統(tǒng)被某個任務異常占用 CPU 讓系統(tǒng)鎖死;

2, LCD 的初始化: airlcd.lcd_init("AirLCD_0001"),其中 AirLCD_0001 是合宙 LCD 配件的型號。

10.4.2 業(yè)務主循環(huán)

UITask() 函數(shù), 是 main.lua 啟動之后的主循環(huán)。

在 UITask 函數(shù)里面,先做按鍵的初始化之后,就無限循環(huán)的不斷調(diào)用三個函數(shù):keypressed, update, draw。

其中,keypressed 是查看按鍵是否有待處理的事件;

update 是更新業(yè)務數(shù)據(jù);

draw 是更新 UI 畫面。

10.4.3 按鍵事件的處理

由于 780EPM 開發(fā)板只有三個按鍵: 開機鍵,boot 鍵,reset 鍵。

reset 鍵無法被捕獲事件,只能復位硬件,所以固件只能處理 開機鍵和 boot 鍵的事件。

boot 按鍵是一個特殊的 GPIO, 編號為 GPIO0。

開機鍵也是個特殊的 GPIO, 編號為 GPIO.PWR_KEY。

在 KeyInit()這個函數(shù), 分別配置了 gpio.PWR_KEY 和 GPIO0 為雙邊沿中斷,中斷處理函數(shù)分別為 PowerInterrupt 和 BootInterrupt。

根據(jù)開發(fā)板的原理圖,開機鍵初始電平是上拉為高電平,boot 鍵初始電平為下拉低電平。

在 PowerInterrupt() 和 BootInterrupt()這兩個函數(shù)的處理邏輯是類似的,都是計算按下和抬起的時間間隔,從而判斷是短按還是長按,然后給 key 這個全局變量賦值。

key 是字符串類型,是一個比較關鍵的變量,根據(jù) key 的值不同, main.lua 進入不同的功能。

這個邏輯是在 keypressed 來實現(xiàn)。

在 keypressed() 函數(shù)里面,檢查 key 變量的值,然后做不同的處理。

在主界面, 處理 "main" 和 "enter"這兩個值,分別是切換按鈕加亮顯示,以及進入具體功能按鈕;

在具體功能界面, enter 按鍵時間會返回主界面;

在俄羅斯方塊界面, 有 5 種按鍵:

(1)right: 短按 boot, 往右移動方塊;

(2) left:短按開機,往左移動方塊;

(3)up:長按 boot,旋轉(zhuǎn)方塊;

(4)fast:長按開機,快速下落;

(5)quit:超長按開機,退出游戲回到主界面。

10.4.4 UI 界面的循環(huán)刷新

在 draw 函數(shù)里面刷新界面。

當需要把繪圖權限交給其他的功能模塊的時候, 根據(jù)情況做不同的處理:

(1)俄羅斯方塊的刷新函數(shù)就是自己實現(xiàn) drawrus 函數(shù), draw 函數(shù)調(diào)用 drawrus 函數(shù)刷新屏幕;

(2)攝像頭預覽功能接管了屏幕后,draw 函數(shù)判斷當前是攝像頭預覽功能,就直接退出,如果判斷不是攝像頭,再繼續(xù)處理刷新任務;

(3)在刷新之前,調(diào)用 update 函數(shù)更新用于刷新的關鍵數(shù)據(jù)。

10.4.5 管理當前功能狀態(tài)機

有兩個關鍵變量:

cur_sel: 整數(shù),范圍是 1-9, 當前選擇的九宮格是哪個;

cur_fun: 字符串,10 種值:

記錄當前已經(jīng)進入的界面是主界面,還是 9 個之一。

“main”: 主界面;

另外 9 個界面用一個數(shù)組記錄,并根據(jù) cur_sel 賦值給到 cur_fun。

local funlist = {

"picshow", "camshow","russia",

"LAN", "WAN","selftest",

"modbusTCP","modbusRTU","CAN"

}

cur_sel 和 cur_fun,結合 key 的值,組成了整個的邏輯切換,可以決定該進入什么軟件功能,該顯示什么界面。

理解了 cur_sel, cur_fun, key 這三個變量的運用,就可以看明白整個軟件的邏輯。

10.5 總結

這份 780EPM 的開發(fā)板的出廠固件的代碼,展示了一個完整的 LuatOS 工程的基本實現(xiàn)的方法。

腳本文件一共只有 10 個,全部加一起只有 30k 字節(jié),1000 行代碼,實現(xiàn)了 9 宮格界面,電量,信號強度,天氣的狀態(tài)欄顯示,包括俄羅斯方塊在內(nèi)的多種功能的演示。

這份代碼后續(xù)還會繼續(xù)更新,并且都不會采用非常高難度的編碼技巧,只需要用最簡單的編程邏輯就可以實現(xiàn)相對復雜的業(yè)務邏輯。

今天的內(nèi)容就分享到這里了~

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5172

    文章

    19967

    瀏覽量

    324212
  • 腳本
    +關注

    關注

    1

    文章

    405

    瀏覽量

    28948
  • LuatOS
    +關注

    關注

    0

    文章

    118

    瀏覽量

    2473
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Air780EPM開發(fā)板NTP對時教程:LuatOS腳本開發(fā)入門指南

    通過簡單的LuatOS腳本,Air780EPM即可實現(xiàn)NTP時間同步。本指南從零開始,帶你掌握嵌入式設備聯(lián)網(wǎng)校時的核心方法。 一、NTP通信概述 1.1 NTP 網(wǎng)絡時間協(xié)議(英語:Network
    的頭像 發(fā)表于 09-30 16:01 ?831次閱讀
    Air780EPM<b class='flag-5'>開發(fā)</b>板NTP對時教程:<b class='flag-5'>LuatOS</b><b class='flag-5'>腳本</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>入門</b>指南

    Air780EPM開發(fā)板FTP功能實戰(zhàn):LuatOS嵌入式開發(fā)解析

    本文深入講解Air780EPM模組在LuatOS環(huán)境下的FTP應用開發(fā),涵蓋AT指令配置、網(wǎng)絡連接與文件傳輸流程,助你高效完成嵌入式通信項目。 一、什么是 FTP ? 1.1 基本概念 FTP 協(xié)議
    的頭像 發(fā)表于 09-29 15:37 ?84次閱讀
    Air780EPM<b class='flag-5'>開發(fā)</b>板FTP功能實戰(zhàn):<b class='flag-5'>LuatOS</b><b class='flag-5'>嵌入式開發(fā)</b><b class='flag-5'>全</b><b class='flag-5'>解析</b>

    嵌入式開發(fā)新選擇:LuatOS腳本框架入門教程

    LuatOS正成為嵌入式開發(fā)的新趨勢!本教程帶你從基礎入手,全面了解其基于Lua的腳本開發(fā)模式與輕量級運行
    的頭像 發(fā)表于 09-26 17:34 ?124次閱讀
    <b class='flag-5'>嵌入式開發(fā)</b>新選擇:<b class='flag-5'>LuatOS</b><b class='flag-5'>腳本</b><b class='flag-5'>框架入門</b>教程

    嵌入式達到什么水平才能就業(yè)?

    (三)實戰(zhàn)經(jīng)驗擁有2-3 個完整嵌入式項目經(jīng)驗:項目需包含需求分析、方案設計、代碼開發(fā)、測試優(yōu)化流程,能清晰闡述項目難點與解決方案能獨立排查項目中的軟硬聯(lián)調(diào)問題:比如通過示波器查看信號波形定位
    發(fā)表于 09-15 10:20

    嵌入式入門到進階,怎么學?

    嵌入式入門到進階,怎么學? 嵌入式學習的核心是 “軟硬結合的技術壁壘”,科學分層才能高效突破。以下是從入門到高階的精簡路線,幫你避開彎路: 1、基礎奠基層:構建技術底座 C 語言聚焦
    發(fā)表于 09-02 09:44

    BitsButton嵌入式按鍵處理框架

    配備了完整的按鍵測試用例,專為嵌入式C項目設計: 詳情見:按鍵測試用例 ?? 分層架構設計 核心層(core/): 測試框架基礎設施和運行器 工具層(utils/): 模擬工具、時間控制、斷言增強 測試
    發(fā)表于 08-02 11:24

    Linux嵌入式和單片機嵌入式的區(qū)別?

    新的應用程序和驅(qū)動程序來擴展功能。 6. 開發(fā)難度 : 單片機嵌入式開發(fā)難度相對較低,適合初學者入門。 Linux嵌入式
    發(fā)表于 06-20 09:46

    嵌入式開發(fā)入門指南:從零開始學習嵌入式

    隨著物聯(lián)網(wǎng)、智能硬件的發(fā)展,嵌入式開發(fā)成為熱門技能之一。以下將為初學者提供一份詳細的嵌入式開發(fā)入門指南,涵蓋學習路徑、必備工具、推薦資源等內(nèi)容。 1. 嵌入式系統(tǒng)的定義與應用
    發(fā)表于 05-15 09:29

    LuatOS協(xié)程深度解析:小白也能10分鐘學會,代碼效率直接起飛!

    嵌入式開發(fā)如何兼顧效率與簡潔?LuatOS協(xié)程給出完美答案!它用類線程的語法封裝異步邏輯,讓多任務開發(fā)像單線程一樣簡單。本文用圖文并茂的方式拆解協(xié)程原理,10分鐘帶你輕松入門! ?
    的頭像 發(fā)表于 04-10 15:23 ?376次閱讀
    <b class='flag-5'>LuatOS</b>協(xié)程深度<b class='flag-5'>解析</b>:小白也能10分鐘學會,代碼效率直接起飛!

    嵌入式系統(tǒng)開發(fā)圣經(jīng)【干貨】

    主管、系統(tǒng)設計分析人員及欲進入該領域的工程師。是一本開發(fā)嵌入式系統(tǒng)產(chǎn)品必備的入門圣經(jīng),進入嵌入式系統(tǒng)領域的寶典。可以翻看翻看,學習一下嵌入式開發(fā)
    發(fā)表于 03-12 13:58

    嵌入式教育科普|GPIO接口全面解析

    知識的掌握直接影響著嵌入式項目實現(xiàn)功能的成效。本文將以GPIO接口為切入點,深入解析其工作原理與技術特性,希望能幫助屏幕前想要學習嵌入式開發(fā)的小伙伴建立嵌入式接口的
    的頭像 發(fā)表于 03-05 11:11 ?2395次閱讀
    <b class='flag-5'>嵌入式</b>教育科普|GPIO接口全面<b class='flag-5'>解析</b>

    入門必看】從菜鳥到大牛,嵌入式系統(tǒng)完整學習路線!看這篇就夠了!

    ?嵌入式Linux”的順序幫助您從入門到進階,掌握嵌入式開發(fā)的精髓。第一階段單片機單片機是嵌入式學習的基石,因為它集成了處理器、存儲器和輸入輸出接口于單一芯片中,提
    的頭像 發(fā)表于 02-20 10:53 ?2886次閱讀
    【<b class='flag-5'>入門</b>必看】從菜鳥到大牛,<b class='flag-5'>嵌入式</b>系統(tǒng)完整學習路線!看這篇就夠了!

    韓國企業(yè)Mythosia發(fā)布面向嵌入式行業(yè)的腳本驅(qū)動串行通信

    專注于嵌入式與固件開發(fā)的韓國企業(yè)Mythosia全新推出了一款基于腳本運行的串行通信監(jiān)控程序“CRMT”。 ? CRMT設計為可應用于包括Arduino在內(nèi)的多種
    的頭像 發(fā)表于 12-30 11:20 ?957次閱讀
    韓國企業(yè)Mythosia發(fā)布面向<b class='flag-5'>嵌入式</b>行業(yè)的<b class='flag-5'>腳本</b>驅(qū)動串行通信

    新手怎么學嵌入式?

    運行機制。例如,了解數(shù)據(jù)結構中的鏈表、棧和隊列,對于在嵌入式編程中管理數(shù)據(jù)非常有幫助。 2. 選擇合適的編程語言 嵌入式開發(fā)中常用的編程語言有 C 和 C++。C 語言是嵌入式開發(fā)
    發(fā)表于 12-12 10:51

    嵌入式系統(tǒng)開發(fā)與硬件的關系 嵌入式系統(tǒng)開發(fā)常見問題解決

    系統(tǒng)開發(fā)與硬件關系的幾個關鍵點: 硬件依賴性 :嵌入式系統(tǒng)的軟件必須能夠在特定的硬件上運行,這包括處理器、內(nèi)存、輸入/輸出接口等。軟件必須能夠充分利用硬件的特性,同時繞過其限制。 資源限制 :
    的頭像 發(fā)表于 12-09 09:38 ?1283次閱讀