Tina Linux E907開發指南
1 編寫目的
介紹v85X 上E907 的啟動環境和AMP 的環境搭建。
2 使用范圍
全志V85X 系列芯片
3 環境
A7 SDK:Tina E907 SDK:melis
4 SDK 快捷命令說明
這里主要介紹幾個下文會用到的命令,并不會介紹全部命令,如果想了解全部命令,可以在lunch 方案后使用hmm打印出所有tina提供的快捷命令。
ckernel, m kernel_menuconfig, mkernel:分別對應進入到內核目錄,配置內核,單獨編譯內核
cboot0, mboot0:進入boot0 目錄,單獨編譯boot0
cmelis, mmelis, mmelis menuconfig:分別對應進入melis 根目錄,編譯melis,配置melis
make:編譯整個tina 除了melis 外的所有東西,如boot0,uboot,內核,跟文件系統等
cconfigs:進入板級配置目錄,這里主要存放板級的設備樹,分區等配置文件
p:打包命令,將編譯后的東西打包成固件
5 E907 啟動環境
5.1 預先工作
選擇方案
cd tina
source build/envsetup.sh
lunch
選擇對應的V85x方案
5.2 配置boot0 啟動e907
e907 在boot0 階段啟動,需要對boot0 進行一些配置
cboot0
vim board/sun8iw21p1/common.mk
# 如下圖取消注釋
保存退出
mboot0 #編譯
?
圖5-1: 配置1
?
5.2.1 關閉RISCV 的IOMMU
本步驟只有需要在boot0 階段啟動E907 的需要配置。打開設備樹,注釋掉下面2 條屬性,因為 e907 在boot0 階段就啟動了,不能打開其IOMMU。
cconfigs
vim ../board.dts
?
圖5-2: 關閉IOMMU
?
5.3 配置打包e907 固件
cconfigs
cd ../../default/
vim boot_package_nor.cfg # 取消melis-elf選項的注釋,如下圖
vim boot_package.cfg # 取消melis-elf選項的注釋,如下圖
保存退出
?
圖5-3: 打包配置
?
5.4 Linux 配置
ckernel
m kernel_menuconfig
# 如下圖選中2個驅動
mkernel -j
?
圖5-4: 補丁下載
?
mmelis menuconfig # 如下圖選中standby支持
?
圖5-5: e907-standby 配置
?
5.5 編譯打包
至此關于E907 啟動的配置完成,進行編譯燒錄即可
make -j16 # 編譯tina
mmelis # 編譯melis
p
燒錄
6 AMP 環境搭建
AMP 環境用于Linux 和E907 間通信,Linux 依賴于2 個驅動,melis 依賴于openamp 驅 動。
remoteproc 驅動:主要用來管理E907 固件的加載器的
rpmsg:在virtio 框架上實現的消息傳送框架
6.1 Linux 配置
注意:需要前面的啟動環境配置好后,再執行以下操作。 需要打開的配置有:
remoteproc 驅動
rpmsg 驅動
6.1.1 remoteproc 驅動
ckernel
m kernel_menuconfig
選中
?
圖6-1: rproc config
?
6.1.2 rpmsg 驅動
ckernel m kernel_menuconfig # 紅框必選,藍色框為sdk提供的rpmsg demo,視情況而選擇 # 建議選上sunxi rpmsg ctrl driver 方便后面測試rpmsg通信功能
選中
?
圖6-2: rpmsg config
?
6.2 melis 配置
主要進行2 個配置:
msgbox 配置
openamp 配置
6.2.1 msgbox 配置
mmelis menuconfig #選擇下面2項
選中
?
圖6-3: msgbox-melis config
?
6.2.2 openamp 配置
mmelis menuconfig # 紅框是必選,藍框是可選的rpmsg demo
剛剛Linux 端選擇了rpmsg hearbeat demo 和ctrl driver,我們這里也選上對應的驅動hearbeatdriver 和client driver。 選中
?
圖6-4: openamp config
?
為了方便在控制臺測試rpmsg 通信,rpmsg client driver 還需開啟下面2 個選項
?
圖6-5: rpmsg client config
?
6.3 打包
make -j16 # 編譯tina mmelis # 編譯melis p 燒錄
6.4 測試
本章節介紹一些AMP 提供的控制臺命令,用于測試AMP 環境
6.4.1 E907 控制
1.在linux 控制臺執行:echo stop > /sys/kernel/debug/remoteproc/remoteproc0/state (停止e907)
2.在linux 控制臺執行:echo start > /sys/kernel/debug/remoteproc/remoteproc0/state (啟動e907)
若控制臺出現remoteproc0: remote processor e907_rproc is now up,表明啟動e907 成功。 如果使能了rpmsg_heartbeat 和rpmsg_ctrl 驅動,可以在Linux 控制臺start 之后會看到如下輸出:
?
圖6-6: rproc test
?
紅框里面表示有2 個設備成功創建,代表rpmsg 正常。
6.4.2 rpmsg 通信測試
借助rpmsg_ctrl 驅動幫助我們進行測試
6.4.2.1 名字監聽.
平臺:melis 控制臺 輸入如下圖命令: eptdev_bind 命令:監聽name=test 的鏈接,最大連接數5 個
?
圖6-7: rproc test
?
6.4.2.2 節點創建
平臺:Linux 控制臺 輸入如下圖的命令,進行節點創建
?
圖6-8: rpmsg test
?
?
圖6-9: rpmsg test
?
根據log 可以看出,創建了一個rpmsg0-4 5 個設備,因為melis 只監聽的5 個,故最多只能創建5 個。
6.4.2.3 節點通信
rpmsg 節點支持標準的文件操作,直接讀寫即可。 Linux 向e907 發數據:
?
圖6-10: rpmsg test
?
?
圖6-11: rpmsg test
?
e907 向Linux 發數據:
?
圖6-12: rpmsg test
?
?
圖6-13: test
?
6.4.2.4 節點關閉
Linux 主動釋放:
?
圖6-14: rpmsg test
?
?
圖6-15: rpmsg test
?
e907 主動釋放:
?
圖6-16: rpmsg test
?
?
圖6-17: rpmsg test
?
e907 端接觸監聽,會釋放所有的鏈接:
?
圖6-18: rpmsg test
?
?
圖6-19: rpmsg test
?
7 開發使用
7.1 rpmsg 內核開發
linux 端請參考driver/rpmsg/rpmsg_client_e907.c 。
melis 端請參考ekernel/subsys/thirdparty/openamp/rpmsg_demo/ 目錄下的文件。
7.2 rpmsg 用戶層接口
控制臺調試命令參考測試章節,這里列舉代碼使用示例。
Linux 端:
#include # 創建端點 int fd; struct rpmsg_ept_info info; char ept_dev_name[32]; strcpy(info.name, "test"); info.id = 0xfffff; # id由itctl進行更新 fd = open(ctrl_dev, O_RDWR); ret = ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &info); # 當ioctl返回值==0時,端點已經創建成功,設備節點會出現在/dev/rpmsg%d(=info.id)下 close(fd); #讀寫設備節點 snprintf(ept_dev_name, 32, "/dev/rpmsg%d", info.id); fd = open(ept_dev_name, O_RDWR); write,read,poll... close(fd); # 關閉節點 fd = open(ctrl_dev, O_RDWR); ret = ioctl(fd, RPMSG_DESTROY_EPT_IOCTL, &info); close(fd);
melis 端:
方法1:基于rpmsg_ctrl 驅動,等待主機建立連接
// 頭文件 #include static int ept_cb(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { // 收到數據 } int bind_cb(struct rpmsg_ept_client *client) { // client綁定,每個client代表一個連接 // client->priv和client->ept->priv 可供用戶使用 } int unbind_cb(struct rpmsg_ept_client *client) { // 連接關閉 } int main() { // cnt: 監聽的數量,即最多對test創建cnt個連接 // 最后一個參數priv,其實里面設置的是client->priv rpmsg_client_bind("test", ept_cb, bind_cb, unbind_cb, cnt, NULL); // do some things // 取消綁定會unbind所有與其相關的client rpmsg_client_unbind("test"); }
具體代碼參考ekernel/subsys/thirdparty/openamp/rpmsg_demo/rpmsg_ctrl/test.c;
方法2:基于rpmsg 原生框架,melis 端主動創建連接,觸發主機端的rpmsg driver 的probe。
melis 端代碼參考:
1.ekernel/subsys/thirdparty/openamp/rpmsg_demo/demo.c
2.ekernel/subsys/thirdparty/openamp/rpmsg_demo/hearbeat.c
Linux 端參考代碼:
1.drivers/rpmsg/rpmsg_client_e907.c
2.drivers/rpmsg/rpmsg_client_heart.c
7.3 amp 控制臺
SDK 在Linux 端提供了進入E907 控制臺的功能,配置步驟如下:
內核配置
ckernel m kernel_menuconfig # 選擇下圖配置
?
圖7-1: rpmsg config
?
Tina 配置
croot m menuconfig # 選擇下圖配置
?
圖7-2: amp_shell config
?
melis 配置
?
圖7-3: amp_shell config
?
編譯& 打包& 下載
mmelis -j32 make -j32 p
使用
在echo start > /sys/kernel/debug/remoteproc/remoteproc0/state 后檢查有無rpmsg_ctrl 成功創建的log 或者是否存在/dev/rpmsg_ctrl0 節點。如果正常,直
接在Linux 控制臺啊輸入amp_shell 即可進入e907 控制臺,amp_exit退出控制臺。支持執行多次amp_shell,開啟多個控制臺。
?
圖7-4: amp_shell test
?
?
圖7-5: amp_shell test
?
7.4 大數據傳輸
由于rpmsg 特性,不適合傳輸大數據量;如需使用大數據傳輸,請參考本章節。
7.4.1 配置
內核打開rpbuf 驅動:
m kernel_menuconfig Device Drivers ---> RPBuf drivers ---> -*- RPBuf device interface <*> RPMsg-based RPBuf service driver <*> Allwinner RPBuf controller driver <*> Allwinner RPBuf sample driver
Note:Allwinner RPBuf sample driver 是一個簡單的rpbuf 內核層使用demo,可以不使能。
e907 配置:
Kernel Setup Subsystem support Allwinner Components Support RPBuf framework [*] RPMsg-based RPBuf service component [*] RPBuf controller component [*] RPMsg-based RPBuf service component demo OpenAMP Support [*] RPBuf demo
Tina 打開rpbuf_demo 軟件包:
m menuconfig Allwinner ---> RPBuf ---> <*> rpbuf_demo <*> rpbuf_test
7.4.2 測試
rpmsg_test:會自動生成隨機數據并附帶MD5 校驗值,另一端收到會重新計算MD5 并與收到的進行對比。
(e907) rpbuf_test -c -N "rpbuf_demo" -L 0x100000 # 創建size=0x100000的buffer (Linux) rpbuf_test -d 1000 -s -L 0x100000 -N "rpbuf_demo" # 發送測試數據 (Linux) rpbuf_test -r -t 1000 -L 0x100000 -N "rpbuf_demo" # 接收數據 (e907) rpbuf_test -s -L 0x100000 -N "rpbuf_demo" #發送測試數據 (e907) rpbuf_test -N "rpbuf_demo" -d # 刪除buffer
出現success 表明校驗成功。
過程log 如下:
?
圖7-6: Linux 端log
?
?
圖7-7: e907 端log
?
rpbuf_demo:用于在控制臺簡單傳輸數據
(e907) rpbuf_demo -c -N "rpbuf_demo" -L 0x1000 # 創建size=4k的buffer (Linux) rpbuf_demo -d 1000 -L 0x1000 -N "rpbuf_demo" -s "hello" # 發送數據,并在1000ms后釋放 buffer (Linux) rpbuf_demo -r -t 1000 -L 0x1000 -N "rpbuf_demo" # 接收數據 (e907) rpbuf_demo -s "hello" -N "rpbuf_demo" # 發送數據 (e907) rpbuf_demo -N "rpbuf_demo" -d # 刪除buffer
?
圖7-8: Linux 端log
?
?
圖7-9: e907 端log
?
7.4.3 使用
內核層接口,參考drivers/rpbuf/rpbuf_sample_sunxi.c: Linux 端使用流程:
在需要用到rpbuf 接口的驅動的設備樹節點種添加一條屬性:rpbuf = <&rpbuf_controller0>;, 可以創建多個controller,當面默認只有一個rpbuf_controller0;
獲取controller:調用controller = rpbuf_get_controller_by_of_node(np, 0);
創建buffer:調用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);
接收數據:收到數據時候會調用cbd->rx_cb 回調
判斷狀態:創建出的buffer 不一樣馬上可用,需要用判斷狀態,調用rpbuf_buffer_is_available(buffer)
發送數據:
buf_va = rpbuf_buffer_va(buffer);
buf_len = rpbuf_buffer_len(buffer);
直接對buf_va 地址進行寫入即可
rpbuf_transmit_buffer(buffer, offset, data_len);
釋放buffer:rpbuf_free_buffer(buffer);
應用層端口,具體細節可以參考package/allwinner/rpbuf/
創建buffer
fd = open(0, O_RDWR);
ioctl(fd, RPBUF_CTRL_DEV_IOCTL_CREATE_BUF, &buffer->info);
buf_fd = open(buf_dev_path, O_RDWR);
addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, buf_fd, 0);
接收數據:
rpbuf_receive_buffer_block(buffer, &offset, &data_len) 阻塞接收
rpbuf_receive_buffer_nonblock(buffer, &offset, &data_len) 非阻塞接收
發送數據:
buf_va = rpbuf_buffer_va(buffer);
直接對buf_va 地址進行寫入即可
rpbuf_transmit_buffer(buffer, offset, data_len);
釋放buffer:
close(buf_fd);
ioctl(fd, RPBUF_CTRL_DEV_IOCTL_DESTROY_BUF, &buffer->info);
close(fd);
e907 端接口,可以參考ekernel/subsys/aw/rpbuf/rpbuf_demo/rpbuf_demo.c e907 端使用流程:
獲取controller:調用controller = rpbuf_get_controller_by_id(0); 代碼默認提供一個controller, 這里直接使用
創建buffer:調用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);
接收數據:收到數據時候會調用cbd->rx_cb 回調
判斷狀態:創建出的buffer 不一樣馬上可用,需要用判斷狀態,調用rpbuf_buffer_is_available (buffer)
發送數據:
buf_va = rpbuf_buffer_va(buffer);
buf_len = rpbuf_buffer_len(buffer);
直接對buf_va 地址進行寫入即可
rpbuf_transmit_buffer(buffer, offset, data_len);
釋放buffer:rpbuf_free_buffer(buffer);
7.4.4 Note
關于controller:代碼默認已經提供了一個基于rpmsg 實現的controller0 了,正常情況下 直接使用改controller 即可
關于rpbuf_alloc_buffer 的ops 參數:controller0 已經基于ion 實現了內存分配函數。如 無必要,使用controller 的內存分配函數即可,即創建buffer 時,ops 參數置NULL。
關于互斥:由于通信雙方都能拿到的buffer 的地址,難以在驅動實現互斥,所以需要在具體 應用上自行保證互斥。
8 其他
8.1 rpmsg 需知
端點是rpmsg 通信的基礎;每個端點都有自己的src 和dst 地址,范圍(1 - 1023,除了0x35)
rpmsg 每次發送數據最大為512 -16 字節;(數據塊大小為512,頭部占用16 字節)
rpmsg 使用name server 機制,當E907 創建的端點名,和linux 注冊的rpmsg 驅動名一樣的時候,rpmsg bus 總線會調用其probe 接口。所以如果需要
Linux 端主動發起創建端點并通知e907,則需要借助上面提到的rpmsg_ctrl 驅動。
rpmsg 是串行調用回調的,故建議rpmsg_driver 的回調中不要調用耗時長的函數,避免影響其他rpmsg 驅動的運行
8.2 rpbuf 簡介
rpbuf 全志基于rpmsg 開發的一套通信機制,它主要解決rpmsg 不適合傳輸大數據量的問題。 其實現原理是使用rpmsg 傳輸數據的地址,而不是數據的本身,避免了數據的多次拷貝以及每次 傳輸不能大于496 字節的限制。 rpbuf 中使用名字和長度來唯一標識一個buffer,故不能創建相同名字的buffer。 rpbuf 中的buffer 有3 個狀態:
remote_dummy_buffers:該buffer 遠端已創建,本地未創建
local_dummy_buffers:該buffer 本地已創建,遠端未創建
buffers:遠端、本地已創建,此時buffer 才可用
8.3 修改e907 地址
目前在perf1 板子上,給e907 預留的內存為:0x48000000 開始的4M 空間
如果需要修改E907 固件的運行地址和大小,可按如下步驟進行修改:
8.3.1 修改設備樹(Linux)
cconfigs vim ../board.dts # 找到e907_dram項,修改成想要的地址,例如這里向修改成0x49000000 e907_dram: riscv_memserve { reg = <0x0 0x49000000 0x0 0x00400000>; no-map; }; # 重新編譯內核 mkernel
8.3.2 修改配置項(melis)
mmelis menuconfig # 如下圖進行修改;e907沒有mmu,故第一項和第二項相等 # 將第一項和第二項改成0x49000000 # 第三項為大小,可按需修改
?
圖8-1: e907 dram config
?
8.3.3 修改鏈接腳本(melis)
cmelis vim source/projects/v853-e907-ver1-board/kernel.lds # 如下圖所示,按照所需修改DRAM_SEG_KRN 項目 mmelis -j16
?
圖8-2: e907 lds config
?
8.4 添加新板級注意事項
當用戶需要添加新的板子時,需要注意修改build/expand_melis.sh 來支持mmelis, cmelis命令。例如,用戶在添加了新的板級v853_user,在melis 添加了新的板
級e907_user,則需要對build/expand_melis.sh文件進行如下修改:
?
圖8-3: 新板級配置
?
8.5 melis 系統
8.5.1 常用命令
help:列出當前系統支持的所有命令
p addr [len]:打印內存數據
m addr value:修改內存數據
top:顯示當前系統各個線程CPU 占用率
ps:顯示當前系統各個線程狀態
free:查看當前系統內存信息
8.5.2 自定義命令
當用戶想要在e907 控制臺上執行自定義的命令時候,可以用FINSH_FUNCTION_EXPORT_ALIAS導出自定義的函數。例如:
?
圖8-4: 添加自定義命令
?
?
圖8-5: 執行自定義命令
?
-
Linux
+關注
關注
87文章
11292瀏覽量
209328 -
Amp
+關注
關注
0文章
81瀏覽量
47155 -
開發指南
+關注
關注
0文章
34瀏覽量
7538 -
Tina
+關注
關注
2文章
45瀏覽量
16976
發布評論請先 登錄
相關推薦
評論