关注,
如果全裸机跑咋样?
官方SDK支持全裸跑不?
由于之前没接触过嵌入式linux,本文恐有不少错误,还请各位多多见谅。
前言:该板使用(相当新的)STM32MP157F,有俩 Cortex-A7 内核,运行频率为 800MHz。 该SoC需要片外DDR3L RAM,增加了布线的难度。 不过,因为芯片可以选择 LFBGA448 (18x18mm) 封装,间距为 0.8mm,所以布线好像也没那么难。 此外,DDR 允许在每个bank内以及整个bank(对于 16 位)交换bit,所以布线容易些,但是地址位仍然必须按顺序排列。
至于为何要用很小众的STM32MP157嘛,因为ST给免费的样品,不用实在可惜。虽然2019年才推出Cortex-A7,实属落后,但数据手册等支持都相当不错。DIY这个项目也是为了体验一下MPU开发的全过程。。。
硬件部分用JLC的四层板就能布得下。由于布线时匆忙,DDR既没有做阻抗,也没有仔细拉等长,后文会提到一些具体细节。
硬件概述
STM32MP157FAA - SoC
4 GBit(512 MB)DDR3L RAM
2 通道 MIPI-DSI 屏幕连接器
1 个 USB-C OTG、1 个 USB-A 主机
1x 8 位并行摄像头接口
1 Gbit (128MByte) NAND-QSPI FLASH
、
PCB渲染图。
反面用JLC贴片,正面使用热风枪手焊。此时遇到了第一个困难:由于DDR内存迟迟未到,而我又没有植球工具,之前拆焊的内存完全没法用,只好继续等待。
硬件没有什么大坑,这个芯片要三组电压:VDD = 3.3V,Vcore = 1.2V VDDR = 1.35V。还有一个需要特别上电顺序的Vusb,也是3.3V,必须要单独一组LDO。
焊好的芯片没什么问题,由此开始调试固件和Linux系统——没想到这才是坑的所在。
ST官方支持Yocto系统,但由于Yocto过于庞大,而且我的设备也与官方的设计相差甚远(晶振,PMIC等等)我决定用第三方的buildroot。A7的启动过程一共分四部,ARM用BL*来表示。
BL1 - 内部的ROM,通过跳线帽选择启动设备。
BL2 - TF-A - ARM的“可信平台”,跑在内部SRAM里,有自己的设备树(Device Tree),将验证硬件与固件是否相符,并且初步初始化DDR内存。
BL32 - OPTEE-OS - 可信操作系统,负责硬件加密部分,也有自己的设备树。由于ST的内部SRAM过小,OPTEE必须运行在分页模式下,并且利用外部DDR来进行操作。
BL33 - 我们的好朋友UBOOT,负责启动Linux。
由于遇到的坑过多,基本上是一点点磨过去的,下面便用“问答”形式来简单讲解问题的原因以及解决方法。
* buildroot完全不编译?
** 首先检查配置文件***defconfig,按需求改动附带的配置文件。这个第三方的buildroot有两种配置-demo和默认,demo包含很多附加的包,默认只保留启动所需的核心选项。
* buildroot 编译TF-A,OPTEE, UBOOT等任意一项时DEVICE TREE报错
** ST的CubeIDE给出的Device Tree文件不是完整的,需要从buildroot所带的文件里移植一些用户配置。比较重要的是UART的配置,不然debug给出的信息都会去到奇怪的地方。
* buildroot编译成功了,但是烧录到SD卡之后uart只输出PANIC和一个地址。
** 先看看config里有没有调用修改过的device tree,这基本上是硬件调用问题,比如板子上的晶振是12MHz的,默认的Device Tree却是24MHz。
* PANIC后显示DDR问题
** 检查内存焊接。
* TF-A 能够启动,但是出现HASH问题,然后死机
** 检查四个device tree配置是否一致 (这四个内容并不是完全一样,但是每个文件里有的节点都需要一致)。
* OPTEE启动后各种原因死机,进不去UBOOT
**检查OPTEE的device tree设置,以及config文件中的选项。OPTEE必须配置在分页模式下,最好打开调试选项。有些时候也可能是SD卡坏了。
* UBOOT启动了,进不去Linux系统。
** 首先恭喜!这一步就应该有UBOOT的shell,可以进行简单测试。一般这个问题也是SD卡坏了,也可能是重新编译时老文件没有清理干净,需要运行make clean。
附录
进了Linux后跑了memtest,和一个内存跑分软件,memtest没有报错(533MHz内存时钟-等效1066M, cpu 600 MHz)membench如下:
C copy backwards : 217.5 MB/s
C copy backwards (32 byte blocks) : 591.7 MB/s
C copy backwards (64 byte blocks) : 591.7 MB/s
C copy : 803.2 MB/s
C copy prefetched (32 bytes step) : 755.9 MB/s
C copy prefetched (64 bytes step) : 762.4 MB/s
C 2-pass copy : 529.6 MB/s
C 2-pass copy prefetched (32 bytes step) : 477.8 MB/s
C 2-pass copy prefetched (64 bytes step) : 475.1 MB/s
C fill : 1512.3 MB/s (0.4%)
C fill (shuffle within 16 byte blocks) : 1511.6 MB/s (0.3%)
C fill (shuffle within 32 byte blocks) : 324.1 MB/s (0.1%)
C fill (shuffle within 64 byte blocks) : 352.0 MB/s
---
standard memcpy : 795.0 MB/s
standard memset : 1458.3 MB/s
---
NEON read : 1201.7 MB/s
NEON read prefetched (32 bytes step) : 1242.0 MB/s
NEON read prefetched (64 bytes step) : 1278.4 MB/s
NEON read 2 data streams : 344.5 MB/s
NEON read 2 data streams prefetched (32 bytes step) : 639.8 MB/s
NEON read 2 data streams prefetched (64 bytes step) : 719.1 MB/s
NEON copy : 805.0 MB/s
NEON copy prefetched (32 bytes step) : 832.6 MB/s
NEON copy prefetched (64 bytes step) : 835.8 MB/s
NEON unrolled copy : 801.4 MB/s
NEON unrolled copy prefetched (32 bytes step) : 778.6 MB/s
NEON unrolled copy prefetched (64 bytes step) : 799.5 MB/s
NEON copy backwards : 805.2 MB/s
NEON copy backwards prefetched (32 bytes step) : 831.6 MB/s
NEON copy backwards prefetched (64 bytes step) : 834.5 MB/s
NEON 2-pass copy : 607.0 MB/s
NEON 2-pass copy prefetched (32 bytes step) : 626.7 MB/s
NEON 2-pass copy prefetched (64 bytes step) : 634.3 MB/s
NEON unrolled 2-pass copy : 427.2 MB/s
NEON unrolled 2-pass copy prefetched (32 bytes step) : 441.3 MB/s
NEON unrolled 2-pass copy prefetched (64 bytes step) : 479.6 MB/s
NEON fill : 1543.9 MB/s
NEON fill backwards : 1543.9 MB/s
VFP copy : 804.0 MB/s
VFP 2-pass copy : 486.4 MB/s
ARM fill (STRD) : 1457.9 MB/s
ARM fill (STM with 8 registers) : 1543.8 MB/s
ARM fill (STM with 4 registers) : 1543.0 MB/s
ARM copy prefetched (incr pld) : 805.9 MB/s
ARM copy prefetched (wrap pld) : 709.1 MB/s
ARM 2-pass copy prefetched (incr pld) : 545.9 MB/s
ARM 2-pass copy prefetched (wrap pld) : 530.7 MB/s
==========================================================================
== Memory latency test ==
== ==
== Average time is measured for random memory accesses in the buffers ==
== of different sizes. The larger is the buffer, the more significant ==
== are relative contributions of TLB, L1/L2 cache misses and SDRAM ==
== accesses. For extremely large buffer sizes we are expecting to see ==
== page table walk with several requests to SDRAM for almost every ==
== memory access (though 64MiB is not nearly large enough to experience ==
== this effect to its fullest). ==
== ==
== Note 1: All the numbers are representing extra time, which needs to ==
== be added to L1 cache latency. The cycle timings for L1 cache ==
== latency can be usually found in the processor documentation. ==
== Note 2: Dual random read means that we are simultaneously performing ==
== two independent memory accesses at a time. In the case if ==
== the memory subsystem can't handle multiple outstanding ==
== requests, dual random read has the same timings as two ==
== single reads performed one after another. ==
==========================================================================
block size : single random read / dual random read
1024 : 0.0 ns / 0.0 ns
2048 : 0.0 ns / 0.0 ns
4096 : 0.0 ns / 0.0 ns
8192 : 0.0 ns / 0.0 ns
16384 : 0.0 ns / 0.0 ns
32768 : 0.0 ns / 0.1 ns
65536 : 10.9 ns / 18.9 ns
131072 : 16.8 ns / 26.5 ns
262144 : 21.8 ns / 32.4 ns
524288 : 99.9 ns / 156.1 ns
1048576 : 144.1 ns / 201.9 ns
2097152 : 175.6 ns / 229.8 ns
4194304 : 192.1 ns / 242.8 ns
8388608 : 203.5 ns / 253.5 ns
16777216 : 216.4 ns / 271.7 ns
33554432 : 233.5 ns / 301.5 ns
67108864 : 260.2 ns / 354.7 ns
忘记上传源文件了,本设计硬件全部开源,但需改进的地方很多,仅供参考。。。
顺便跑了一下Coremark,得分2033 (CPU=800MHz),相当的不行。。。
做了第二个版本,修改了DDR布线,增加了以太网(PCB有一根线没连,有bug)
引用GiroPetrenko发表于4楼的内容做了第二个版本,修改了DDR布线,增加了以太网(PCB有一根线没连,有bug)
勘误:其实Eth的phy并不是没有连接(之前以为没有连接的线是RxC,结果发现RMII不需要RxC,MII才需要),而是在STM32段连错了,连到了RGMII(千兆)的CLK上,所以还是没法用。
还有一个不知道怎么修的BUG,解码视频和播放图片有颜色出错。但是modetest的彩色条纹正常。也检查过布线和EMC,并没有发现什么大问题。显示工具用的是MPV,也试过ffplay,都一样。
如下图:
原图应该这样……
200字以内,仅用于支线交流,主线讨论请采用回复功能。