BCM2835芯片数据手册(中文翻译)

BCM2835芯⽚数据⼿册(中⽂翻译)1 前⾔
1.1 概述
BCM2835 具有以下可以被 ARM 安全使⽤的外设压力容器钢板
定时器
中断控制器
GPIO
USB
PCM/I2S
DMA
I2C 主机
I2C/SPI 从机
SPI0,SPI1,SPI2
PWM
UART0,UART1
多分力传感器本数据⼿册旨在对这些外设的细节进⾏描述,以⽅便开发者对该芯⽚移植操作系统。
有⼀些被 GPU 控制的外设将不会出现在本数据⼿册。不推荐从 ARM 访问这些外设。
1.2 地址映射
1.2.1 图表概述
除了 ARM 的内存管理单元( MMU )之外,BCM2835 还增加了⼀个粗颗粒的 MMU,⽤于将 ARM 的物理地址映射到系统总线地址。下⾯这幅图⽚展⽰了与之相关的地址空间。
在 ARM Linux 中的地址如下:
⾸先是 ARM 内核规定的虚拟地址
之后是 ARM MMU 映射的物理地址
之后是 ARM mapping MMU 映射的总线地址
最后为适当的外设和 RAM 地址
1.2.2 ARM 虚拟地址(标准 Linux 内核)
⼀般情况下,BCM2835 标准的 Linux 内核在存储单元的头部对整个可使⽤的 RAM 进⾏了连续的地址映射。该内核被配置为在内核和⽤户使⽤的存储空间中分割了 1GB/3GB 的空间。
在 ARM 和 GPU 之间分割的区域⽤于存放⼀个⽀持的 start*.elf ⽂件,该⽂件被⽤作 SD 卡 FAT32 boot 区域的 start.elf。分配给 GPU 的最⼩存储量为 32MB,但是这将影响其多媒体性能;例如,32MB 的空间⼩于让 GPU 进⾏ 1080p30 解码所需的缓存空间。
在内核模式下,虚拟地址为 0xC0000000 到 0xEFFFFFFF。
在⽤户模式下,即在运⾏ ARM Linux 时,虚拟内存为0x00000000 到 0xBFFFFFFF。
外设(物理地址为0x20000000)被映射到从地址 0xF20000000 处开始的内核虚拟地址空间。因此,在总线地址 0x7Ennnnnn 处的外设在 ARM 内核的虚拟地址为 0xF2nnnnnn。
1.2.3 ARM 物理地址防漏杯盖
RAM 的物理地址从 0x00000000 处开始。
ARM 定义的 RAM 地址从 0x00000000 开始
家用食品搅拌机只有在系统被配置为⽀持内存映射显⽰时,RAM 中的 VideoCore 部分才会被映射(这是常见情况)
VideoCore MMU 通过 VideoCore (和 VideoCore 外设)将 ARM 物理地址空间映射到总线地址空间。RAM 的总线地址被设置为映射到 VideoCore 内 uncache[^1] 总线地址 0xC0000000 处开始。
外设的物理地址是从 0x20000000 到0x20FFFFFF。外设的总线地址被映射到外设地址总线 0x7E000000 处开始。因此访问地址
0x7Ennnnnn 实际上是在访问物理地址 0x20nnnnnn。
1.2.4 总线地址
在本⽂中将外设地址称为总线地址。软件直接访问外设时,需要⽤如上所⽰的⽅式将地址转换位物理地址或虚拟地址。软件使⽤ DMA 访问外设时必须使⽤总线地址。
软件直接访问 RAM 时,必须使⽤物理地址(从0x00000000开始)。软件使⽤ DMA 访问 RAM 时,必须使⽤总线地址(从
0xC0000000开始)。
1.3 外设访问内存的正确顺序
BCM2835 系统使⽤ AMBA AXI 兼容的接⼝结构。为了保证较低的系统复杂性和较⾼的数据吞吐量,BCM2835 的 AXI 系统并没有始终按照次序地返回数据[^2]。GPU 具有特殊的逻辑可以不按次序的拷贝数据,但是 ARM 内核并不⽀持这个逻辑。因此在使⽤ ARM 访问外设时必须予以警惕。
在访问同⼀个外设时,数据总是按照次序地返回。但当访问是从⼀个外设到另⼀个外设时,数据就可能会错乱。为了确保数据具有正确的顺序,最简单的⽅法是在代码的临界区域设置内存隔离指令(memory barrier instructions)。如下两点:
在⾸次写外设前设置⼀个内存写屏障
在最后⼀次读外设之后设置⼀个内存读屏障
并不是每⼀次读或写操作之后都需要设置⼀个内存隔离指令,仅在代码对⼀个外设读或写操作是跟在对另⼀不同外设执⾏读或写操作之后时才需要,这通常是在进⼊或者退出外设服务函数时。
在代码的任何位置都有可能产⽣中断,因此你需要有如下防护措施。如果在读⼀个外设时发⽣中断,则需要先设置⼀个内存读屏障,如果在写⼀个外设时发⽣中断,则需要在之后设置⼀个内存写屏障。
[1] BCM2835 上具有⼀个 128KB 的 L2 cache,主要⽤于 GPU。访问内存时是经过还是绕过 L2 cache 由总线地址的⾼两位决定。
[2] ⼀般来说,在执⾏两次读操作时,处理器假定数据是按序返回的。所以先从 X 位置处读数据再从 Y 位置处读取数据时,应先返回 X 位置的数据。返回数据的顺序发⽣错乱将导致错误的结果。例如:
a_status = *pointer_to_peripheral_a;
b_status = *pointer_to_peripheral_b;
没有采取预防措施时,a_status 和 b_status 的数值可能会发⽣交换。
挡板砖
理论上这可能会导致错误,但实际上这种情况很难发⽣,因为 AXI 系统可以确保数据始终被按序地送到⽬的地。因此:
*pointer_to_peripheral_a = value_a;
*pointer_to_peripheral_b = value_b;
⼀直是正确的。唯⼀可能出现错误的时候是不同的外设被连接到了相同的外部设备。
内存屏障,也称内存栅栏,内存栅障,屏障指令等,是⼀类同步屏障指令,是CPU或编译器在对内存随机访问的操作中的⼀个同步点,使得此点之前的所有读写操作都执⾏后才可以开始执⾏此点之后的操作。
摩托车雨棚⼤多数现代计算机为了提⾼性能⽽采取乱序执⾏,这使得内存屏障成为必须。
语义上,内存屏障之前的所有写操作都要写⼊内存;内存屏障之后的读操作都可以获得同步屏障之前的写操作的结果。因此,对于敏感的程序块,写操作之后、读操作之前可以插⼊内存屏障。
VideoCore 是⼀个由Alphamosaic Ltd开发并且现在被Broadcom拥有的低功耗移动多媒体指令集架构。⼆维的DSP架构使其在软件中可以灵活且⾼效地编解码多媒体数据的同时保持低功耗。该IP核⽬前仅在Broadcom的SoC中被使⽤。

本文发布于:2024-09-22 15:26:56,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/287316.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:外设   内存   数据   地址   访问   内核   操作   总线
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议