首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ARM到VideoCore在RPi3上创建C缓冲区

从ARM到VideoCore在RPi3上创建C缓冲区
EN

Stack Overflow用户
提问于 2017-11-27 02:48:01
回答 1查看 349关注 0票数 2

我正在研究hello world of裸金属在RPi3上,它正在打开ACT。

有许多很好的资源:

  1. Pi 1装配中的一些
  2. 戴维·韦尔奇用于Pi 1和2的优秀裸金属教程
  3. 以及Pi 1和2的blinker01例子

不幸的是,Pi3已经将LED移除了GPIO。相反,您必须发消息到其邮箱中的VideoCore (GPU)才能打开LED。

文档将该消息的缓冲区内容声明如下:

u32:以字节为单位的缓冲区大小(包括头值、结束标记和填充) u32:缓冲区请求/响应代码 请求代码: 0x00000000:进程请求所有其他值保留响应代码: 0x80000000:成功请求0x80000001:错误解析请求所有保留的其他值 U8.:串联标签序列 u32: 0x0 (结束标记) U8.:填充

我能够让此程序集示例成功地运行在Pi 3上。able开启并保持。

但我这样做的目的是学习裸金属C。我对C还不熟悉,但我对以下函数的功能有足够的了解:

代码语言:javascript
复制
/**
*** This is my own summary ** so likely incorrect
* 
* Assigns the address of the Mailbox which is 0x3f00b880 to the mailbox variable
* 
* Then waits until Mailbox 0 which the GPU uses as interrupt to the ARM;
* basically saying I am ready for your message.
* 
* The function then puts the address of the message buffer
* plus the channel to be used; in this case channel 4 for ACT LED
*/
unsigned int MailboxWrite ( unsigned int fbinfo_addr, unsigned int channel )
{
    unsigned int mailbox;

    mailbox=0x3f00b880;
    while(1)
    {
        if((GET32(mailbox+0x18)&0x80000000)==0) break;
    }
    PUT32(mailbox+0x20,fbinfo_addr+channel);
    return(0);
}

我遇到的问题(也许是因为很晚了,我已经做了好几个小时)是我不知道如何构造缓冲区。

我的想法是创建一个int数组,如下所示:

代码语言:javascript
复制
# ?? buffer size in bytes
# 0 is the request code
# 0x00038041 Tag ID (SET_GPIO_STATE)
# 8 value buffer size
# 0 Request/response size
# 130 ACT_LED pin number
# 1 Turn it on
# 0 End tag
[??,0,0x00038041,8,0,130,1,0]

如何计算缓冲区大小?是数组的大小吗?

那么,我是否只添加一个0作为第一个元素,然后运行sizeof并更新数组?

代码语言:javascript
复制
int[] buffer = [0,0,0x00038041,8,0,130,1,0];
buffer[0] = sizeof(buffer)
EN

回答 1

Stack Overflow用户

发布于 2017-11-27 13:04:25

也许回答我自己的问题是不好的,但我希望它能帮助到别人。

感谢@old_timer的评论,我搜索了裸金属论坛并找到了这个解决方案

代码语言:javascript
复制
void set_PI3LED(bool on) {
    uint32_t __attribute__((aligned(16))) mailbox_message[8];
    mailbox_message[0] = sizeof(mailbox_message);
    mailbox_message[1] = 0;
    mailbox_message[2] = 0x38041;
    mailbox_message[3] = 8;
    mailbox_message[4] = 8;
    mailbox_message[5] = 130;
    mailbox_message[6] = (uint32_t)on;
    mailbox_message[7] = 0;
    mailbox_write(MB_CHANNEL_TAGS, mailbox_ARM_to_VC(&mailbox_message[0]));
    mailbox_read(MB_CHANNEL_TAGS);
}

很高兴知道我离得不远,而且很高兴知道我现在有了我需要的确切语法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47503285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档