Mailbox

Mailboxes 是 ARM Cores 與 VideoCore GPU 間溝通的橋樑,透過 Mailboxes 可以設定 framebuffer 或是設定一些周邊元件。

參考 官方文件課程網頁 來取得更詳細的使用說明。

Mailboxes Registers

mbox.c

傳送訊息至 Mailbox 的流程:

  1. Combine the message address (upper 28 bits) with channel number (lower 4 bits)
  2. Check if Mailbox 0 status register’s full flag is set.
  3. If not, then you can write to Mailbox 1 Read/Write register.
  4. Check if Mailbox 0 status register’s empty flag is set.
  5. If not, then you can read from Mailbox 0 Read/Write register.
  6. 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 取得更多資訊。

Get Board Revision

注意 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]);
}

Get VC Memory

 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]);
}

Reference

https://github.com/raspberrypi/firmware/wiki/Mailboxes

https://github.com/raspberrypi/documentation/tree/JamesH65-mailbox_docs/configuration/mailboxes

comments powered by Disqus