Mailboxes 是 ARM Cores 與 VideoCore GPU 間溝通的橋樑,透過 Mailboxes 可以設定 framebuffer 或是設定一些周邊元件。
參考 官方文件 及 課程網頁 來取得更詳細的使用說明。
Mailboxes Registers
傳送訊息至 Mailbox 的流程:
- Combine the message address (upper 28 bits) with channel number (lower 4 bits)
- Check if Mailbox 0 status register’s full flag is set.
- If not, then you can write to Mailbox 1 Read/Write register.
- Check if Mailbox 0 status register’s empty flag is set.
- If not, then you can read from Mailbox 0 Read/Write register.
- Check if the value is the same as you wrote in step 1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| int mbox_call(unsigned int* mbox, unsigned char channel) {
unsigned int r = (unsigned int)(((unsigned long)mbox) & (~0xF)) | (channel & 0xF);
// wait until full flag unset
while (*MBOX_STATUS & MBOX_FULL) {
}
// write address of message + channel to mailbox
*MBOX_WRITE = r;
// wait until response
while (1) {
// wait until empty flag unset
while (*MBOX_STATUS & MBOX_EMPTY) {
}
// is it a response to our msg?
if (r == *MBOX_READ) {
// check is response success
return mbox[1] == MBOX_CODE_BUF_RES_SUCC;
}
}
return 0;
}
|
透過 Channel 8, 9 並搭配不同的 tag number 來進行不同的 operation。
- Channel 8: Request from ARM for response by VC
- Channel 9: Request from VC for response by ARM (none currently defined)
參考 https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface 取得更多資訊。
注意 aligned(16),因為 mbox_call 在定址時會需要在後方放上 channel number
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| void mbox_board_revision() {
unsigned int __attribute__((aligned(16))) mbox[7];
mbox[0] = 7 * 4; // buffer size in bytes
mbox[1] = MBOX_CODE_BUF_REQ;
// tags begin
mbox[2] = MBOX_TAG_GET_BOARD_REVISION; // tag identifier
mbox[3] = 4; // maximum of request and response value buffer's length.
mbox[4] = MBOX_CODE_TAG_REQ; // tag code
mbox[5] = 0; // value buffer
mbox[6] = 0x0; // end tag
// tags end
mbox_call(mbox, 8);
uart_printf("Board Revision: %x\n", mbox[5]);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| void mbox_vc_memory() {
unsigned int __attribute__((aligned(16))) mbox[8];
mbox[0] = 8 * 4; // buffer size in bytes
mbox[1] = MBOX_CODE_BUF_REQ;
// tags begin
mbox[2] = MBOX_TAG_GET_VC_MEMORY; // tag identifier
mbox[3] = 8; // maximum of request and response value buffer's length.
mbox[4] = MBOX_CODE_TAG_REQ; // tag code
mbox[5] = 0; // base address
mbox[6] = 0; // size in bytes
mbox[7] = 0x0; // end tag
// tags end
mbox_call(mbox, 8);
uart_printf("VC Core base addr: 0x%x size: 0x%x\n", mbox[5], mbox[6]);
}
|
https://github.com/raspberrypi/firmware/wiki/Mailboxes
https://github.com/raspberrypi/documentation/tree/JamesH65-mailbox_docs/configuration/mailboxes