
【工業級樹莓派】
Revolution Pi是一款基於樹莓派計算模塊進行工業級設計和封裝的工業樹莓派。RevPi的操作系統在Raspbian基礎上進行了優化,給linux內核添加了RT實時補丁,以使得linux滿足硬實時的需求。
用戶可以通過python等高級語言編寫程序,並且可以通過存儲器中的過程映像便捷的寫入或者讀取所有當前過程值。
本文將介紹從過程映像中訪問數據的三種方法:直接從文件中讀取、透過ioctl讀取或透過revpimodio2模塊讀取。(以下示例均採用python語言)
▊ 設備配置
為了演示如何從過程映像中讀取過程值,本文採用RevPi內置的虛擬Modbus TCP Master讀取電腦模擬的Modbus TCP Slave的一個保持寄存器的值,並將其放入變量Input_Word_1中。其中變量Input_Word_1的值被放入過程映像中。
下面將採用三種方法讀取它的值。在此之前,首先使用piTest命令,查看Input_Word_1的當前值。

圖0.1 Modbus TCP Slave寄存器配置

圖0.2 Input_Word_1的值
▊ 訪問數據方法
1. 直接從文件中讀取
直接從文件中讀取數據,簡單來說就是透過變量的參數offset和length,在過程映像文件中查找變量所在位置並讀取,然後對讀取到的數據進行解包即可。

圖1.1 從文件中直接讀取數據程序示例

圖1.2數據讀取程序運行結果
當然,也可以直接對文件進行修改,為變量賦值。可以在RevPi的Modbus TCP Master中配置另一個任務,將Output_Word_1的值寫入電腦模擬的Modbus TCP Slave寄存器中。下圖展示了,如何透過python程序為Output_Word_1賦值。

圖1.3 透過修改文件為變量賦值程序示例

圖1.4 寫入數據程序運行結果
透過這種方式讀取和寫入數據,過程不是很複雜,但問題在於:需要提前知道變量的offset和length,這對於編程開發人員來說很不友好。我們希望的是直接通過變量名,而不需要知道變量的存儲位置及長度,就可以對變量進行操作,下面一個方法將彌補這個缺點。
2. 透過ioctl讀取
在計算機中,ioctl(input/output control)是一個專用於設備輸入輸出操作的系統調用,該調用傳入一個跟設備有關的請求碼,系統調用的功能完全取決於請求碼。
RevPi的系統中已經預定義好了一些ioctl功能,我們可以通過調用這些功能,獲取變量的offset、length等訊息,並讀取數據。

圖2.1 ioctl功能定義

圖2.2 ioctl讀取數據示例程序

圖2.3 ioctl讀取數據程序運行結果

圖2.4 ioctl為變量賦值程序示例

圖2.5 ioctl為變量賦值程序運行結果
實際上ioctl功能15和16主要用於長度為1bit的變量的讀寫,如果將其用於2byte的變量的讀寫,程序比較繁雜,且可能會帶來其它問題。
示例程序採用ioctl功能15和16讀寫變量數據僅僅是為了展示其功能,在實際使用時,通過ioctl功能17得到變量的offset之後,用f.seek()和f.read()以及f.write()實際上更方便。

圖2.6 ioctl訪問2byte數據示例程序


雖然採用第二種方法,我們不再需要提前記住變量的offset,但這種程序比較繁雜,只是為了讀取或者修改一個變量就需要很多程式碼。在實際開發中,這也會給開發人員帶來很多困擾。
那有沒有一種更簡單的方式讓我們能夠輕鬆便捷的控制變量呢?很幸運地,確實有這樣的方法!以下就跟大家介紹第三種方法:revpimodio2模塊。
3. 透過revpimodio2模塊讀取
如前所述,如果要使用Python3編寫程序,可以使用FileHandler打開過程映像並讀取/寫入模塊中的數據。但是,變量名稱在那裡不可用,必須在文件中搜索IO的各個位…計算…讀取…寫入…
這給開發人員帶來很大的困擾,但這也正是python3-revpimodio2發揮作用的地方!與過程映像的所有通訊均可在該模塊內部執行。不僅如此,python3-revpimodio2還為開發者提供了一些其它功能。總的來說,通過這個模塊,可以讓所有Python開發人員省去很多工作。
如需了解詳細訊息,可以查看:https://revpimodio.org/en/homepage/。在這裡,本文僅僅展示如何借助revpimodio2模塊讀取或寫入變量。

圖3.1 revpimodio2示例程序


圖3.2 revpimodio2示例程序運行結果