LoRaWAN網關移植記錄

之前寫的LoRaWAN GW NS代碼中提到了已經基于Twisted實現了GW/NS代碼。其中NS代碼設計起來比較簡單。因為許多Linux系統(tǒng)中并沒有Twisted,甚至CPython也是比較低的版本。所以必須基于MicroPython的多線程版本backport到低版本CPython中。

兼容性

MicroPython是基于CPython 3.4的,而舊版本CPython大多都是2.7的,甚至更低。一種做法是直接交叉編譯MicroPython到這些SBC中,另外就是乖乖滴重新寫代碼了。

主要的兼容性問題在于Timer和time兩個模塊。

Timer

MicroPython將Timer歸為machine下的模塊,因為它的定時器是物理定時器,采用定時中斷驅動。同時也正是這個原因,ISR代碼大多采用lambda來寫。

CPython中,Timer歸為threading的子類。本質上是線程,所以CPython下循環(huán)定時器代碼反而比MicroPython要繁瑣。移植后的CPython版本,成了1+3四個線程的程序:主程序+UDP接收+兩個定時器線程。

time

因為MicroPython來自CPython 3.4,所以有些高精度的計時方法,如tick_cpu()/tick_us()/sleep_ms(),其實這些也都是MicroPython特有方法,CPython 3.4里不是這些方法。目前我暫時以time.time()的浮點數來替代,理論上精確到0.1us。其實能夠實現1ms就不錯了。

LoRaWAN下發(fā)窗口其實是有時間精度要求的。在LoRaWANPktFwd協(xié)議中有三種方式計時:

  1. 立即下發(fā);
  2. 時間戳下發(fā);
  3. GPS時間戳下發(fā)。

如果計時有問題,會返回以下錯誤報告:

Value Definition
NONE Packet has been programmed for downlink
TOO_LATE Rejected because it was already too late to program this packet for downlink
TOO_EARLY Rejected because downlink packet timestamp is too much in advance
COLLISION_PACKET Rejected because there was already a packet programmed in requested timeframe
COLLISION_BEACON Rejected because there was already a beacon planned in requested timeframe
TX_FREQ Rejected because requested frequency is not supported by TX RF chain
TX_POWER Rejected because requested power is not supported by gateway
GPS_UNLOCKED Rejected because GPS is unlocked, so GPS timestamp cannot be used

問題來了,在許多廣域應用中,需要借助GPS授時,這當然沒有疑問。立即下發(fā)也沒有問題。反倒是沒有嚴格要求的情況下,一般通過NTP進行授時,能夠精確到ms么?好像不能。局域網內1ms,公網一般在100ms左右。如果終端設備沒有授時裝置,則需要網關不斷地Beacon推送時間戳。加上TOF時間,誤差真的還蠻大的。

更新(20180930)

基于CPython的多線程設計已經在Ubuntu和OpenWRT中調試完畢,現在只需要對接LoRaWAN USB dongle的HCI接口即可。改HCI接口參考Bluetooth SIG HCI而來,主要做了減法,簡化了設計。

祝大家國慶快樂!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容