即使語(yǔ)法正確的LuatOS-Air腳本,在LuatOS環(huán)境中也可能出現(xiàn)“靜默失敗”——程序無(wú)報(bào)錯(cuò)但功能未執(zhí)行。這類問(wèn)題多與系統(tǒng)事件循環(huán)、模塊加載時(shí)機(jī)或硬件抽象層調(diào)用方式有關(guān)。本文通過(guò)多個(gè)真實(shí)案例,深入分析運(yùn)行異常的根本原因并提出預(yù)防措施。
一、lua版本不一樣
LuatOS-Air使用的是lua5.1版本,本身不支持位移運(yùn)算符。
LuatOS使用的是lua5.3版本,取消了module(..., package.seeall)這種形式的跨文件調(diào)用。
二、api不同
首先說(shuō)明,core和腳本有所不同,用戶可以理解為,core是安卓/ios系統(tǒng),腳本為一個(gè)又一個(gè)的app,只有core+腳本,才能支撐起完整的一個(gè)二次開發(fā)項(xiàng)目。
LuatOS-Air的api:
在https://doc.openluat.com/wiki/21?wiki_page_id=2068這里,又分為了5.1原生接口,提供的額外接口兩種。
在額外的接口其中,又分為了底層接口和二次封裝接口,底層接口叫做core api,二次封裝接口叫做script lib api,下面會(huì)簡(jiǎn)稱為lib層api。
core api實(shí)現(xiàn)過(guò)程不可見,封裝在了core里,受限于和RDA的協(xié)議,這部分實(shí)現(xiàn)過(guò)程不開源,而lib層的api,實(shí)現(xiàn)過(guò)程可見,用戶可以自行修改。
lib層api一般是將底層提供的接口進(jìn)行合并與封裝,更加的簡(jiǎn)單與易用,也有部分lib層api是直接給core發(fā)送AT指令然后處理AT指令的返回值,并且以函數(shù)返回值的形式返回給調(diào)用該api的位置。
LuatOS的api:
在https://docs.openluat.com/osapi/這里,和LuatOS-Air一樣,分為了5.3原生接口和提供的額外接口兩種。
在額外的接口其中,又分為了核心庫(kù)接口和擴(kuò)展庫(kù)接口,核心庫(kù)接口叫做core api,擴(kuò)展庫(kù)接口叫做script lib api,下面會(huì)簡(jiǎn)稱為lib層api。
core api實(shí)現(xiàn)過(guò)程不可見,封裝在了core里,這部分實(shí)現(xiàn)過(guò)程不開源,而lib層的api,實(shí)現(xiàn)過(guò)程可見,用戶可以自行修改。
LuatOS 核心庫(kù)是在底層實(shí)現(xiàn)的功能庫(kù),調(diào)用核心庫(kù)無(wú)需代碼使用 require 操作;
LuatOS 擴(kuò)展庫(kù)是用 Lua 腳本實(shí)現(xiàn)的功能庫(kù),必須用 requre 調(diào)用才能夠使用擴(kuò)展庫(kù)。
三、跨文件調(diào)用方式不同
LuatOS-Air跨文件調(diào)用方式
LuatOS-Air在每一個(gè)非main.lua的文件頭部,第一行可執(zhí)行代碼永遠(yuǎn)是module(..., package.seeall),主要作用是將該文件中所有的全局變量/全局函數(shù),加入到一張名為 _G的table中方便其他.lua文件調(diào)用,在這里不做過(guò)多講解,能有轉(zhuǎn)移需求的客戶,基本都會(huì)LuatOS-Air的跨文件調(diào)用方法。
luatos跨文件調(diào)用方式
luatos跨文件調(diào)用方式有兩種,一種和LuatOS-Air類似,不過(guò)是在文件第一行,新建一個(gè)和文件名相同的table,文件結(jié)尾處return這個(gè)table,接下來(lái)舉個(gè)例子
首先封裝一個(gè)函數(shù)

我們新建一個(gè)文件叫tools.lua,把這個(gè)函數(shù)放進(jìn)去,現(xiàn)在,整個(gè)文件如下面這樣:


現(xiàn)在,我們封裝的這個(gè)函數(shù)就能在其他文件(例如main.lua)里被調(diào)用了,具體代碼如下:

當(dāng)調(diào)用了require接口后,Lua虛擬機(jī)會(huì)自動(dòng)加載你調(diào)用的文件,執(zhí)行文件的內(nèi)容,然后返回你文件里return的結(jié)果。
為了更好地理解這段話,我們可以看下面兩個(gè)文件,其中main.lua是被運(yùn)行的那個(gè)入口文件,




此處為第一種調(diào)用方法,簡(jiǎn)單來(lái)說(shuō),被調(diào)用文件頭部,將module(..., package.seeall)換成文件名={},文件末尾處加return {本文件中寫的函數(shù)名=本文件中寫的函數(shù)名},有多個(gè)函數(shù)的時(shí)候,可以添加多個(gè)元素名= 元素名進(jìn)table里。
第二種調(diào)用方法依舊是在文件開頭寫上文件名={},不同的是,需要被調(diào)用的函數(shù)名,可以寫成文件名.函數(shù)名的形式,最后的return不需要return一個(gè)很長(zhǎng)的table了,只需要return 文件名,例如:
需要在main.lua 中調(diào)用test.lua的test函數(shù),那么除了固定格式以外的main.lua可以寫成

具體可參考https://gitee.com/openLuat/LuatOS/tree/master/script/libs這里所有的demo
四、實(shí)例
以uart的demo為例,筆者將帶著用戶,將LuatOS-Air uart的demo,移植到luatos上(僅講解uart1的移植過(guò)程,其他串口通用),除去無(wú)關(guān)本次移植過(guò)程的部分,LuatOS-Air的uart1完整demo如下,是一個(gè)自發(fā)自收的測(cè)試demo,luatos完整的demo也會(huì)放在最后,方便用戶對(duì)比。
LuatOS-Air_uart.zip
開始移植
main.lua的改造

PROJECT和VERSION這兩個(gè)參數(shù)不變,下載時(shí)候需要這兩個(gè)參數(shù)
require "log"這句可以刪除,底層已經(jīng)寫好了log庫(kù),并提供了和LuatOS-Air lib層api幾乎一致的core api,查看對(duì)應(yīng)的 luatos log庫(kù)api https://docs.openluat.com/osapi/core/log/
后得知,幾種日志模式的常量有所不同,所以LOG_LEVEL = log.LOGLEVEL_TRACE這句,可以改成LOG_LEVEL = log.LOG_INFO,再添加一句log.setLevel(LOG_LEVEL )
因?yàn)橹鬟壿嫸荚趖estUart1文件中,不需要在main.lua中調(diào)用,所以保持 require "testUart1" 原樣即可,為了用戶更直觀的看出跨文件調(diào)用的不同,所以我在testUart1中又寫了一個(gè)名為function_name的函數(shù),然后在main.lua中進(jìn)行循環(huán)調(diào)用。sys.init函數(shù)不需要,直接刪去即可
完成上述步驟以后,main.lua就被我們改造成了下面這樣

testUart1.lua的改造
接下來(lái)進(jìn)入testUart1.lua中

module(...,package.seeall)改為 testUart1 ={},pm和utils兩個(gè)庫(kù),utils不需要,直接刪除,pm庫(kù)底層提供了,無(wú)需require,也刪除。
接下來(lái)會(huì)先將proc、read、write、writeOk和我剛剛寫的function_name這幾個(gè)函數(shù)會(huì)加載到內(nèi)存中,但是還沒(méi)有執(zhí)行,接下來(lái)執(zhí)行的是pm.wake("testUart"),查看luatos的pm接口(https://docs.openluat.com/osapi/core/pm/),可以看到luatos沒(méi)有wake接口,但是有不休眠模式,所以先設(shè)置下不休眠,也就是將pm.wake("testUart")換成pm.request(pm.NONE)
然后執(zhí)行的是uart.on兩個(gè)注冊(cè)函數(shù),當(dāng)時(shí)串口有接收事件產(chǎn)生時(shí)候,會(huì)去執(zhí)行read函數(shù),當(dāng)串口有發(fā)送事件產(chǎn)生時(shí),會(huì)執(zhí)行writeOK函數(shù),對(duì)比luatos的注冊(cè)串口收發(fā)事件(https://docs.openluat.com/osapi/core/uart/#45-uartonid-event-func),可以看出,這兩個(gè)芯片收發(fā)事件函數(shù)一致,無(wú)需更改。
最后執(zhí)行的是串口設(shè)置指令,LuatOS-Air和luatos有很大不同,LuatOS-Air的uart設(shè)置接口如下(https://doc.openluat.com/wiki/21?wiki_page_id=2250#uartsetup_id_baud_databits_parity_stopbitsmsgmodetxDoneReportflowcontrolpriority_33)
luatos的uart設(shè)置接口如下(https://docs.openluat.com/osapi/core/uart/#41-uartsetupid-baud_rate-data_bits-stop_bits-partiy-bit_order-buff_size-rs485_gpio-rs485_level-rs485_delay-debug_enable-error_drop)
這兩個(gè)接口,LuatOS-Air的和luatos最大區(qū)別就是,LuatOS-Air將485半自動(dòng)收發(fā)控制分開了,單獨(dú)寫了一個(gè)uart.set_rs485_oe
而luatos將其寫在了一起,用戶在使用該接口時(shí),一定要注意不同接口之間參數(shù)的位置。
當(dāng)有串口接收事件產(chǎn)生時(shí),模塊會(huì)進(jìn)入read函數(shù),在read函數(shù)里,打印了data原始數(shù)據(jù)和轉(zhuǎn)成hex以后的數(shù)據(jù)后,便進(jìn)入了proc函數(shù)中,并且將串口來(lái)的數(shù)據(jù)傳入給proc函數(shù),進(jìn)行處理。
值得注意的是,read函數(shù)里有將串口來(lái)的數(shù)據(jù)通過(guò)uart.read函數(shù)賦值給data變量這個(gè)操作,但是luatos截至當(dāng)前文章完成時(shí),uart.read函數(shù)的第二個(gè)參數(shù),只能填number,意為每次接收的字節(jié)數(shù),也就是需要將代碼中的uart.read(UART_ID,"*l")換成uart.read(UART_ID,1024)后面這個(gè)1024,為uart.setup的第7個(gè)參數(shù),串口緩沖區(qū)你設(shè)置的大小,未設(shè)置默認(rèn)為1024字節(jié),如果需要用戶自行設(shè)置,則最小512,最大4096
而當(dāng)有串口發(fā)送事件產(chǎn)生時(shí),模塊會(huì)進(jìn)入writeOk函數(shù),該函數(shù)比較簡(jiǎn)單,就打印了下發(fā)送成功字樣。
最后一行因?yàn)橛锌缥募{(diào)用,所以需要return 文件名,也就是加一句return testUart1
最后整個(gè)testUart1.lua就被我們改造成了這樣

至此 整個(gè)改造過(guò)程結(jié)束,改造后的文件我也放在下面方便用戶對(duì)比
luatos_uart.zip
今天的內(nèi)容就分享到這里了~
審核編輯 黃宇
-
LuatOS
+關(guān)注
關(guān)注
0文章
156瀏覽量
2691
發(fā)布評(píng)論請(qǐng)先 登錄
LuatOS 框架的嵌入式系統(tǒng)架構(gòu)設(shè)計(jì)原理
LuatOS 系統(tǒng)框架的模塊化設(shè)計(jì)原理
輕松掌握——LuatOS socket基礎(chǔ)知識(shí)和應(yīng)用開發(fā)
LuatOS框架的使用(上)
LuatOS-Air腳本移植到LuatOS版本注意事項(xiàng)
構(gòu)建可靠USB應(yīng)用:硬件設(shè)計(jì)要點(diǎn)與LuatOS開發(fā)技巧!
Air780EPM開發(fā)板NTP對(duì)時(shí)教程:LuatOS腳本開發(fā)入門指南
LuatOS腳本開發(fā)入門:嵌入式運(yùn)行框架全解析!
嵌入式開發(fā)新選擇:LuatOS腳本框架入門教程
Task任務(wù):LuatOS實(shí)現(xiàn)“任務(wù)級(jí)并發(fā)”的核心引擎
揭秘LuatOS Task:多任務(wù)管理的“智能中樞”
解碼LuatOS:短信功能的底層運(yùn)作機(jī)制
血淚教訓(xùn)總結(jié):Air780EPM的LuatOS二次開發(fā)——OneWire協(xié)議調(diào)試注意事項(xiàng)
警惕兼容性陷阱:LuatOS-Air腳本在LuatOS中的運(yùn)行異常分析
評(píng)論