樹莓派的cpu與gpu通信設(shè)計(jì)淺析
掃描二維碼
隨時(shí)隨地手機(jī)看文章
樹莓派的cpu與gpu通信設(shè)計(jì)淺析
-
1.本文介紹
-
2.樹莓派的videocoreiv
-
3.訪問策略
-
4.framebuff圖像訪問
-
5.注意事項(xiàng)
1.本文介紹
異構(gòu)設(shè)計(jì)在嵌入式開發(fā)過程中非常的重要,比如mcu與mpu的異構(gòu),還有兩個(gè)不同架構(gòu)的cpu或者兩個(gè)不同架構(gòu)的mpu等等。本文主要介紹樹莓派的cpu與gpu通信的設(shè)計(jì)思想。并且通過在樹莓派4上進(jìn)行測試,測試訪問gpu所提供的功能。
2.樹莓派的videocoreiv
樹莓派上電啟動(dòng)時(shí),首先啟動(dòng)的是GPU,然后從sd卡中加載啟動(dòng)文件,緊接著啟動(dòng)CPU,所以GPU在學(xué)習(xí)使用樹莓派時(shí)非常重要。可以通過下面的倉庫看到底層的GPU的使用。
https://github.com/hermanhermitage/videocoreiv
要想CPU與GPU之間訪問,首先需要了解兩個(gè)設(shè)計(jì)的架構(gòu),下面從樹莓派3b攝像頭傳輸圖像的角度去理解一下這個(gè)架構(gòu)的設(shè)計(jì)。
BCM2835 SOC是芯片的設(shè)計(jì)架構(gòu),里面集成了一個(gè)ARM Cortex A53的CPU與VideoCore IV GPU。攝像頭的MIPI數(shù)據(jù)傳輸線連接在GPU上,其攝像頭SCCB連接在CPU上。
GPU上運(yùn)行著一個(gè)RTOS,就是VCOS其實(shí)是基于ThreadX系統(tǒng)實(shí)現(xiàn)的。CPU與GPU共享RAM。當(dāng)啟動(dòng)圖像傳輸?shù)臅r(shí)候,實(shí)際上就是首先由GPU出來圖像時(shí)序,然后將圖像放到RAM中,CPU與GPU通過VCHI管道進(jìn)行通信,啟動(dòng)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的功能比較齊全。所以訪問這些信息是如何進(jìn)行的呢?
3.訪問策略
如果要實(shí)現(xiàn)CPU與GPU的通信,樹莓派做了一個(gè)控制器,就是一個(gè)獨(dú)立的外設(shè)接口,叫做Mailbox Peripheral。這個(gè)Mailbox的外設(shè)的寄存器布局如下:
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 |
+-----------------------------------------------------------+-+-+
寄存器的起始地址為外設(shè)起始地址加速0xB880的偏移量。例如在樹莓派4上其外設(shè)的地址為0xFE000000。上述就是CPU核操作GPU時(shí)的寄存器的布局。寄存器并不多,只需要判斷狀態(tài)即可。
當(dāng)進(jìn)行通信時(shí),要往寄存器寫的數(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個(gè)通道可以指定,每個(gè)通道有著特定的用途,如上定義所示。寫數(shù)據(jù)(write data)實(shí)際上寫的是一個(gè)消息列表的地址,這個(gè)消息列表可以是一個(gè)數(shù)組。叫做msgbox。這個(gè)地址一般都是要求4字節(jié)對齊的,因?yàn)樯蠄D寄存器中前面4字節(jié)是用于存放通道信息的。
一般一個(gè)消息的空間布局如下:
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 | +---------------------------------------------------------------+
獲取版本信息,傳遞消息實(shí)際實(shí)現(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é)果的消息包傳遞到原來的地址中,這樣就可以實(shí)現(xiàn)基本的通信邏輯了。
具體的完整的實(shí)現(xiàn)細(xì)節(jié)可以參考rt-thread/bsp/raspberry-pi/raspi3-64/driver/mbox.c。
4.framebuff圖像訪問
上述基本上講述了cpu和gpu的訪問流程,那么如果想使用樹莓派的hdmi接口進(jìn)行圖像顯示,該如何進(jìn)行設(shè)計(jì)呢?首先樹莓派在設(shè)計(jì)的時(shí)候,并未在CPU集成圖像控制接口,那只能通過GPU來實(shí)現(xiàn)了。訪問其實(shí)就是利用mbox的通信進(jìn)行實(shí)現(xiàn),利用TAG的消息進(jìn)行區(qū)分。
下面是framebuff相關(guān)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ù)。
當(dāng)傳遞消息后GPU會將申請到的framebuff的地址通過mbox[5]傳遞回來,當(dāng)訪問這個(gè)地址的時(shí)候,實(shí)際上就是訪問這個(gè)framebuff。我們不用去關(guān)心具體的時(shí)序邏輯問題,當(dāng)然,可能需要注意的是圖像傳輸完成之后的中斷。
5.注意事項(xiàng)
在訪問GPU的時(shí)候,需要注意的是寄存器的地址一定需要通過MMU映射成非cache的模式,否則可能會出現(xiàn)內(nèi)存一致性問題,導(dǎo)致實(shí)際上通道的數(shù)據(jù)沒有寫到寄存器中。訪問圖像的時(shí)候,也需要注意這個(gè)問題,因?yàn)閒ramebuff也需要非cache訪問,這些都是在實(shí)際項(xiàng)目設(shè)計(jì)中需要注意的問題??傊谑褂脴漭蒅PU和CPU的通信過程中,弄清楚BCM的SOC的設(shè)計(jì)思想,注意幾個(gè)寄存器,并且注意消息的傳輸格式,那么訪問GPU時(shí)就不是什么很大的問題了。其中比較有借鑒意義的是共享內(nèi)存的方式訪問,還有就是采用不同的tag進(jìn)行消息機(jī)制的傳遞。