樹莓派的cpu與gpu通信設計淺析
掃描二維碼
隨時隨地手機看文章
樹莓派的cpu與gpu通信設計淺析
-
1.本文介紹
-
2.樹莓派的videocoreiv
-
3.訪問策略
-
4.framebuff圖像訪問
-
5.注意事項
1.本文介紹
異構(gòu)設計在嵌入式開發(fā)過程中非常的重要,比如mcu與mpu的異構(gòu),還有兩個不同架構(gòu)的cpu或者兩個不同架構(gòu)的mpu等等。本文主要介紹樹莓派的cpu與gpu通信的設計思想。并且通過在樹莓派4上進行測試,測試訪問gpu所提供的功能。
2.樹莓派的videocoreiv
樹莓派上電啟動時,首先啟動的是GPU,然后從sd卡中加載啟動文件,緊接著啟動CPU,所以GPU在學習使用樹莓派時非常重要??梢酝ㄟ^下面的倉庫看到底層的GPU的使用。
https://github.com/hermanhermitage/videocoreiv
要想CPU與GPU之間訪問,首先需要了解兩個設計的架構(gòu),下面從樹莓派3b攝像頭傳輸圖像的角度去理解一下這個架構(gòu)的設計。
BCM2835 SOC是芯片的設計架構(gòu),里面集成了一個ARM Cortex A53的CPU與VideoCore IV GPU。攝像頭的MIPI數(shù)據(jù)傳輸線連接在GPU上,其攝像頭SCCB連接在CPU上。
GPU上運行著一個RTOS,就是VCOS其實是基于ThreadX系統(tǒng)實現(xiàn)的。CPU與GPU共享RAM。當啟動圖像傳輸?shù)臅r候,實際上就是首先由GPU出來圖像時序,然后將圖像放到RAM中,CPU與GPU通過VCHI管道進行通信,啟動DMA將圖像傳遞到CPU可以訪問的內(nèi)存區(qū)域。
那么GPU有哪些功能呢?
具體可以看下面的信息:
https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
1.得到固件信息
2.電源管理
3.頻率管理
4.內(nèi)存管理
5.framebuff
6.攝像頭
7.觸摸屏
整體來看GPU的功能比較齊全。所以訪問這些信息是如何進行的呢?
3.訪問策略
如果要實現(xiàn)CPU與GPU的通信,樹莓派做了一個控制器,就是一個獨立的外設接口,叫做Mailbox Peripheral。這個Mailbox的外設的寄存器布局如下:
0 4 8 12 16 20 24 28 32
+-------+-------------------------------------------------------+
0x00 |rd chn | read data |
+-------+-------------------------------------------------------+
0x04 | Unused |
... \\ \\
0x14 | Unused |
+-----------------------------------------------------------+-+-+
0x18 | status reserved |E|F|
+-----------------------------------------------------------+-+-+
0x1C | Unused |
+-----------------------------------------------------------+-+-+
0x20 |wt chn | write data |
+-----------------------------------------------------------+-+-+
寄存器的起始地址為外設起始地址加速0xB880的偏移量。例如在樹莓派4上其外設的地址為0xFE000000。上述就是CPU核操作GPU時的寄存器的布局。寄存器并不多,只需要判斷狀態(tài)即可。
當進行通信時,要往寄存器寫的數(shù)據(jù)是什么?
#define MBOX_CH_POWER 0 #define MBOX_CH_FB 1 #define MBOX_CH_VUART 2 #define MBOX_CH_VCHIQ 3 #define MBOX_CH_LEDS 4 #define MBOX_CH_BTNS 5 #define MBOX_CH_TOUCH 6 #define MBOX_CH_COUNT 7 #define MBOX_CH_PROP 8
一般來說是有9個通道可以指定,每個通道有著特定的用途,如上定義所示。寫數(shù)據(jù)(write data)實際上寫的是一個消息列表的地址,這個消息列表可以是一個數(shù)組。叫做msgbox。這個地址一般都是要求4字節(jié)對齊的,因為上圖寄存器中前面4字節(jié)是用于存放通道信息的。
一般一個消息的空間布局如下:
0 4 8 12 16 20 24 28 32 +---------------------------------------------------------------+ 0x00 | Buffer Size | +---------------------------------------------------------------+ 0x04 | Request/Response Code | +---------------------------------------------------------------+ 0x08 | Tags | ... \\ \\ 0xXX | Tags | +---------------------------------------------------------------+ 0xXX+4 | End Tag (0) | +---------------------------------------------------------------+ 0xXX+8 | Padding | ... \\ \\ 0xXX+16| Padding | +---------------------------------------------------------------+
獲取版本信息,傳遞消息實際實現(xiàn)代碼如下:
int bcm283x_mbox_hardware_get_revison(void) { mbox[0] = 8*4; // length of the message mbox[1] = MBOX_REQUEST; // this is a request message mbox[2] = MBOX_TAG_HARDWARE_GET_REV; mbox[3] = 4; // buffer size mbox[4] = 0; // len mbox[5] = 0; mbox[6] = 0; mbox[7] = MBOX_TAG_LAST; mbox_call(MBOX_CH_PROP, MMU_DISABLE); return mbox[5]; }
這樣就將消息傳遞給CPU的寄存器,寄存器通過訪問狀態(tài),并且將消息傳遞給GPU,GPU得到信息后,將消息填充,然后通過DMA將返回結(jié)果的消息包傳遞到原來的地址中,這樣就可以實現(xiàn)基本的通信邏輯了。
具體的完整的實現(xiàn)細節(jié)可以參考rt-thread/bsp/raspberry-pi/raspi3-64/driver/mbox.c。
4.framebuff圖像訪問
上述基本上講述了cpu和gpu的訪問流程,那么如果想使用樹莓派的hdmi接口進行圖像顯示,該如何進行設計呢?首先樹莓派在設計的時候,并未在CPU集成圖像控制接口,那只能通過GPU來實現(xiàn)了。訪問其實就是利用mbox的通信進行實現(xiàn),利用TAG的消息進行區(qū)分。
下面是framebuff相關TAG的宏定義
#define TAG_ALLOCATE_BUFFER 0x00040001 #define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003 #define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004 #define TAG_SET_DEPTH 0x00048005 #define TAG_SET_PIXEL_ORDER 0x00048006 #define TAG_GET_PITCH 0x00040008 #define TAG_SET_VIRT_OFFSET 0x00048009 #define TAG_END 0x00000000
通過mbox的數(shù)組傳遞消息,其tag為TAG_ALLOCATE_BUFFER,并且指定圖像的depth、width、height等參數(shù)。
當傳遞消息后GPU會將申請到的framebuff的地址通過mbox[5]傳遞回來,當訪問這個地址的時候,實際上就是訪問這個framebuff。我們不用去關心具體的時序邏輯問題,當然,可能需要注意的是圖像傳輸完成之后的中斷。
5.注意事項
在訪問GPU的時候,需要注意的是寄存器的地址一定需要通過MMU映射成非cache的模式,否則可能會出現(xiàn)內(nèi)存一致性問題,導致實際上通道的數(shù)據(jù)沒有寫到寄存器中。訪問圖像的時候,也需要注意這個問題,因為framebuff也需要非cache訪問,這些都是在實際項目設計中需要注意的問題。總之在使用樹莓派GPU和CPU的通信過程中,弄清楚BCM的SOC的設計思想,注意幾個寄存器,并且注意消息的傳輸格式,那么訪問GPU時就不是什么很大的問題了。其中比較有借鑒意義的是共享內(nèi)存的方式訪問,還有就是采用不同的tag進行消息機制的傳遞。