NXP iMX7 異構雙核心開發除錯
By Toradex秦海
1). 簡介
在工業領域,很多時候會遇到實時任務和主控介面同時需要的場景,比如工業自動化的控制器等,通常情況下傳統做法是分別使用兩個獨立的處理器,比如一個Cortex-M4 ARM處理器來完成實時任務,另外再使用一個Cortex-A系列的ARM處理器來處理主控介面和命令控制,兩個處理器之間再通過某種通訊匯流排來互聯互通,比如串列埠,SPI之類。
這樣做的好處是兩個處理器相對分隔獨立,但缺點也很明顯,系統複雜性提高,資料面和控制面要單獨建立,正式基於此NXP提出了一個新的思路,就是在一個晶片中整合這兩個功能核心。
而本文所演示的ARM平臺來自於Toradex Apalis iMX7 ARM嵌入式平臺,這是一個基於NXP iMX7 ARM處理器的ARM計算機模組,在這個晶片中,NXP將Cortex-A7 ARM核心和Cortex-M4 ARM核心整合到了同一個晶片裡面,並且兩個核心共享儲存和外設資源,這使得對於上面提到的應用模式可以更精巧,高效的實現,接下來本文會基於這個平臺進行一個簡單的應用開發以及除錯示例。
2. 準備
a). Colibri iMX7S ARM核心版配合Colibri Evaluation Board,分別連線A7核心預設除錯串列埠UART1(載板X27)和M4核心預設除錯串列埠UART2(載板X25上)到開發主機方便除錯,另外由於iMX7S只支援一個USB介面,需要通過載板X30連線一個USB Hub後來擴充套件鍵盤滑鼠外設。更多關於Colibri iMX7的說明請參考
b). Colibri iMX7 A7核心系統使用整合Qt執行庫的Linux BSP V2.7版本,如何編譯和部署整合Qt image以及配置Qt開發環境請參考這裡。
c). 另外,由於本文演示示例使用到了載板上面的LED和按鍵資源,需要連線如下:
X10 SODIMM-106 -> X21 LED3
X10 SODIMM-135 -> X21 LED1
X10 SODIMM-133 -> X21 SW6
X10 SODIMM-127 -> X21 LED2
d). SEGGER J-Link 模擬器,USB一端連線開發主機,JTAG一端連線載板X13。
3). Colibri iMX7 M4核心FreeRTOS基本資料
a). Colibri iMX7 架構基本說明請參考如下:
https://developer.toradex.cn/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7
b). 本示例中M4核心執行FreeRTOS v8系統,相關的原始碼和sample程式請從下面git下載:
http://git.toradex.cn/cgit/freertos-toradex.git/
c). 基本的SDK配置和編譯請參考如下:
d). 編譯好的M4 firmware如何在Colibri iMX7上面載入執行請參考如下:
e). 幾個自帶的sample程式碼簡單說明請參考如下:
https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Examples
4). Colibri iMX7 M4核心除錯環境配置
a). 在上一章節編譯部分資料中有提到編譯自帶sample code只需要執行專案中的 build_all.sh 指令碼,就可以生成release和debug專案,然後進入debug專案目錄,開啟“build_debug.sh”指令碼,可以看到通過“-G”引數指定了編譯系統,這裡預設是“Eclipse CDT4 - Unix Makefiles”,支援的是Eclipse指定了,因此本文示例就基於Eclipse進行除錯。
b). 由於Ubuntu 16.04 系統自帶的Eclipse版本比較低,不支援後續需要的plugin,因此需要手動安裝最新版本的Eclipse:
./ 首先安裝最新版本的openjdk
-------------------------------
$ sudo add-apt-repository ppa:openjdk-r/ppa
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk
-------------------------------
./ 從下面地址下載最新的Eclipse CPP,解壓後可以直接執行,無需安裝。
http://www.eclipse.org/downloads/packages/
c). 下載安裝J-Link software and documentation pack,安裝好第一次執行,會自動檢查J-Link firmware並升級到最新版本。
https://www.segger.com/products/debug-probes/j-link/
d). 執行Eclipse CPP,安裝J-Link GDB plugin
-------------------------------
// Main menu -> Help -> install new software
// 輸入下面地址
https://dl.bintray.com/gnu-mcu-eclipse/updates/
// 在列表裡面安裝下面plugin
GNU ARM C/C++ J-Link Debugging
-------------------------------
e). 在Eclipse 中匯入需要debug的專案
-------------------------------
./ 選擇 File -> Import -> General -> Existing Projects into Workspace
./ 在 “Select root directory”,輸入專案“armgcc/debug”資料夾目錄地址,此時會自動識別出已經編譯好的debug專案,完成專案匯入,比如本次示例專案名字為gpio-freertos,匯入如下:
f). 在Eclipse 中進行debug GDB引數配置
./ 開啟 Run –> Debug Configurations,可以看到左邊側欄中 GDB SEGGER J-Link Debugging專案下一般會自動出現剛才匯入的專案,右邊是對應的一些選項。
./ Main選項卡,一些基本名字等資訊
./ Debugger 選項卡
需要注意的地方:
// Device name,Colibri iMX7對應就是這個名字,具體的列表可以參考這裡
// Interface選擇使用的模擬器介面,我這裡使用的是JTAG的
// Other options,非常關鍵,-scriptfile指定的檔案請從這裡下載使用即可,其他引數一樣就行,當然熟悉配置的話也可以進行修改。
// GDB Client Setup -> Executable,設定為SDK目錄下的bin/arm-none-eabi-gdb檔案
./ Startup 選項卡
需要注意的地方:
// 取消 Enable flash breakpoints
// 新增命令列 monitor reset 0
// 勾選 RAM application (reload after each reset/restart)
g). 至此,GDB配置完畢,點選Debug按鈕即可進行debug了。
5). Colibri iMX7 M4核心示例程式
a). 本程式主要實現三個並行任務:
./ LED1, LED2和LED3的跑馬燈任務,時間間隔從最小100ms到最大1000ms,每檔間隔為100ms。
./ 按鍵中斷任務,每按鍵一次,跑馬燈的時間間隔增加100ms,如果已經到達1000ms上限,再次按鍵則回到100ms初始值。同時在每次跑馬燈時間間隔更改後,給A7核心系統發訊息通知。
./ 和A7核心通訊任務,當接收到A7發來的跑馬燈時間間隔指令後,按指令配置跑馬燈時間間隔,同時配置完成後給A7核心發訊息通知。
b). 具體程式碼請見如下git地址
https://github.com/simonqin09/iMX7_M4_Runniung_LED_Demo/tree/master/gpio_freertos
./ 程式碼中對應上面三個任務分別由三個task實現
跑馬燈 – ToggleTask
按鍵 – SwitchTask
通訊 – StrEchoTask
./ ToggleTask就是簡單的通過vTaskDelay實現了跑馬燈的間隔時間
./ SwitchTask 通過GPIO中斷響應,來捕獲按鍵同時更新間隔時間,並通知A7
./ StrEchoTask主要通過OPAMP/Rpmsg實現和A7訊息的接收,另外通過Semaphore來實現幾個task之間的切換,關於Semaphore的使用是異構雙核架構下M4程式設計的重點,具體可以參考下面FreeRTOS官方文件說明:
https://www.freertos.org/a00113.html
6). Colibri iMX7 A7核心示例程式
a). 在展示A7程式程式碼之前需要先進行一些關於A7 Linux系統的說明:
./ 由於iMX7 A7和M4是共享外設,因此在開發前需要先區分好M4所需要的外設,同時在A7 Linux的device tree
中將這些外設disable,以免產生衝突,比如本示例,主要就使用了幾個GPIO資源,以及M4除錯串列埠,因此需要在A7 device tree中確保未使用對應的GPIO和串列埠資源,具體關於device tree的修改編譯這裡就不詳述了,具體可以參考這裡。當然,如果只是臨時測試,也可以直接在uboot中配置,詳細可以參考如下:
./ 如果需要M4和A7通過Rpmsg進行通訊,需要在A7 Linux下載入相關驅動,目前Toradex Linux BSP V2.7版本已經包含了驅動,只需要通過下面方式載入即可:
-------------------------------
modprobe imx_rpmsg_tty
-------------------------------
另外,如果需要開機自動載入,可以增加一個systemd自啟動專案來實現。
b). A7 Rpmsg通訊的Qt應用程式碼如下:
https://github.com/simonqin09/iMX7_M4_Runniung_LED_Demo/tree/master/qt-rpmsg
./ 程式分為兩個執行緒,主執行緒mainwindow實現主要圖形介面顯示,同時實現傳送訊息功能;另外一個子執行緒主要負責實時獲取M4發來的訊息並顯示在主介面的對應位置。
./ 由於Rpmsg Linux驅動載入後,會虛擬出一個串列埠裝置,因此基本的傳送接收就是Linux下串列埠的基本操作,具體說明可以參考這裡。
7). 完整程式的部署測試
a). 首先在uboot下通過SD卡或者tftp將編譯好的M4核心firmware下載儲存到imx7 flash裡面並開機自動載入,通過SD卡相關命令可以參考這裡。
-------------------------------
// download
# ubi part ubi
# tftp ${loadaddr} gpio_freertos.elf
# ubi write ${loadaddr} m4firmware ${filesize}
// autorun
# setenv m4boot 'ubi read ${loadaddr} m4firmware && bootaux ${loadaddr}'
# saveenv
-------------------------------
b). 然後進入linux,建立兩個開機自啟動服務,一個用於載入imx_rpmsg_tty驅動,另外一個用於載入Qt應用程式qt-rpmsg
-------------------------------
// script to start imx_rpmsg_tty
$ cd /home/root
$ vi rpmsg
#!/bin/bash
modprobe imx_rpmsg_tty
exit 0
// system service file to autorun rpmsg on startup
$ cd /etc/systemd/system
$ vi rpmsg-load.service
[Unit]
Description=load Rpmsg driver
After=multi-user.target
[Service]
Type=simple
ExecStart=/home/root/rpmsg
[Install]
WantedBy=multi-user.target
$ systemctl enable rpmsg-load.service
-------------------------------
關於qt應用qt-rpmsg的開機自動載入請參考這裡說明,這裡就不贅述。
c). 重新啟動,可以看到在開機馬上uboot啟動瞬間LED跑馬燈已經開始運轉,證明M4 firmware已經執行起來,然後Linux啟動後Qt應用起來,可以對跑馬燈時間間隔進行增加和減少操作,同時按鍵更改跑馬燈時間間隔的結果也會即時反饋到應用介面上來。
8). 總結
通過上述示例可見,通過iMX7這樣異構多核架構的處理器,可以更簡潔高效的實現原來需要兩個分立處理器來完成的任務,簡化的硬體設計,軟體開發也相對更統一,資料面分享可以直接通過記憶體共享非常方便,相信未來會有越來越多的嵌入式應用採用這樣的方案。