移植Contiki
1 LoRa終端需要OS嗎?
盡管工程師有很多理由拒絕在LoRa終端上使用OS(Operating System,作業系統):“它很複雜”,“沒必要”,“記憶體太小”,“有學習成本”,“要改變程式設計思維”,“可能不穩定”……然而,基于以下理由,我們強烈推薦移植一個小型OS:
降低複雜度
LoRa終端的複雜度其實比我們想象的要高:它需要驅動SX1278,這需要處理很多事件,如接收資料逾時,接收資料錯誤等;它需要實作網絡算法,申請入網,主動上報,低功耗喚醒,斷網續連等;它需要管理本地裝置,采集傳感器資料,控制閥門等。
使用OS,可以将上述任務分解成多個程序,開發者專注于每個程序的實作,可以有效降低複雜度。
複用元件
LoRa終端一定有這樣的需求:射頻CAD偵聽到喚醒信号後,快速通知程序接收資料幀;需要一個軟定時器來靈活地延時和喚醒……這些系統元件,OS都提供,要知道,這些豐富的元件可是經過嚴格測試的。複用成熟穩定的元件是提高軟體生産力的有效手段,這方面,作業系統功不可沒。
提高CPU效率
當LoRa終端“等待射頻發送資料包完成”前,它無事可幹;而其他程序希望得到CPU運作權,不用擔心,作業系統會完成排程,它會将“因等待而無事可幹”的程序阻塞,而将CPU配置設定給“具備運作條件”的程序享用。
移植性更好
有一天,因為某種原因(需要更強大的計算能力,需要更低成本等)需要更換LoRa終端的MCU,有作業系統支撐的系統就輕松多了,因為應用軟體調用的是作業系統的API,它很少與硬體層直接打交道;基本上,隻要将作業系統移植到“新MCU平台”,軟體系統就OK了。
2 Contiki是一個怎樣的OS?
Contiki是少有能同時實作2個目标的作業系統:對記憶體要求極低,同時支援程序阻塞機制。8位單片機的RAM極為寶貴,幾KB都是很大了,一般的RTOS(FreeRTOS或uc/os-ii等)無法運作,而Contikil可運作良好;有些作業系統,如OSAL也在極少的RAM上可以運作,但是這種基于“狀态機”開發的機制,讓代碼很難了解,程式執行流在狀态中來回判斷和切換,讓邏輯更複雜。
節能記憶體
Contiki有一個巧妙的機制來實作程序的排程:當程序被阻塞時,OS記錄該程序的下一C語言行号;當程序繼續運作時,從記錄的C語言行号繼續運作。這種機制從2個方面極大節省記憶體:所有的程序共享一個棧,沒有上下文機切換。甚至在小于1KB記憶體的MCU上,Contiki都可以良好地運作。
程序可以阻塞
在Contiki系統中可以實作如下語句,程序發送無線電資料包,然後阻塞自己,直到發送完畢。這種“優雅”的機制,非常符合程式員思維,同時降低了開發的複雜度。
SX1278Send(packetbuf_dataptr(),packetbuf_datalen());
PROCESS_YIELD_UNTIL(RF_Tx_Done ==s_tRFResult);
移植簡單
如果僅使用Contiki的核心,隻需要移植clock.c,即從MCU中找一個定時器來給etimer程序提供時鐘源。如果使用Contiki的網絡協定棧,需要按radio.c實作無線收發函數。
豐富的網絡協定棧
針對無線通信,Contiki提供3種MAC協定,還有RIME通信原語和RPL路由協定;針對TCP/IP,Contiki提供uIP協定棧,它支援IPv4和IPv6。
3 怎樣移植Contiki?
移植一個作業系統是指将它運作在給定的硬體平台。因為Contiki是非可剝奪的OS,不用實作上下文切換(CPU的寄存器儲存與恢複),是以它的核心移植特别容易,一般是實作2個定時器:etimer和rtimer。
如果站在3萬英尺的高度,一個基于Contiki嵌入式系統的層次結構如下所示。
考慮2種情況,首先需要更新Contiki更高版本的軟體,其次需要将Contiki移植到不同的硬體平台。為了盡可能地減少更新和移植的工作量,增加了ports檔案夾,ports目錄中檔案與core目錄中檔案低耦合。
3.1 移植Contiki核心
如果僅僅隻移植Contiki的核心,那麼還是比較容易的,一般說來隻需要修改2個檔案:clock.c和contiki-conf.h。
clock.c有2個函數需要适配對應硬體平台:
void clock_init(void); 設定一定時器,每秒産生CLOCK_SECOND個tick;
void SysTick_handler(void); tick中斷時遞增時間,檢測是否有逾時事件;
contiki-conf.h:設定contiki系統的一些參數,如:CLOCK_CONF_SECOND=100;
3.2 移植rtimer
3.2.1 rtimer用途
Contiki系統引入rtimer可以滿足精準定時的需要,一些對時間極為敏感的子產品(如MAC協定)依賴于rtimer。和etimer的粗粒度(常見為100Hz)不同,rtimer是細粒度(常見為1kHz)定時器。
3.2.2 rtimer移植
移植rtimer比較容易,基于MCU實作rtimer-arch.c和rtimer-arch.h。
需要特别注意,大多數定時器(尤其是8位MCU)位寬為16位,即MAX=65535, rtimer的頻率定為1kHz比較合理,它既可以保證比較好的精度(1ms),又具備65秒的滿量程,這可以适應大多數的應用需要。
另外,大多數應用需要随機撤銷和重新開機動rtimer,它可以通過添加2個函數來實作:rtimer_arch_disable_irq()和rtimer_arch_enable_irq()。
關于rtimer更多的原理與應用介紹,請連結:
http://blog.csdn.net/jiangjunjie_2005/article/details/44947899
4 怎樣應用Contiki?
Contiki是标準ANSI C語言開發,調用API函數和系統元件和一般的OS無異。在程序函數中開發,以下三點需要注意:
1. 自動變量不能跨越阻塞語句
2. 不能使用switch語句
3. 執行語句位于PROCESS_BEGIN()和PROCESS_END()之間
詳細了解該規則,請參考《Contiki開發要點》:
http://blog.csdn.net/jiangjunjie_2005/article/details/44725997
從一個入門級的Contiki進行代碼,請參考《Contiki開發5:Hello, Contiki》:
http://blog.csdn.net/jiangjunjie_2005/article/details/51921568