Documentation in pdf format: Download

PD24.1.0 NXP i.MX 8M Plus BSP手册

文档标题

PD24.1.0 NXP i.MX 8M Plus BSP手册

文档类型

BSP 手册

型号

PD24.1.0 NXP

Yocto 手册

Scarthgap

发布日期

2024/11/08

母文档

PD24.1.0 NXP i.MX 8M Plus BSP手册

下表显示了与本手册兼容的 BSP:

Compatible BSPs

BSP 发布类型

BSP 发布日期

BSP 状态

BSP-Yocto-NXP-i.MX8MP-PD24.1.0

大版本

2024/11/06

已发布

本手册指导您完成BSP包的安装、编译和烧写,并描述如何使用 phyCORE-i.MX8M Plus Kit 的硬件接口。本手册还包括如何从源码编译内核、u-boot镜像。本手册包含需要在PC(linux操作系统)上执行的指令。

备注

本文档包含指令示例,描述如何在串口终端上与核心板进行交互。指令示例以“host:~$”、“target:~$”或“u-boot=>”开头,开头的这些关键字描述了指令执行的软件环境。如果需要复制这些指令,请仅复制这些关键字之后的内容。

1. PHYTEC 文档

PHYTEC 将为旗下所有产品提供各种硬件和软件文档。包括以下任一以及全部内容:

  • 快速上手指南:简单指导我们如何配置和启动 phyCORE 核心板,以及对构建 BSP、设备树和外设访问进行简要说明。

  • 硬件手册:核心板和配套底板的详细硬件描述。

  • Yocto 指南:phyCORE 使用的 Yocto 版本的综合指南。本指南包含: Yocto 概述;PHYTEC BSP 介绍、编译和定制化修改;如何使用 Poky 和 Bitbake 等编译框架。

  • BSP 手册:phyCORE 的 BSP 版本专用手册。可在此处找到如何编译BSP、启动、更新软件、设备树和外设等信息。

  • 开发环境指南:本指南介绍了如何使用 PHYTEC 虚拟机来搭建多样的开发环境。VM 中包含了 Eclipse 和 Qt Creator 的详细上手指导,还说明了如何将所编译出的demo程序放到phyCORE 核心板上运行。本指南同时也介绍了如何在本地Linux ubuntu上搭建完整的开发环境。

  • 引脚复用表:phyCORE 核心板附带一个引脚复用表(Excel 格式)。此表将显示从处理器到底板的信号连接以及默认的设备树复用选项。这为开发人员进行引脚复用和设计提供了必要的信息。

除了这些标准手册和指南之外,PHYTEC 还将提供产品变更通知、应用说明和技术说明。这些文档将根据具体案例进行针对性提供。大部分文档都可以在我们产品的 https://www.phytec.de/produkte/system-on-modules/phycore-imx-8m-plus/#downloads 中找到。

1.1. 支持的硬件

在我们的网页上,您可以查看适用于BSP版本 BSP-Yocto-NXP-i.MX8MP-PD24.1.0 的所有Machine及其对应的Article Numbers(产品型号): 网页.

如果您在“Supported Machines”一栏选择了特定的 Machine Name ,您可以查看该machine下可用的 Article Numbers 以及硬件信息的简短描述。如果您只有硬件的 Article Numbers ,您可以将 Machine Name 下拉菜单留空,仅选择您的 Article Numbers 。现在,它应该会显示您特定硬件所需的 Machine Name

1.1.1. phyBOARD-Pollux 器件

../../../_images/phyBOARD-Pollux-front-components.jpg

phyBOARD-Pollux 器件图(顶部)

../../../_images/phyBOARD-Pollux-back-components.jpg

phyBOARD-Pollux 器件图(底部)

2. 开始使用

phyCORE-i.MX8M Plus Kit 包含预先烧写好的SD卡。它包含 phytec-qt6demo-image 镜像,可以直接用作启动盘。默认情况下,核心板上的eMMC仅烧写了U-Boot。您可以从 PHYTEC下载服务器 获取所有镜像资源。本章将解释如何将BSP镜像烧写到SD卡以及如何启动开发板。

有几种方法可以将镜像写入SD卡或eMMC。最为人熟知的方式是使用Linux命令行工具 dd 进行简单的顺序写入。另一种方法是使用PHYTEC的自研程序 partup ,它可以让格式化复杂系统的过程变得简单。您可以从其发布页面获取 预编译的Linux partup 二进制文件 。请阅读 partup的readme文件 来获取安装指导。

2.1. 下载镜像

phytec-qt6demo-image 镜像包含完整系统所需的所有必要文件,您需确保镜像中各个分区以及裸数据都会被正确写入启动盘。可以从 PHYTEC 下载服务器 下载 partup 镜像文件或者是可以使用 dd 进行烧写的 WIC 镜像。

从下载服务器获取 partup 镜像文件或WIC镜像:

host:~$ wget https://download.phytec.de/Software/Linux/BSP-Yocto-i.MX8MP/BSP-Yocto-NXP-i.MX8MP-PD24.1.0/images/ampliphy-vendor-xwayland/phyboard-pollux-imx8mp-3/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.partup
host:~$ wget https://download.phytec.de/Software/Linux/BSP-Yocto-i.MX8MP/BSP-Yocto-NXP-i.MX8MP-PD24.1.0/images/ampliphy-vendor-xwayland/phyboard-pollux-imx8mp-3/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz

备注

针对eMMC,我们建议使用partup去烧写比较大的或者是有复杂分区配置的镜像,因为它在写入速度上比 dd 更快,并且可以对闪存设备进行更灵活的配置。

2.2. 将镜像写入SD卡

警告

要创建SD卡启动盘,必须要拥有Linux PC上的root权限。在选择烧写设备时请务必小心!所选设备上的所有文件将在命令执行后立即被擦除,而且擦除前不会有任何进一步的确认!

选择错误的设备可能会导致 数据丢失 ,例如,可能会擦除您当前所在PC上的系统!

2.2.1. 寻找正确的设备

要创建SD卡启动盘,首先要找到PC上您SD卡对应的正确设备名称。在开始将镜像复制到SD卡之前,请卸载任何已挂载的分区。

  1. 为了获取正确的设备名称,请移除您的SD卡并执行:

    host:~$ lsblk
    
  2. 现在插入你的SD卡,然后再次执行命令:

    host:~$ lsblk
    
  3. 比较两个输出,以获取第二个输出中的新设备名称。这些是SD卡的设备名称(如果SD卡已格式化,则包括设备名称和对应的分区)。

  4. 为了验证找到的设备名称的最终正确性,请执行命令 sudo dmesg。在其输出的最后几行中,您应该也能找到设备名称,例如 /dev/sde/dev/mmcblk0 (具体取决于您的系统)。

或者,您可以使用图形化的程序,例如 GNOME DisksKDE Partition Manager 来找到正确的设备。

现在您已经得到了正确的设备名称,例如 /dev/sde,如果SD卡曾格式化过,需要确认已取消其分区的挂载,您可以在输出中看到带有附加了数字的设备名称(例如 /dev/sde1),它们是SD卡的分区。一些Linux发行版系统在设备插入时会自动挂载分区。在写入之前,必须卸载这些分区,以避免数据损坏。

卸载所有这些分区,例如:

host:~$ sudo umount /dev/sde1
host:~$ sudo umount /dev/sde2

现在,SD卡已经准备好可以使用 partupddbmap-tools 来写入镜像。

2.2.2. 使用bmap-tools

烧写SD卡的其中一种方法是使用 bmap-tools 。Yocto会自动为WIC镜像创建一个block map文件( <IMAGENAME>-<MACHINE>.wic.bmap ),该文件描述了镜像内容并包含数据完整性的校验。 bmaptool 已被多种Linux发行版支持。对于基于Debian的系统,可以通过以下命令安装:

host:~$ sudo apt install bmap-tools

通过以下命令将WIC镜像烧写到SD卡:

host:~$ bmaptool copy phytec-qt6demo-image-phyboard-pollux-imx8mp-3?(.rootfs).wic?(.xz) /dev/<your_device>

将 <your_device> 替换为您之前找到的SD卡设备名称,并确保将文件 <IMAGENAME>-<MACHINE>.wic.bmap 与WIC镜像文件放在一起,以便bmaptool知道哪些块需要写入,哪些块需要跳过。

警告

bmaptool 仅擦写SD卡上镜像数据所在的区域。这意味着在写入新的镜像后,之前写入的旧U-Boot环境变量可能仍然可用。

2.2.3. 使用partup

使用partup烧写SD卡只需一个命令:

host:~$ sudo partup install phytec-qt6demo-image-phyboard-pollux-imx8mp-3?(.rootfs).partup /dev/<your_device>

确保将 <your_device> 替换为您之前找到的设备名称。

关于partup的进一步使用说明,请参阅其 官方文档

警告

使用resize2fs版本1.46.6及更早版本的PC系统(例如Ubuntu 22.04)无法烧写在Mickledore以及更新的yocto版本上创建的partup软件包。这个是因为resize2fs新增了默认选项而导致的兼容性问题。有关详细信息,请参阅 release notes

备注

partup 具有清除eMMC user区域中特定区域的功能,我们提供的partup程序中用该功能擦除U-Boot环境变量。这是 bmaptool 工具所无法完成的一点,如前一部分所提到的。

partup相较于其他烧写工具的一个主要优势是,它可以配置MMC的特定部分,比如他可以直接写入eMMCboot分区,无需调用其他命令。

2.2.4. 使用 dd

在卸载所有SD卡的挂载分区后,您可以烧写SD卡。

一些PHYTEC BSP会生成未压缩的镜像(文件名扩展名为*.wic),而另一些则生成压缩的镜像(文件名扩展名为*.wic.xz)。

要写入未压缩的镜像(*.wic),请使用以下命令:

host:~$ sudo dd if=phytec-qt6demo-image-phyboard-pollux-imx8mp-3?(.rootfs).wic of=/dev/<your_device> bs=1M conv=fsync status=progress

或者要写入压缩后的镜像(*.wic.xz),请使用以下命令:

host:~$ xzcat phytec-qt6demo-image-phyboard-pollux-imx8mp-3?(.rootfs).wic.xz | sudo dd of=/dev/<your_device> bs=1M conv=fsync status=progress

再次确保将 <your_device> 替换为之前找到的设备名称。

参数 conv=fsync 强制在 dd 返回之前对设备进行sync操作。这确保所有数据块都已写入SD卡,而没有任何数据缓存在内存中。参数 status=progress 将打印出进度信息。

2.3. 首次启动

../../../_images/SD_Card_Boot1.png
  • 插入SD卡

  • 使用 micro USB 线将开发板的 (X1) 调试USB口和主机连接起来

  • 给开发板通电

3. 编译BSP

This section will guide you through the general build process of the i.MX 8M Plus BSP using Yocto and the phyLinux script. For more information about our meta-layer or Yocto in general visit: Yocto Reference Manual (scarthgap).

3.1. 基本设置

If you have never created a Phytec BSP with Yocto on your computer, you should take a closer look at the chapter BSP Workspace Installation in the Yocto Reference Manual (scarthgap).

3.2. 下载BSP

获取BSP有两种方式。您可以从我们的下载页面下载完整的BSP镜像: BSP-Yocto-IMX8MP ;您也可以使用Yocto下载BSP工程并编译。如果您想要对BSP进行修改,建议使用第二种方式。

phyLinux脚本使用python语言编写,是一个用于管理PHYTEC Yocto BSP工程的基础工具,帮助用户更快上手BSP。

  • 创建一个新的项目文件夹,获取phyLinux脚本,并赋予脚本具备可执行权限:

    host:~$ mkdir ~/yocto
    host:~$ cd yocto/
    host:~/yocto$ wget https://download.phytec.de/Software/Linux/Yocto/Tools/phyLinux
    host:~/yocto$ chmod +x phyLinux
    

    警告

    我们需要一个空的项目文件夹,phyLinux首先会清理当前所在的工作目录。从一个不为空的目录下调用phyLinux将会产生告警。

  • 运行phyLinux:

    host:~/yocto$ ./phyLinux init
    

    备注

    在首次初始化时,phyLinux脚本会要求您在 /usr/local/bin 目录中安装Repo工具。

  • 在执行init命令时,您需要选择您的处理器平台(SoC)、PHYTEC的BSP版本号以及您正在使用的硬件。

    备注

    如果您无法根据菜单中提供的信息识别您的开发板,请查看产品的发票。并查看 our BSP

  • 也可以通过命令行参数直接传递这些信息:

    host:~/yocto$ DISTRO=ampliphy-vendor-xwayland MACHINE=phyboard-pollux-imx8mp-3 ./phyLinux init -p imx8mp -r BSP-Yocto-NXP-i.MX8MP-PD24.1.0
    

在执行init命令后,phyLinux将打印一些重要的说明。例如,它将打印您的git用户信息、选择的SOC和BSP版本,以及引导构建过程进行下一步处理的信息。

3.2.1. 开始构建

  • 设置Shell环境变量:

    host:~/yocto$ source sources/poky/oe-init-build-env
    

    备注

    在每次打开新的用于编译的shell时,都需要先执行这一步骤。

  • 当前的工作目录会变更为 build/。

  • 打开主配置文件,同意并接受GPU和VPU二进制文件的许可证协议。通过取消注释相应的行来完成此操作,如下所示。

    host:~/yocto/build$ vim conf/local.conf
    # Uncomment to accept NXP EULA
    # EULA can be found under ../sources/meta-freescale/EULA
    ACCEPT_FSL_EULA = "1"
    
  • 编译您的镜像:

    host:~/yocto/build$ bitbake phytec-qt6demo-image
    

    备注

    对于第一次编译,我们建议从我们的较小的非图形化镜像phytec-headless-image开始,以查看一切是否正常工作。

    host:~/yocto/build$ bitbake phytec-headless-image
    

    第一次构建过程在现代的Intel Core i7处理器上大约需要40分钟。后续的构建将使用本次编译产生的缓存,大约需要3分钟。

3.2.2. BSP镜像

所有由Bitbake生成的镜像都放在 ~/yocto/build/deploy*/images/<machine> 。例如以下列表是 phyboard-pollux-imx8mp-3 machine生成的所有文件:

  • u-boot.bin: 编译后的U-boot bootloader二进制文件。不是最终镜像中的bootloader!

  • oftree: 默认内核设备树

  • u-boot-spl.bin: 二级程序加载器 (SPL)

  • bl31-imx8mp.bin: ARM可信固件二进制文件

  • lpddr4_pmu_train_2d_dmem_202006.bin, lpddr4_pmu_train_2d_imem_202006.bin: DDR PHY固件镜像

  • imx-boot:由imx-mkimage编译的bootloader镜像,包括SPL、U-Boot、ARM可信固件和DDR固件。这是最终的可引导bootloader镜像。

  • fitImage: Linux内核FIT镜像

  • fitImage-its*.its

  • Image: Linux内核镜像

  • Image.config: 内核config文件

  • imx8mp-phyboard-pollux-rdk*.dtb: 内核设备树文件

  • imx8mp-phy*.dtbo: 内核设备树overlay文件

  • phytec-qt6demo-image*.tar.gz: 根文件系统

  • phytec-qt6demo-image*.rootfs.wic.xz: 压缩的SD卡镜像

4. 安装操作系统

4.1. 启动模式开关 (S3)

小技巧

硬件修订版底板:1552.2

该 phyBOARD-Pollux 具有一个(启动源配置)开关,配有四个可单独切换的位,用于选择phyCORE-i.MX 8M Plus 默认的启动源。

../../../_images/eMMC1.png

eMMC

../../../_images/Internal_Fuses1.png

内部fuse

../../../_images/SPI_NOR.png

SPI NOR

../../../_images/USB_Serial_Download1.png

USB

../../../_images/SD_Card_Boot1.png

SD卡

../../../_images/Test_Mode.png

测试模式

4.2. 烧写eMMC

为了保持文档的一致性和简洁性,假设已经配置好了TFTP服务器;所有生成的镜像(如上所列)都被复制到默认的/srv/tftp目录。如果您没有进行设置,您需要修改路径到包含镜像的目录。有关如何设置TFTP服务器和目录的说明,请参见 Setup Network Host

要从 eMMC 启动,请确保 BSP 镜像已正确烧写到 eMMC,并且 bootmode switch (S3) 设置为 eMMC

警告

当eMMC和SD卡上烧录了相同(完全一致)的镜像时,他们boot分区的UUID也是相同的。所以如果从emmc启动时,烧录一致镜像的SD卡也同时存在,这会导致不确定的后果,因为Linux会根据UUID来挂载启动分区。

target:~$ blkid

可以运行上述命令来检查系统启动在这种条件下是否会到影响。如果 mmcblk2p1mmcblk1p1 具有相同的UUID,则会影响系统正确启动。

4.2.1. 从网络烧写 eMMC

i.MX 8M Plus 开发板具有以太网连接器,可以通过网络进行更新。确保正确设置主机,主机的IP需要设置为192.168.3.10,子网掩码为255.255.255.0,并且需要在主机开启TFTP服务。抽象来看,eMMC设备和SD卡十分类似。因此,可以直接将Yocto生成的 WIC镜像<name>.wic )直接烧写到eMMC。该镜像包含bootloader、内核、设备树、设备树overlay和根文件系统。

4.2.1.1. 在Linux主机上通过网络烧写 eMMC

可以在您的Linux主机上将镜像烧写到eMMC。和之前一样,您需要在主机上准备一个完整的镜像。

小技巧

需要保证设备和存储镜像的主机之间的网络正常! Setup Network Host

查看主机上可用的镜像文件:

host:~$ ls /srv/tftp
phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz
phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.bmap

通过网络ssh协议使用 bmaptool 命令将镜像发送到开发板的eMMC:

host:~$ scp /srv/tftp/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.* root@192.168.3.11:/tmp && ssh root@192.168.3.11 "bmaptool copy /tmp/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz /dev/mmcblk2"

4.2.1.2. 在开发板的Linux系统中通过网络烧写eMMC

您可以在开发板系统中更新eMMC。

小技巧

需要保证设备和存储镜像的主机之间的网络正常! Setup Network Host

使用以下命令,通过网络将压缩或未压缩的镜像和配套的 *.bmap 文件传送到核心板并写入 eMMC:

target:~$ scp <USER>@192.168.3.10:/srv/tftp/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.* /tmp && bmaptool copy /tmp/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz /dev/mmcblk2

4.2.1.3. 在开发板的U-Boot中通过网络烧写eMMC

这些步骤将展示如何通过网络更新eMMC。

小技巧

此步骤仅在镜像文件小于1GB的情况下会被执行成功,因为在启用OPTEE后,Bootloader中可用的RAM大小有限,不足以加载超过1GB的镜像

小技巧

需要保证设备和存储镜像的主机之间的网络正常! Setup Network Host

解压缩您的镜像

host:~$ unxz /srv/tftp/phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz

通过网络将您的镜像加载到内存中:

  • 使用DHCP

    u-boot=> dhcp phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic
    BOOTP broadcast 1
    DHCP client bound to address 192.168.3.1 (1 ms)
    Using ethernet@30be0000 device
    TFTP from server 192.168.3.10; our IP address is 192.168.3.1
    Filename 'phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic'.
    Load address: 0x40480000
    Loading: ######################################
             ######################################
             ######################################
             ...
             ...
             ...
             ######################################
             #############
             11.2 MiB/s
    done
    Bytes transferred = 911842304 (36599c00 hex)
    
  • 使用静态IP地址(必须先设置serverip和ipaddr)。

    u-boot=> tftp ${loadaddr} phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic
    Using ethernet@30be0000 device
    TFTP from server 192.168.3.10; our IP address is 192.168.3.11
    Filename 'phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic'.
    Load address: 0x40480000
    Loading: ######################################
             ######################################
             ######################################
             ...
             ...
             ...
             ######################################
             #############
             11.2 MiB/s
    done
    Bytes transferred = 911842304 (36599c00 hex)
    

将镜像写入eMMC:

u-boot=> mmc dev 2
switch to partitions #0, OK
mmc2(part 0) is current device
u-boot=> setexpr nblk ${filesize} / 0x200
u-boot=> mmc write ${loadaddr} 0x0 ${nblk}

MMC write: dev # 2, block # 0, count 1780942 ... 1780942 blocks written: OK

4.2.2. 在运行的U-Boot中通过网络烧写eMMC U-Boot镜像

可以在U-Boot中更新U-Boot镜像imx-boot,eMMC上的U-Boot需要位于eMMC的user区域。

小技巧

需要保证设备和存储镜像的主机之间的网络正常! Setup Network Host

通过tftp将镜像加载到RAM中,然后写入eMMC:

u-boot=> tftp ${loadaddr} imx-boot
u-boot=> setexpr nblk ${filesize} / 0x200
u-boot=> mmc dev 2
u-boot=> mmc write ${loadaddr} 0x40 ${nblk}

提示

十六进制值表示偏移量,单位为512字节块的倍数。请参阅 偏移表 以获取相应SoC的正确值。

4.2.3. 从USB大容量存储设备烧写eMMC

4.2.3.1. 在运行的Linux系统中从USB烧写eMMC

下面这些步骤展示如何在Linux系统上使用USB大容量存储设备烧写eMMC。您需要一个保存了完整镜像的U盘和一个可从SD卡启动的核心板。(例如: phytec-qt6demo-image-phyboard-pollux-imx8mp-3.|yocto-imageext| )。将 bootmode switch (S3) 设置为SD卡。

  • 插入并挂载U盘:

    [   60.458908] usb-storage 1-1.1:1.0: USB Mass Storage device detected
    [   60.467286] scsi host0: usb-storage 1-1.1:1.0
    [   61.504607] scsi 0:0:0:0: Direct-Access                               8.07 PQ: 0 ANSI: 2
    [   61.515283] sd 0:0:0:0: [sda] 3782656 512-byte logical blocks: (1.94 GB/1.80 GiB)
    [   61.523285] sd 0:0:0:0: [sda] Write Protect is off
    [   61.528509] sd 0:0:0:0: [sda] No Caching mode page found
    [   61.533889] sd 0:0:0:0: [sda] Assuming drive cache: write through
    [   61.665969]  sda: sda1
    [   61.672284] sd 0:0:0:0: [sda] Attached SCSI removable disk
    target:~$ mount /dev/sda1 /mnt
    
  • 现在查看您在USB优盘上保存的镜像文件:

    target:~$ ls /mnt
    phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz
    phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.bmap
    
  • 将镜像写入 phyCORE-i.MX 8M Plus eMMC(无分区的 MMC 设备 2):

    target:~$ bmaptool copy /mnt/phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz /dev/mmcblk2
    
  • 在完成写入后,您的开发板可以从eMMC启动。

    小技巧

    在此之前,您需要将 bootmode switch (S3) 配置为 eMMC

4.2.3.2. 在开发板上通过U-Boot从USB烧写eMMC

小技巧

此步骤仅在镜像文件小于1GB的情况下会被执行成功,因为在启用OPTEE后,Bootloader中可用的RAM大小有限,不足以加载超过1GB的镜像

下面这些步骤展示如何通过USB设备更新eMMC。将 bootmode switch (S3) 配置为SD卡并插入SD卡。给开发板上电并进入U-Boot环境。将已存储了未压缩WIC镜像的优盘插入开发板USB接口。

将镜像从USB设备加载到RAM中:

u-boot=> usb start
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 1 Storage Device(s) found
u-boot=> fatload usb 0:1 0x58000000 phytec-headless-image-|yocto-machinename|.rootfs.wic
497444864 bytes read in 31577 ms (15 MiB/s)

将镜像写入eMMC:

u-boot=> mmc dev 2
switch to partitions #0, OK
mmc2(part 0) is current device
u-boot=> setexpr nblk ${filesize} / 0x200
u-boot=> mmc write 0x58000000 0x0 ${nblk}

MMC write: dev # 2, block # 0, count 1024000 ... 1024000 blocks written: OK
u-boot=> boot

4.2.4. 从SD卡烧写eMMC

即使没有可用的网络,您也可以更新eMMC。为此,您需要一个位于SD卡上的镜像文件( *.wic )。由于镜像文件相当大,您需要在SD卡创建第三个分区。要创建新分区或扩展您的SD卡,请参见 Resizing ext4 Root Filesystem

或者,使用partup包烧写SD卡,如 Getting Started 中所述。这样就可使用SD卡的全部容量。

4.2.4.1. 在开发板的linux环境中通过SD卡烧写eMMC

您也可以在Linux系统中烧写eMMC。您只需要一个partup包或保存在SD卡上的WIC镜像。

  • 检查在SD卡上保存的partup包或WIC镜像文件:

    target:~$ ls
    phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.partup
    phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz
    phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.bmap
    
  • 使用 partup 将镜像写入 phyCORE-i.MX 8M Plus 的 eMMC(MMC 设备 2 不带 分区字样):

    target:~$ partup install phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.partup /dev/mmcblk2
    

    使用partup烧写的优点是可以充分利用eMMC设备的全部容量,会相应自动调整分区大小。

    备注

    另外,也可以使用 bmaptool 工具:

    target:~$ bmaptool copy phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic.xz /dev/mmcblk2
    

    请注意,在使用 bmaptool 烧写时,根文件系统分区并不会使用eMMC的最大容量。

  • 在完成写入后,您的开发板可以从eMMC启动。

    警告

    在此之前,您需要将 bootmode switch (S3) 配置为 eMMC。

4.2.4.2. 在开发板的uboot环境中通过SD卡烧写eMMC

小技巧

此步骤仅在镜像文件大小小于1GB的情况下有效,因为在启用OPTEE后,Bootloader中可用的RAM大小有限。如果镜像文件过大,请阅读 在开发板上通过SD卡更新eMMC 一节

  • 将一个可用的镜像烧写到SD卡,并创建一个EXT4格式的第三分区。将WIC镜像(例如 phytec-qt6demo-image.rootfs.wic)复制到该分区。

  • bootmode switch (S3) 配置为 SD 卡并插入 SD 卡。

  • 打开电源并进入U-Boot。

  • 加载镜像:

    u-boot=> ext4load mmc 1:3 ${loadaddr} phytec-headless-image-phyboard-pollux-imx8mp-3.rootfs.wic
    reading
    911842304 bytes read in 39253 ms (22.2 MiB/s)
    
  • 将当前mmc设备切换到eMMC:

    u-boot=> mmc list
    FSL_SDHC: 1 (SD)
    FSL_SDHC: 2 (eMMC)
    u-boot=> mmc dev 2
    switch to partitions #0, OK
    mmc2(part 0) is current device
    
  • 将您的WIC镜像(例如 phytec-qt6demo-image.rootfs.wic)从SD卡烧写到eMMC。这将对emmc进行分区,并将imx-boot、Image、dtb、dtbo和根文件系统复制到eMMC。

    u-boot=> setexpr nblk ${filesize} / 0x200
    u-boot=> mmc write ${loadaddr} 0x0 ${nblk}
    
    MMC write: dev # 2, block # 0, count 1780942 ... 1780942 blocks written: OK
    
  • 关闭电源并将 bootmode switch (S3) 更改为 eMMC。

4.3. 烧写 SPI NOR Flash

phyCORE-i.MX8MP 模块可选配SPI NOR Flash。要从SPI Flash启动,请将 bootmode switch (S3) 设置为 SPI NOR 。SPI Flash通常比较小。phyBOARD-Pollux-i.MX8MP开发套件仅配备32MB的SPI NOR Flash。只能存储bootloader及其环境变量。默认情况下,内核、设备树和文件系统会从eMMC加载。

SPI NOR Flash分区表在U-Boot环境变量中定义。可以通过以下命令打印:

u-boot=> printenv mtdparts
mtdparts=30bb0000.spi:3840k(u-boot),128k(env),128k(env:redund),-(none)

4.3.1. 通过网络烧写SPI NOR Flash

SPI NOR可以包含bootloader及其环境变量。arm64的linux内核无法自行解压缩,内核镜像大小超出了phyCORE-i.MX 8M Plus 上的SPI NOR Flash的容量。

小技巧

需要保证设备和存储镜像的主机之间的网络正常! Setup Network Host

4.3.1.1. 在开发板linux环境中通过网络烧写SPI NOR Flash

  • 将镜像从主机复制到开发板:

    host:~$ scp imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi root@192.168.3.11:/root
    
  • 查找要擦除的U-boot分区的块数:

    target:~$ mtdinfo /dev/mtd0
    mtd0
    Name:                           u-boot
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          60 (3932160 bytes, 3.7 MiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:0
    Bad blocks are allowed:         false
    Device is writable:             true
    
  • 擦除U-Boot分区并烧写:

    target:~$ flash_erase /dev/mtd0 0x0 60
    target:~$ flashcp imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi /dev/mtd0
    

4.3.1.2. 在开发板的U-Boot环境中通过网络烧写SPI NOR

类似于通过网络更新eMMC,请确保正确设置主机PC。IP地址需要设置为192.168.3.10,子网掩码设置为255.255.255.0,并且需要有一个可用的TFTP服务。在进行读写之前,需要对SPI NOR Flash进行枚举:

u-boot=> sf probe
SF: Detected mt25qu512a with page size 256 Bytes, erase size 64 KiB, total 64 MiB
  • SPI NOR Flash需要使用特殊格式的U-Boot镜像。确保您使用了正确的镜像文件。通过tftp加载镜像,然后将bootloader写入Flash:

    u-boot=> tftp ${loadaddr} imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi
    u-boot=> sf update ${loadaddr} 0 ${filesize}
    device 0 offset 0x0, size 0x1c0b20
    1641248 bytes written, 196608 bytes skipped in 4.768s, speed 394459 B/s
    
  • 同时需要擦除环境分区。这样,环境变量可以在从SPI NOR Flash启动后写入:

    u-boot=> sf erase 0x400000 0x100000
    

4.3.2. 从SD卡烧写SPI NOR Flash

SPI NOR Flash上的bootloader也可以通过SD卡进行烧写。

4.3.2.1. 在开发板的linux环境中从SD卡烧写SPI NOR

  • 将SPI NOR Flash的U-boot镜像imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi复制到SD卡的第一个分区。

  • 挂载SD卡:

    target:~$ mount /dev/mmcblk1p1 /mnt
    
  • 查找要擦除的U-Boot分区的块数:

    target:~$ mtdinfo /dev/mtd0
    mtd0
    Name:                           u-boot
    Type:                           nor
    Eraseblock size:                65536 bytes, 64.0 KiB
    Amount of eraseblocks:          60 (3932160 bytes, 3.7 MiB)
    Minimum input/output unit size: 1 byte
    Sub-page size:                  1 byte
    Character device major/minor:   90:0
    Bad blocks are allowed:         false
    Device is writable:             true
    
  • 擦除u-boot分区并烧写:

    target:~$ flash_erase /dev/mtd0 0x0 60
    target:~$ flashcp /mnt/imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi /dev/mtd0
    

4.3.2.2. 在开发板的U-Boot环境中从SD卡烧写SPI NOR

  • 将SPI NOR Flash的U-boot镜像imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi复制到SD卡的第一个分区。

  • 在进行读写操作之前,需要对SPI-NOR Flash进行枚举:

    u-boot=> sf probe
    SF: Detected n25q256ax1 with page size 256 Bytes, erase size 64 KiB, total 32 MiB
    
  • SPI NOR Flash需要使用特殊格式的U-Boot镜像,请确保使用正确的镜像文件。从SD卡加载镜像,擦除并将bootloader写入flash:

    u-boot=> mmc dev 1
    u-boot=> fatload mmc 1:1 ${loadaddr} imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi
    u-boot=> sf update ${loadaddr} 0 ${filesize}
    
  • 同时需要擦除环境分区。这样,环境变量可以在从SPI NOR Flash启动后写入:

    u-boot=> sf erase 0x400000 0x100000
    

4.4. RAUC

BSP支持RAUC(Robust Auto-Update Controller)。它管理设备固件更新的过程。这包括更新Linux内核、设备树和根文件系统。PHYTEC已撰写了一份在线手册,介绍如何在我们的BSP中集成RAUC: L-1006e.A6 RAUC Update & Device Management Manual

4.5. EFI Boot

Standardboot in U-Boot also supports booting distros over efi. By default the U-Boot will search for a bootscript first, which is used to boot our Ampliphy distro. If it does not find any bootscript, it will search for bootable efi applications. So for booting over efi just make sure you don't have our distro installed.

4.5.1. Disable booting with efi

To disable booting with efi you have to set the doefiboot variable to 0. Also make sure you do not have efi or efi_mgr specified in the bootmeths environment variable.

u-boot=> setenv doefiboot 0
u-boot=> env save; env save;

4.5.2. Switch to only efi boot

If you want to only boot with efi, you can set the bootmeths environment variable to efi. Also make sure you have the doefiboot environment variable set to 1.

u-boot=> setenv bootmeths efi
u-boot=> env save; env save;

4.5.3. Installing a distro

With efi you can install and boot different distros like openSUSE, Fedora or Debian. First you have to get the iso Image from their website. For example:

https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/

Then copy the .iso file to a usb stick for example. Make sure you select the correct device:

sudo dd if=file.iso of=/dev/sdx bs=1M conv=fsync status=progress

Insert the USB stick into the board and boot it. GRUB will then prompt you with a menu where you can select what to do. Here select install. Then you have to click through the installation menu. This is relatively straightforward and differs a bit for every distro. You can install the distro for example to emmc (mmc 2) or sdcard (mmc 1). Make sure you do not overwrite your U-Boot during the install. Best to choose a different medium to install to than the U-Boot is stored on. Otherwise manual partitioning will be required. The automatic partitioning will start at the beginning of the disk. To not overwrite the U-Boot, use an offset of 4MiB at the beginning of the disk.

During the Installation of Debian you will be asked, if you want to Force the GRUB installation to the EFI removable media path. Select no. Also select no, when you will be asked if you want to update the NVRAM variables. Otherwise the grub-dummy installation step will fail and you will be sent back to the "Force GRUB installation" prompt.

After the installation is complete, reboot the board and remove the installation medium (USB-stick). The board should then boot the distro you installed.

If that does not happen, check if there is a boot option set for the distro. The easiest way is with the eficonfig command.

u-boot=> eficonfig

That will open a menu. Then you can select Edit Boot Option. It will show you the current boot options. If this is empty or you don't find your distro, select Add Boot Option to add a new one. For debian for example you only need to set the description and the file. You can enter whatever you want into the description field. When you select the file field, you can select the disc you installed the distro on and partition number one. For example "mmc 2:1" for emmc, or "mmc 1:1" for sdcard. The file you need to select is at EFI/debian/grubaa64.efi. After that save, quit and reset the board. The board should then boot into debian.

5. 开发

从这个版本开始,U-Boot中的启动行为发生了变化。之前,内核和设备树是作为单独的二进制文件提供的。现在,二者将被包含在一个单一的FIT镜像二进制文件中。此外,PHYTEC ampliphy发行版的启动逻辑被移到了一个启动脚本中,该脚本本身是一个单独的FIT镜像二进制文件的一部分。要恢复到旧的启动方式,您可以执行

run legacyboot

备注

这种启动方式已被弃用,并将在下一个版本中移除。默认情况下,通过此命令启动将返回错误,因为启动分区中缺少内核和设备树。

5.1. 独立编译准备

在本节中,我们将描述如何在不使用 Yocto Project 的情况下编译 U-Boot 和 Linux kernel。U-Boot、Linux kernel以及其他源码的 git 仓库都可以在我们的 Git 服务器 上找到,地址为 git://git.phytec.de。

备注

如果您的公司防火墙/网关禁止git协议,您可以改用HTTP或HTTPS(例如:git clone git://git.phytec.de/u-boot-imx)

5.1.1. Git 仓库

  • 使用的 U-Boot 仓库:

    git://git.phytec.de/u-boot-imx
    
  • 我们的U-Boot基于 u-boot-imx 并添加了一些硬件相关的补丁。

  • 使用的 Linux 内核仓库:

    https://github.com/phytec/linux-phytec-imx
    
  • 我们的 i.MX 8M Plus 内核是基于 linux-phytec-imx 内核。

要找出核心板应使用的u-boot和kernel版本对应的git仓库tag标签,请查看您的BSP源文件夹:

meta-phytec/recipes-kernel/linux/linux-phytec-imx_*.bb
meta-phytec/recipes-bsp/u-boot/u-boot-imx_*.bb

5.1.2. 获取SDK

您可以在此处下载SDK 这里,或者使用Yocto去编译生成SDK:

  • 移动到Yocto的build目录:

    host:~$ source sources/poky/oe-init-build-env
    host:~$ bitbake -c populate_sdk phytec-qt6demo-image # or another image
    

在成功编译后,SDK安装包保存在 build/deploy*/sdk

5.1.3. 安装SDK

  • 设置正确的权限并安装SDK:

    host:~$ chmod +x phytec-ampliphy-vendor-xwayland-glibc-x86_64-phytec-qt6demo-image-cortexa53-crypto-toolchain-5.0.x.sh
    host:~$ ./phytec-ampliphy-vendor-xwayland-glibc-x86_64-phytec-qt6demo-image-cortexa53-crypto-toolchain-5.0.x.sh
    ============================================================================================================
    Enter target directory for SDK (default: /opt/ampliphy-vendor-xwayland/5.0.x):
    You are about to install the SDK to "/opt/ampliphy-vendor-xwayland/5.0.x". Proceed [Y/n]? Y
    Extracting SDK...done
    Setting it up...done
    SDK has been successfully set up and is ready to be used.
    

5.1.4. 使用SDK

通过在工具链目录中source environment-setup 文件来初始化您的 shell 交叉编译环境:

host:~$ source /opt/ampliphy-vendor-xwayland/5.0.x/environment-setup-cortexa53-crypto-phytec-linux

5.1.5. 安装所需工具

独立编译Linux kernel和U-Boot需要主机安装一些额外的工具。对于Ubuntu,您可以使用以下命令安装它们:

host:~$ sudo apt install bison flex libssl-dev

5.2. 单独编译U-Boot

5.2.1. 获取源代码

  • 获取U-Boot源代码:

    host:~$ git clone git://git.phytec.de/u-boot-imx
    
  • 要获取正确的 U-Boot tag,您需要查看我们的release notes,可以在这里找到:release notes

  • 此版本中使用的**tag**称为 v2024.04_2.0.0-phy7

  • 查看所需的 U-Boot tag

    host:~$ cd ~/u-boot-imx/
    host:~/u-boot-imx$ git fetch --all --tags
    host:~/u-boot-imx$ git checkout tags/v2024.04_2.0.0-phy7
    
  • 设置编译环境:

    host:~/u-boot-imx$ source /opt/ampliphy-vendor-xwayland/5.0.x/environment-setup-cortexa53-crypto-phytec-linux
    

5.2.2. 获取所需的二进制文件

要编译bootloader,您需要将这些文件复制到您的 u-boot-imx 编译目录,并将其重命名以适应 mkimage 脚本:

  • ARM Trusted firmware 二进制文件mkimage 工具 兼容格式 bl31.bin ):bl31-imx8mp.bin

  • OPTEE 镜像 (可选的):tee.bin

  • DDR firmware files ( mkimage 工具 兼容格式 lpddr4_[i,d]mem_*d_*.bin ): lpddr4_dmem_1d_*.bin, lpddr4_dmem_2d_*.bin, lpddr4_imem_1d_*.bin, lpddr4_imem_2d_*.bin

如果您已经使用Yocto编译了我们的BSP,您可以在yocto工程目录中获取 bl31-imx8mp.bin、tee.bin和lpddr4_*.bin:BSP Images

或者你可以在这里下载文件: https://download.phytec.de/Software/Linux/BSP-Yocto-i.MX8MP/BSP-Yocto-NXP-i.MX8MP-PD24.1.0/images/ampliphy-vendor-xwayland/phyboard-pollux-imx8mp-3/imx-boot-tools/

警告

确保您重命名所需的文件,以和 mkimage tool 兼容。

5.2.3. 编译bootloader

  • 编译 flash.bin (imx-boot):

    host:~/u-boot-imx$ make phycore-imx8mp_defconfig
    host:~/u-boot-imx$ make flash.bin
    

5.2.4. 将bootloader烧写到块设备上

flash.bin 文件可以在 u-boot-imx/ 目录下找到,现在可以进行烧写。需要指定芯片特定的偏移量:

SoC

User分区偏移量

Boot分区偏移量

eMMC设备

i.MX 8M Plus

32 kiB

0 kiB

/dev/mmcblk2

例如,烧写SD卡:

host:~/u-boot-imx$ sudo dd if=flash.bin of=/dev/sd[x] bs=1024 seek=32 conv=sync

提示

如果您有我们的BSP Yocto工程代码,具体的偏移值也会在Yocto变量"BOOTLOADER_SEEK"和"BOOTLOADER_SEEK_EMMC"中声明。

5.2.5. 使用固定内存大小编译U-Boot

如果您的系统因为EEPROM中的硬件信息损坏或丢失而无法启动,您可以创建一个具有固定RAM大小的flash.bin。但您仍应联系我们支持部门以烧写正确的EEPROM数据。

按照步骤获取U-boot源代码,并切换到 Build U-Boot 章节说明的分支。

Edit the file configs/phycore-imx8mp_defconfig:

CONFIG_TARGET_PHYCORE_IMX8MP=y
CONFIG_PHYCORE_IMX8MP_RAM_SIZE_FIX=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_1GB=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_2GB=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_4GB=y

选择正确的RAM大小,确保与核心板上的贴装的器件一致,取消注释该RAM大小的行。保存更改后,按照 Build U-Boot 章节的剩余步骤进行操作。

5.2.6. 编译支持固定RAM大小与频率的U-Boot

从PD23.1.0 NXP或PD24.1.2 Mainline 版本开始,PCB为1549.3版本的核心板及更新版本的phyCORE-i.MX 8M Plus SoM支持2GHz内存时序。这些将在支持的板上自动启用,但也可以手动启用或禁用。

Edit the file configs/phycore-imx8mp_defconfig. The fixed RAM size with 2GHz timings will be used:

CONFIG_TARGET_PHYCORE_IMX8MP=y
CONFIG_PHYCORE_IMX8MP_RAM_SIZE_FIX=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_1GB=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_2GB=y
# CONFIG_PHYCORE_IMX8MP_RAM_SIZE_4GB=y
CONFIG_PHYCORE_IMX8MP_RAM_FREQ_FIX=y
CONFIG_PHYCORE_IMX8MP_USE_2GHZ_RAM_TIMINGS=y

在保存更改后,按照 Build U-Boot 中剩下的步骤操作。

5.2.7. 编译固定的RAM频率的U-Boot

从PD24.1.2 Mainline版本或者 PD24.1.0 NXP 版本开始,U-Boot可以编译成只固定RAM频率,RAM大小还是保持从EEPROM读取。

Edit the file configs/phycore-imx8mp_defconfig. The RAM size from EEPROM with fixed frequency will be used:

CONFIG_TARGET_PHYCORE_IMX8MP=y
CONFIG_PHYCORE_IMX8MP_RAM_FREQ_FIX=y
# CONFIG_PHYCORE_IMX8MP_USE_2GHZ_RAM_TIMINGS=y
# CONFIG_PHYCORE_IMX8MP_USE_1_5GHZ_RAM_TIMINGS=y

在保存更改后,按照 Build U-Boot 中剩下的步骤操作。

5.3. 单独编译内核

内核与设备树一起打包在FIT镜像中。U-Boot已被配置为能够加载FIT镜像并引导其中包含的内核。因此,内核镜像必须打包在FIT镜像中。

5.3.1. 配置源代码

  • 使用的 linux-phytec-imx 分支可以在 release notes 中找到

  • 此版本所需的标签称为 v6.6.23-2.0.0-phy10

  • Check out 所需的 linux-phytec-imx 标签:

    host:~$ git clone https://github.com/phytec/linux-phytec-imx
    host:~$ cd ~/linux-phytec-imx/
    host:~/linux-phytec-imx$ git fetch --all --tags
    host:~/linux-phytec-imx$ git checkout tags/v6.6.23-2.0.0-phy10
    
  • 为了提交更改,强烈建议切换到一个新分支:

    host:~/linux-phytec-imx$ git switch --create <new-branch>
    
  • 设置编译环境:

    host:~/linux-phytec-imx$ source /opt/ampliphy-vendor-xwayland/5.0.x/environment-setup-cortexa53-crypto-phytec-linux
    

5.3.2. 编译内核

  • 编译Linux内核:

    host:~/linux-phytec-imx$ make imx8_phytec_defconfig
    host:~/linux-phytec-imx$ make -j$(nproc)
    
  • 安装内核模块,比如安装到 NFS 目录:

    host:~/linux-phytec-imx$ make INSTALL_MOD_PATH=/home/<user>/<rootfspath> modules_install
    
  • 镜像可以在 ~/linux-phytec-imx/arch/arm64/boot/Image.gz 找到

  • dtb文件可以在 ~/linux-phytec-imx/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dtb 找到

  • 要(重新)编译设备树和 -overlay 文件,只需运行

    host:~/linux-phytec-imx$ make dtbs
    

备注

如果您遇到以下编译问题:

scripts/dtc/yamltree.c:9:10: fatal error: yaml.h: No such file or directory

确保您在主机系统上安装了 "libyaml-dev" 包:

host:~$ sudo apt install libyaml-dev

5.3.3. 将内核打包成FIT镜像

要简单地替换内核,您需要一个 image tree source (.its)文件。如果您已经使用Yocto编译了我们的BSP,可以从此处提到的目录获取its文件: BSP Images 或者您可以在这里下载该文件: https://download.phytec.de/Software/Linux/BSP-Yocto-i.MX8MP/BSP-Yocto-NXP-i.MX8MP-PD24.1.0/images/ampliphy-vendor-xwayland/phyboard-pollux-imx8mp-3/

将 .its 文件复制到当前工作目录,创建一个指向内核镜像的链接,并使用 mkimage 创建最终的 fitImage。

host:~/linux-phytec-imx$ cp /path/to/yocto/deploydir/fitimage-its*.its .
                  && ln -s arch/arm64/boot/Image.gz linux.bin
                  && uboot-mkimage -f fitImage-its*.its fitImage

5.3.4. 将FIT镜像和内核模块复制到SD卡

FIT镜像以及内核module可以用以下方式复制到已挂载的SD卡上。

host:~/linux-phytec-imx$ cp fitImage /path/to/sdcard/boot/
host:~/linux-phytec-imx$ make INSTALL_MOD_PATH=/path/to/sdcard/root/ modules_install

5.4. 使用UUU工具

NXP的镜像更新工具(UUU-Tool)是一款在主机上运行的软件,用于通过SDP(串行下载协议)在开发板上下载并运行bootloader。有关详细信息,请访问 https://github.com/nxp-imx/mfgtools 或下载 官方UUU工具文档

5.4.1. 使用UUU工具的准备

  • 请按照 https://github.com/nxp-imx/mfgtools#linux 上的说明进行操作。

  • 如果您要从源代码编译UUU,请将其添加到 PATH 中:

    这个BASH命令只是暂时将UUU添加到 PATH 中。要永久添加,请将此行添加到 ~/.bashrc 中。

    export PATH=~/mfgtools/uuu/:"$PATH"
    
  • 设置udev规则(在 uuu -udev 中有详细说明):

    host:~$ sudo sh -c "uuu -udev >> /etc/udev/rules.d/70-uuu.rules"
    host:~$ sudo udevadm control --reload
    

5.4.2. 获取镜像

从我们的服务器下载imx-boot,或者从您Yocto工程中的build/deploy-ampliphy-vendor-xwayland/images/phyboard-pollux-imx8mp-3/路径获取。要将wic镜像烧写到eMMC,你还需要 phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic。

5.4.3. 开发板准备

bootmode switch (S3) 设置为 USB串行下载。同时,将 USB 端口 X5 (upper connector) 连接到主机。

5.4.4. 通过UUU工具启动bootloader

执行并给开发板上电:

host:~$ sudo uuu -b spl imx-boot

您可以像往常一样通过 (X1) 在终端上查看启动日志。

备注

UUU工具使用的默认启动命令为fastboot。如果您想更改此设置,请在U-Boot提示符下使用setenv bootcmd_mfg修改环境变量bootcmd_mfg。但是请注意,当开发板再次使用UUU工具启动时,默认环境变量会被加载,saveenv重启后不生效。如果您想永久的更改U-boot的启动命令,则需要更改U-Boot代码。

5.4.5. 通过UUU工具将U-boot镜像烧写到eMMC

警告

UUU将U-boot刷入eMMC BOOT(硬件)启动分区后,会在eMMC中设置BOOT_PARTITION_ENABLE。这带来一个问题,因为我们希望bootloader保存在eMMC 的USER分区中。如果烧写入新的包含U-boot的.wic镜像而不禁用BOOT_PARTITION_ENABLE位,将导致设备始终使用保存在BOOT分区中的U-boot。为了在U-Boot中解决此问题,需要:

u-boot=> mmc partconf 2 0 0 0
u-boot=> mmc partconf 2
EXT_CSD[179], PARTITION_CONFIG:
BOOT_ACK: 0x0
BOOT_PARTITION_ENABLE: 0x0
PARTITION_ACCESS: 0x0

or check Disable booting from eMMC boot partitions from Linux.

这样bootloader虽然会被烧写到 eMMC 的BOOT分区,但在启动中不会被使用!

在使用 partup 工具和 .partup 包进行eMMC烧写时,上述过程是默认进行的,这是partup的优势,简化烧写过程。

执行并给开发板上电:

host:~$ sudo uuu -b emmc imx-boot

5.4.6. 通过UUU工具将wic镜像烧写到eMMC

执行并给开发板上电:

host:~$ sudo uuu -b emmc_all imx-boot phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.wic

5.4.7. 通过UUU工具烧写SPI NOR Flash

执行并给开发板上电:

host:~$ sudo uuu -b qspi imx-boot-phyboard-pollux-imx8mp-3-fspi.bin-flash_evk_flexspi

这将更新SPI NOR Flash上的U-Boot,但不会更新环境。您可能需要擦除旧环境,以便加载新U-Boot的默认环境:

u-boot=> env erase
u-boot=> reset

5.5. 主机网络准备

为了在bootloader中执行涉及网络的各种任务,需要配置一些主机服务。在开发主机上,必须安装和配置TFTP、NFS和DHCP服务。启动以太网所需的工具如下:

host:~$ sudo apt install tftpd-hpa nfs-kernel-server kea

5.5.1. TFTP服务设置

  • 首先,创建一个目录来存储TFTP文件:

    host:~$ sudo mkdir /srv/tftp
    
  • 然后将您的BSP镜像文件复制到此目录,并确保other用户也对tftp目录中的所有文件具有读取权限,否则将无法从开发板访问这些文件。

    host:~$ sudo chmod -R o+r /srv/tftp
    
  • 您还需要为相应的接口配置一个静态IP地址。PHYTEC开发板的默认IP地址是192.168.3.11。可以将主机地址设置为192.168.3.10,子网掩码为255.255.255.0

    host:~$ ip addr show <network-interface>
    

    将 <network-interface> 替换为连接到开发板的网络接口。您可以通过不指定网络接口来显示所有可选网络接口。

  • 返回的结果应包含以下内容:

    inet 192.168.3.10/24 brd 192.168.3.255
    
  • 创建或编辑 /etc/default/tftpd-hpa 文件:

    # /etc/default/tftpd-hpa
    
    TFTP_USERNAME="tftp"
    TFTP_DIRECTORY="/srv/tftp"
    TFTP_ADDRESS=":69"
    TFTP_OPTIONS="-s -c"
    
  • 将 TFTP_DIRECTORY 设置为您的 TFTP 服务器根目录

  • 将TFTP_ADDRESS设置为TFTP服务监听的主机地址(设置为0.0.0.0:69以监听69端口上所有IP)。

  • 设置 TFTP_OPTIONS,以下命令显示可配置的选项:

    host:~$ man tftpd
    
  • 重新启动服务以应用配置更改:

    host:~$ sudo service tftpd-hpa restart
    

现在将开发板的以太网端口连接到您的主机。我们还需要在开发板和运行TFTP服务的主机之间建立网络连接。TFTP服务器的IP地址应设置为192.168.3.10,子网掩码为255.255.255.0。

5.5.1.1. NFS服务器设置

  • 创建一个NFS目录:

    host:~$ sudo mkdir /srv/nfs
    
  • NFS服务对文件共享的路径没有限制,因此在大多数linux发行版中,我们只需修改文件 /etc/exports ,并将我们的根文件系统共享到网络。在这个示例文件中,整个目录被共享在主机地址为192.168.3.10的IP地址上。注意这个地址需要根据本地情况进行调整:

    /srv/nfs 192.168.3.0/255.255.255.0(rw,no_root_squash,sync,no_subtree_check)
    
  • 现在NFS服务器需要再次读取 /etc/exportfs 文件:

    host:~$ sudo exportfs -ra
    

5.5.1.2. DHCP服务器设置

  • 创建或编辑 /etc/kea/kea-dhcp4.conf 文件;以内部子网为例,将 <network-interface> 替换为物理网络接口的名称:

    {
      "Dhcp4": {
        "interfaces-config": {
          "interfaces": [ "<network-interface>/192.168.3.10" ]
        },
        "lease-database": {
          "type": "memfile",
          "persist": true,
          "name": "/tmp/dhcp4.leases"
        },
        "valid-lifetime": 28800,
        "subnet4": [{
            "id": 1,
            "next-server": "192.168.3.10",
            "subnet": "192.168.3.0/24",
            "pools": [
              { "pool": "192.168.3.1 - 192.168.3.255" }
            ]
        }]
      }
    }
    

警告

在创建子网时请小心,因为这可能会扰乱公司网络政策。为了安全起见,请使用不同的子网,并通过 interfaces 配置选项指定该网络。

  • 现在DHCP服务需要重新读取 /etc/kea/kea-dhcp4.conf 文件:

    host:~$ sudo systemctl restart kea-dhcp4-server
    

当您启动/重启主机时,如果kea-dhcp4配置中指定的网络接口未处于活动状态,kea-dhcp4-server将无法启动。因此请确保在连接接口后启动或者重启该systemd服务。

5.6. 从网络启动内核

从网络启动意味着通过TFTP加载内核和设备树,并通过NFS加载根文件系统。但bootloader需要从另外的的启动设备加载。

5.6.1. 在主机上放置网络启动的镜像

  • 将内核fitimage复制到您的tftp目录中:

    host:~$ cp fitImage /srv/tftp
    
  • 将启动脚本复制到您的tftp目录中:

    host:~$ cp boot.scr.uimg /srv/tftp
    
  • 确保other用户对tftp目录中的所有文件具有读取权限,否则将无法从开发板访问它们:

    host:~$ sudo chmod -R o+r /srv/tftp
    
  • 将根文件系统解压到您的NFS目录中:

    host:~$ sudo tar -xvzf phytec-qt6demo-image-phyboard-pollux-imx8mp-3.rootfs.tar.gz -C /srv/nfs
    

备注

请确保使用sudo执行命令,以保留根文件系统中文件的所属权限。

5.6.2. 设置网络启动的bootenv.txt文件

在您的tftp目录中创建一个bootenv.txt文件,并将以下变量写入其中。

nfsroot=/srv/nfs
overlays=<overlayconfignames>

<overlayconfignames> 替换为您想要使用的设备树overlay配置名称。用#号分隔配置名称。例如:

overlays=conf-example-overlay1.dtbo#conf-example-overlay2.dtbo

小技巧

所有支持的设备树overlay文件都在 device tree 章节中。或者可以通过以下命令打印:

host:~$ dumpimage -l fitImage

5.6.3. 开发板上的网络设置

如果要自定义开发板上的以太网配置,请按照此处的说明进行操作: Network Environment Customization

5.6.4. 从开发板启动

将开发板启动到U-boot,按任意键暂停。

  • 要从网络启动,请运行:

    u-boot=> setenv boot_targets ethernet
    u-boot=> bootflow -lb
    

5.7. 获取BSP开发中版本

5.7.1. 当前release的开发中版本

这些release manifest文件是为了让您访问 Yocto BSP的开发版本。它们不会在phyLinux选择菜单中显示,需要手动选择。可以使用以下命令行来完成此操作:

host:~$ ./phyLinux init -p imx8mp -r BSP-Yocto-NXP-i.MX8MP-PD24.1.y

这将初始化一个BSP,用于跟踪当前版本( BSP-Yocto-NXP-i.MX8MP-PD24.1.0 )的最新开发版本。从现在开始,在此文件夹中执行 repo sync 将从我们的Git仓库中拉取所有最新的更改:

host:~$ repo sync

5.7.2. 即将发布版本的开发中版本

即将发布版本的开发中版本可以通过这种方式访问。请执行以下命令,并查找一个比最新版本( BSP-Yocto-NXP-i.MX8MP-PD24.1.0 )的PDXX.Y数字更高的版本,并且以 .y 结尾:

host:~$ ./phyLinux init -p imx8mp

5.8. 获取最新的Upstream支持

我们有一个使用Yocto主分支(不是NXP发布的)的manifest,他使用upstream的Linux和U-Boot。这可以用来测试最新的upstream kernel/U-Boot。

备注

master分支的manifest反映了最新的开发状态。有时会出现一些bug。我们会定期修复master分支。

host:~$ ./phyLinux init -p imx8mp -r BSP-Yocto-Ampliphy-i.MX8MP-master

5.9. 格式化SD卡启动盘以允许通过SD卡进行烧录

使用单一的SD卡启动盘对存储介质进行烧写是开发过程中的常见任务。本章节针对此场景提供基础说明。大多数镜像的大小超过了默认的root分区剩余容量。要使用SD卡进行烧写,根文件系统需要扩展或创建一个单独的分区。有几种不同的方法可以格式化SD卡。最简单的方法是使用Gparted。

5.9.1. Gparted

  • 获取 GParted:

    host:~$ sudo apt install gparted
    
  • 将SD卡插入主机并获取设备名称:

    host:~$ dmesg | tail
    ...
    [30436.175412] sd 4:0:0:0: [sdb] 62453760 512-byte logical blocks: (32.0 GB/29.8 GiB)
    [30436.179846]  sdb: sdb1 sdb2
    ...
    
  • 卸载所有SD卡分区。

  • 启动 GParted:

    host:~$ sudo gparted
    
../../../_images/gparted1.png

5.9.1.1. 扩展根文件系统

警告

使用resize2fs版本1.46.6及更早版本的PC系统(例如Ubuntu 22.04)无法烧写在Mickledore以及更新的yocto版本上创建的partup软件包。这个是因为resize2fs新增了默认选项而导致的兼容性问题。有关详细信息,请参阅 发布说明

  • 在右上角的下拉菜单中选择您的SD卡设备

  • 选择 ext4 根分区并点击调整大小:

../../../_images/gparted5.png ../../../_images/gparted2.png
  • 您可以根据需要拖动滑块或手动输入大小。

../../../_images/gparted3.png
  • 通过点击“Change Size”按钮确认您的输入。

../../../_images/gparted4.png
  • 要应用您的更改,请按绿色勾号。

  • 现在您可以挂载根分区并将 phytec-qt6demo-image-phyboard-pollux-imx8mp-3.wic 镜像复制到其中。然后再卸载它:

    host:~$ sudo cp phytec-qt6demo-image-phyboard-pollux-imx8mp-3.wic /mnt/ ; sync
    host:~$ umount /mnt
    

5.9.1.2. 创建第三个分区

  • 在右上角的下拉菜单中选择您的SD卡设备

../../../_images/gparted1.png
  • 选择更大的未分配区域,然后点击"New":

../../../_images/gparted6.png
  • 点击"Add"

../../../_images/gparted7.png
  • 按绿色勾确认更改。

../../../_images/gparted8.png
  • 现在您可以挂载新的分区并将 phytec-qt6demo-image-phyboard-pollux-imx8mp-3.wic 镜像复制到其中。然后卸载它:

    host:~$ sudo mount /dev/sde3 /mnt
    host:~$ sudo cp phytec-qt6demo-image-phyboard-pollux-imx8mp-3.wic /mnt/ ; sync
    host:~$ umount /mnt
    

5.10. Switch back to legacyboot

警告

As we switched to standardboot with fitimage as default, legacyboot is deprecated. We kept the option to switch back to legacyboot for this release, but it will be removed in the future.

5.10.1. Changes in Yocto

By default, the fitImage and bootscript will be deployed into the wic.xz Image. To switch back to legacyboot, you need to replace the fitImage and bootscript for the kernel image and the devicetrees. They are still in the deploy folder from the Yocto build, so you can manually copy them to the boot partition on your device. Otherwise you can do the following changes in Yocto to get the kernel and devicetrees deployed in the Image again.

First create the variable KERNEL_DEVICETREE_DEPLOY. This can be done for example in the local.conf file in your build directory conf/local.conf. The variable is basically a copy of the KERNEL_DEVICETREE variable that is set in conf/machine/phyboard-pollux-imx8mp-3.conf in meta-phytec but the freescale at the beginning needs to be removed, so that only the devicetree filename are left. In the end it should look something like this:

KERNEL_DEVICETREE_DEPLOY = " \
     imx8mp-phyboard-pollux-rdk.dtb \
     imx8mp-phyboard-pollux-isp-csi1.dtbo \
     imx8mp-phyboard-pollux-isp-csi2.dtbo \
     imx8mp-phyboard-pollux-isi-csi1.dtbo \
     imx8mp-phyboard-pollux-isi-csi2.dtbo \
     imx8mp-phyboard-pollux-peb-av-10.dtbo \
     imx8mp-phyboard-pollux-peb-wlbt-05.dtbo \
     imx8mp-phyboard-pollux-vm016-csi1.dtbo \
     imx8mp-phyboard-pollux-vm016-csi1-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm016-csi1-fpdlink-port1.dtbo \
     imx8mp-phyboard-pollux-vm016-csi2.dtbo \
     imx8mp-phyboard-pollux-vm016-csi2-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm016-csi2-fpdlink-port1.dtbo \
     imx8mp-phyboard-pollux-vm017-csi1.dtbo \
     imx8mp-phyboard-pollux-vm017-csi1-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm017-csi1-fpdlink-port1.dtbo \
     imx8mp-phyboard-pollux-vm017-csi2.dtbo \
     imx8mp-phyboard-pollux-vm017-csi2-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm017-csi2-fpdlink-port1.dtbo \
     imx8mp-phyboard-pollux-vm020-csi1.dtbo \
     imx8mp-phyboard-pollux-vm020-csi1-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm020-csi1-fpdlink-port1.dtbo \
     imx8mp-phyboard-pollux-vm020-csi2.dtbo \
     imx8mp-phyboard-pollux-vm020-csi2-fpdlink-port0.dtbo \
     imx8mp-phyboard-pollux-vm020-csi2-fpdlink-port1.dtbo \
     imx8mp-phycore-no-eth.dtbo \
     imx8mp-phycore-no-rtc.dtbo \
     imx8mp-phycore-no-spiflash.dtbo \
     imx8mp-phycore-rpmsg.dtbo \
"

Then add this line:

IMAGE_BOOT_FILES:mx8m-nxp-bsp:append = " Image oftree ${KERNEL_DEVICETREE_DEPLOY}"

备注

A clean might be required for this to work.

bitbake -c cleanall phytec-qt6demo-image

Then start the build:

host:~$ bitbake phytec-qt6demo-image

5.10.2. Changes in U-Boot environment

To re-enable legacyboot set the following variable:

uboot=> setenv dolegacyboot 1
uboot=> env save; env save;
uboot=> boot

6. 设备树 (DT)

6.1. 介绍

以下文本简要描述了设备树,关于设备树的相关文档可以在Linux kernel文档中找到(https://docs.kernel.org/devicetree/usage-model.html)。

“Open Firmware Device Tree”或简称设备树(DT)是一种用于描述硬件的数据结构和语言。更具体地说,它是一个可由操作系统读取的硬件描述,以便操作系统不需要对machine的细节进行硬编码

内核文档是学习设备树的一个非常好的资源。关于设备树数据格式的概述可以在 devicetree.org 的设备树使用页面找到。

6.2. PHYTEC i.MX 8M Plus BSP设备树概念

以下部分说明了PHYTEC配置基于 i.MX 8M Plus 的核心板设备树的一些规则。

6.2.1. 设备树结构

  • Module.dtsi - 文件包括所有安装在核心板上的设备,例如PMIC和RAM。

  • Board.dts - 包含module dtsi 文件。从SoC i.MX 8M Plus 引出并在底板使用的设备也包含在此 dts 中。

  • Overlay.dtso - 根据核心板或底板上可选硬件(例如 SPI 闪存或 PEB-AV-10)的情况来启用/禁用一些功能。

在Linux内核的根目录下,我们的 i.MX 8 平台的设备树文件可以在 arch/arm64/boot/dts/freescale/ 找到。

6.2.2. 设备树Overlay

设备树Overlay是可以在启动时合并到设备树中的设备树片段。下面是扩展板的硬件描述。对比源码中的include,overlay通过覆盖的方式来生效。overlay也可以根据实际开发板的硬件配置来设置设备树节点状态。设备树Overlay与我们Linux内核仓库中的其他设备树文件一起放在子文件夹 arch/arm64/boot/dts/freescale/ 中。

phyboard-pollux-imx8mp-3.conf 可用的overlay文件有:

imx8mp-isi-csi1.dtbo
imx8mp-isi-csi2.dtbo
imx8mp-isp-csi1.dtbo
imx8mp-isp-csi2.dtbo
imx8mp-phyboard-pollux-peb-av-10.dtbo
imx8mp-phyboard-pollux-peb-wlbt-05.dtbo
imx8mp-phycore-no-eth.dtbo
imx8mp-phycore-no-rtc.dtbo
imx8mp-phycore-no-spiflash.dtbo
imx8mp-phycore-rpmsg.dtbo
imx8mp-vm016-csi1.dtbo
imx8mp-vm016-csi1-fpdlink.dtbo
imx8mp-vm016-csi2.dtbo
imx8mp-vm016-csi2-fpdlink.dtbo
imx8mp-vm017-csi1.dtbo
imx8mp-vm017-csi1-fpdlink.dtbo
imx8mp-vm017-csi2.dtbo
imx8mp-vm017-csi2-fpdlink.dtbo

Otherwise you can show the content of a FIT image including all overlay configs in the FIT image with this command in Linux:

host:~$ dumpimage -l /boot/fitImage

or in U-Boot:

u-boot=> load mmc ${mmcdev}:1 ${loadaddr} fitImage
u-boot=> iminfo

可以在Linux或U-Boot环境下配置overlay。overlay是在引导命令调用后、内核加载之前生效。接下来的部分将更详细地解释配置方法。

6.2.2.1. 设置 ${overlays} 变量

The ${overlays} U-Boot environment variable contains a number-sign (#) separated list of overlays that will be applied during boot. The overlays listed in the overlays variable must be included in the FIT image. Overlays set in the $KERNEL_DEVICETREE Yocto machine variable will automatically be added to the FIT image.

The ${overlays} variable can either be set directly in the U-Boot environment or can be part of the external bootenv.txt environment file. When desired to use the overlays variable as set manually in the U-Boot environment, disable bootenv by setting env set no_bootenv 1 as the overlays variable may be overwritten during the execution of the boot script. By default, the ${overlays} variable comes from the external bootenv.txt environment file which is located in the boot partition. You can read and write the file on booted target from linux:

target:~$ cat /boot/bootenv.txt
overlays=conf-imx8mp-phyboard-pollux-rdk-peb-eval-01.dtbo#conf-imx8mp-phyboard-pollux-peb-av-10.dtbo

更改将在下次重启后生效。如果没有可用的 bootenv.txt 文件,可以直接在U-Boot环境中设置overlay变量。

u-boot=> setenv overlays conf-imx8mp-phyboard-pollux-peb-av-10.dtbo
u-boot=> printenv overlays
overlays=conf-imx8mp-phyboard-pollux-peb-av-10.dtbo
u-boot=> boot

如果用户定义了 ${overlays} 变量,同时存在 bootenv.txt 文件,则需要设置 ${no_bootenv} 变量:

u-boot=> setenv no_bootenv 1
u-boot=> setenv overlays conf-imx8mp-phyboard-pollux-peb-av-10.dtbo
u-boot=> boot

有关环境的更多信息,请参见 U-boot External Environment subsection of the device tree overlay section

We use the ${overlays} variable for overlays describing expansion boards and cameras that can not be detected during run time. To prevent applying overlays unset the overlays variable and set no_bootenv to anything other than 0.

u-boot=> env delete overlays
u-boot=> env set no_bootenv 1

If desired to use the bootenv.txt file for setting U-Boot variables other than overlays and having overlays disabled, remove the overlays definition line from the bootenv.txt file instead of setting no_bootenv.

6.2.2.2. SoM Variants

Additional overlays are applied automatically to disable components that are not populated on the SoM. The detection is done with the EEPROM data (EEPROM SoM Detection) found on the SoM i2c EEPROM.

这取决于核心板型号是否会应用任何设备树overlay。要检查在U-Boot中运行的SoM是否会应用overlay,请运行:

u-boot=> env print fit_extensions

如果没有可用的EEPROM数据,则不加载任何设备树overlay。

To prevent application of the SoM variant related overlays the ${no_extensions} variable can be set to 1 in the bootloader environment:

u-boot=> setenv no_extensions 1
u-boot=> boot

6.2.3. U-boot外部环境

在Linux内核启动时,外部环境 bootenv.txt 文本文件将从MMC设备的boot分区或通过TFTP加载。该文件的主要目的是存储 ${overlays} 变量。这可以针对不同的machine在Yocto中预定义不同的overlay配置。文件的内容在meta-phytec中的Yocto recipe中的bootenv中定义: https://git.phytec.de/meta-phytec/tree/recipes-bsp/bootenv?h=scarthgap

该文件中也可以设置其他变量。这些变量将覆盖环境中现有的设置。但只有对boot命令后进行计算的变量生效,例如 ${nfsroot}${mmcargs}。在文件中更改其他变量将不会有作用。以网络启动的用法作为示例。

如果无法加载外部环境,启动过程将继续进行,并使用自带的环境变量值。

6.2.4. 在Linux环境下更改开发板上的U-boot环境变量

Libubootenv是我们镜像中包含的一个工具,用于在开发板linux上修改U-Boot环境。

使用以下命令打印U-Boot环境:

target:~$ fw_printenv

使用以下命令修改U-Boot环境:

target:~$ fw_setenv <variable> <value>

小心

Libubootenv会读取配置文件中配置的环境变量。要修改的环境变量会被插入到该文件中,默认情况下使用eMMC中存储环境变量。

如果eMMC没有被烧写过或者eMMC环境被擦除,libubootenv将无法工作。您应该修改 /etc/fw_env.config 文件,以匹配您想要使用的环境源。

7. 访问外设

要查找本文中所述的PHYTEC的phyCORE-i.MX 8M Plus BSP支持的开发板和核心板,请访问 our BSP 网页,并在下载部分点击相应的BSP版本。在这里,您可以在"Hardware Article Number"列中找到所有支持的硬件,并在"Machine Name"下的相应单元格中找到正确的"Machine Name"。

为了最大化软件的可复用性,Linux内核提供了一个巧妙的软件架构,软件会根据不同硬件组件来分层。BSP(板级支持包)尽可能地对套件的功能进行模块化。当定制开发板或自定义核心板时,大部分软件配置可以简单的复制粘贴。与具体的开发板相关的内核代码可以在内核代码仓库中的设备树(DT)中找到,路径为 arch/arm64/boot/dts/freescale/*.dts

实际上,软件复用是Linux内核最重要的特性之一,尤其是在ARM架构中,它必须应对大量复杂且不同的系统级芯片(SoC)。整个开发板的硬件在设备树(DT)中描述,独立于内核镜像。硬件描述在一个单独的二进制文件中,称为设备树二进制文件(Device Tree Blob,DTB)(参见 device tree)。

请阅读PHYTEC i.MX 8M Plus BSP设备树概念部分,以了解我们的 i.MX 8 BSP设备树模型。

以下部分概述了 i.MX 8 平台上支持的硬件组件及其对应操作系统驱动程序。客户可以根据自身的需求进行更改。

7.1. i.MX 8M Plus 引脚复用

该 i.MX 8M Plus Soc包含许多外设接口。为了在保持最大功能性的同时减少封装尺寸和降低整体系统成本,许多 i.MX 8M Plus 引脚可以多路复用为多达八种信号功能。尽管存在许多可能的引脚多路复用组合,但由于时序限制,只有一定数量的组合被称为有效的 IO 集合。这些有效的 IO 集合经过精心挑选,以为用户提供尽可能多的应用场景。

请参考我们的硬件手册或NXP i.MX 8M Plus 参考手册,以获取有关特定引脚和复用能力的更多信息。

IO 集合的配置,也称为复用(muxing),是在设备树中完成的。驱动程序pinctrl-single读取设备树的节点fsl,pins,并进行引脚复用配置。

以下是 imx8mp-phyboard-pollux-rdk.dts中UART1设备的引脚复用示例:

pinctrl_uart1: uart1grp {
        fsl,pins = <
                MX8MP_IOMUXC_UART1_RXD_UART1_DCE_RX     0x140
                MX8MP_IOMUXC_UART1_TXD_UART1_DCE_TX     0x140
        >;
};

字符串的第一部分 MX8MP_IOMUXC_UART1_RXD_UART1_DCE_RX 指定了引脚(在这个例子中是 UART1_RXD)。字符串的第二部分(UART1_DCE_RX)是该引脚所选的复用项。引脚设置值(右侧的十六进制值)定义了引脚的不同模式,例如,内部拉电阻是否被激活。在当前情况下,内部拉电阻被禁用。

The device tree representation for UART1 pinmuxing: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L373

7.2. RS232/RS485

phyCORE-i.MX 8M Plus 支持最多 4 个 UART 单元。在 phyBOARD-Pollux 上,UART1(调试串口)和 UART4 的 TTL 电平信号被连接到 Silicon Labs CP2105 UART 到 USB 转换IC。这个 USB 信号通过 Micro-USB 连接器 X1 输出。UART3 位于 X6(扩展连接器),为 TTL 电平信号。UART2 连接到一个多协议收发器IC,可转换为 RS-232 或 RS-485,RS-232 和 RS-485 信号位于连接器 X2 。多协议配置通过主板上的跳线 JP3JP4 完成。更多信息,请参阅 phyCORE-i.MX 8M Plus/phyBOARD-Pollux 硬件手册中的 UARTs 部分。

对于RS-232和RS-485,使用相同的设备树节点。RS485模式可以通过ioctl TIOCSRS485 来启用。双向通讯支持也可以通过ioctl进行配置。请查看我们的小示例应用程序rs485test,该程序也包含在BSP中。需要设置跳线 JP3JP4

7.2.1. RS232

  • 以人类可读的格式显示终端的当前设置:

    target:~$ stty -a
    
  • UART接口的配置可以通过stty命令完成。例如:

    target:~$ stty -F /dev/ttymxc1 115200 crtscts raw -echo
    
  • 通过简单的echo和cat,可以测试基本的通信。示例:

    target:~$ echo 123 > /dev/ttymxc1
    
    host:~$ cat /dev/ttyUSB2
    

主机应打印出 "123"。

7.2.2. RS485

提示

Remember to use bus termination resistors of 120 Ohm at each end of the bus, when using longer cables.

为了方便测试,请查看linux-serial-test。这个工具会通过调用RS485的IOCTL,发送恒定的数据流。

target:~$ linux-serial-test -p /dev/ttymxc1 -b 115200 --rs485 0

有关linux-serial-test工具及其参数的更多信息,请访问此链接:linux-serial-test

The linux-serial-test will automatically set ioctls, but they can also be set manually with rs485conf.

You can show the current config with:

target:~$ rs485conf /dev/ttymxc1

You can show all options with:

target:~$ rs485conf /dev/ttymxc1 -h

Linux kernel文档描述了如何在C代码中调用IOCTL: https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt

7.2.2.1. RS485 half-duplex

For half-duplex mode your connection setup should look like this:

../../../_images/RS485_halfduplex_connection.png

Which function is on which pin is described in the hardware manual.

For half-duplex mode you can set the ioctls manually like this:

target:~$ rs485conf /dev/ttymxc1 -e 1 -r 0
target:~$ rs485conf /dev/ttymxc1
= Current configuration:
RS485 enabled:                true
RTS on send:                  high
RTS after send:               low
RTS delay before send:        0
RTS delay after send:         0
Receive during sending data:  false
Bus termination enabled:  false

Then you can test if sending and receiving works like this:

target1:~$ cat /dev/ttymxc1
target2:~$ echo test > /dev/ttymxc1

You should see "test" printed out on target1. You can also switch the roles and send on target2 and receive on target1.

Alternatively you can also test with the linux-serial-test tool:

target1:~$ linux-serial-test -s -e -f -p /dev/ttymxc1 -b 115200 --rs485 0 -t -i 8
...
/dev/ttymxc1: count for this session: rx=57330, tx=0, rx err=0
target2:~$ linux-serial-test -s -e -f -p /dev/ttymxc1 -b 115200 --rs485 0 -r -o 5
...
/dev/ttymxc1: count for this session: rx=0, tx=57330, rx err=0

In this example target1 will be the receiver and target2 will be the transmitter. You should also be able to switch the roles. Remember to first start the receiver and then the transmitter immediately after. The receiver will receive for 8 sec and the transmitter will send for 5 sec. The receiver needs to receive for a bit longer than the transmitter sends. At the end the program will print the final "count for this session". There you can check, that all transmitted frames were received.

All the tests are target to target, but can also be done with host to target with a USB to rs485 converter. You may need to adjust the interfaces then.

7.2.2.2. RS485 full-duplex

For full-duplex mode your connection setup should look like this:

../../../_images/RS485_fullduplex_connection.png

Which function is on which pin is described in the hardware manual.

For full-duplex mode you can set the ioctls manually like this:

target:~$ rs485conf /dev/ttymxc1 -e 1 -r 1
target:~$ rs485conf /dev/ttymxc1
= Current configuration:
RS485 enabled:                true
RTS on send:                  high
RTS after send:               low
RTS delay before send:        0
RTS delay after send:         0
Receive during sending data:  true
Bus termination enabled:  false

Also here you can do the echo test to see if sending and receiving works:

target1:~$ cat /dev/ttymxc1
target2:~$ echo test > /dev/ttymxc1

You should see "test" printed out on target1. You can also switch the roles and send on target2 and receive on target1.

To check if the full-duplex operation works, you need to use the linux-serial-test tool:

target1:~$ linux-serial-test -s -e -f -p /dev/ttymxc1 -b 115200 --rs485 0 -o 10 -i 15 -W 2
...
/dev/ttymxc1: count for this session: rx=114660, tx=118755, rx err=0
target2:~$ linux-serial-test -s -e -f -p /dev/ttymxc1 -b 115200 --rs485 0 -o 10 -i 15 -W 2
...
/dev/ttymxc1: count for this session: rx=118755, tx=114660, rx err=0

In this example both targets will send and receive simultaneously. They will receive for 15sec and send for 10sec. The receiver needs to receive a bit longer, so that all sent messages will get received. Remember to start both targets almost simultaneously. A small difference in start time is accounted for with the -W 2 option. At the end the program will print the final "count for this session". There you can check that all transmitted frames were received.

All the test examples are target to target, but can also be done with host to target with a USB to rs485 converter. You may need to adjust the interfaces for commands to work on the host then.

The device tree representation for RS232 and RS485: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L412

7.3. 网络

phyBOARD-Pollux-i.MX 8M Plus 提供两个以太网接口。我们的核心板和底板各提供一个千兆以太网接口。

警告

硬件中的以太网接口命名约定(ethernet0 和 ethernet1)与Linux中的网络接口(eth0 和 eth1)不一致。因此,请注意这些差异:

ethernet1 = eth0
ethernet0 = eth1

所有接口都提供一个标准的Linux网络端口,可以使用BSD套接字接口进行编程。整个网络配置由systemd-networkd守护进程管理。相关的配置文件可以在开发板的 /lib/systemd/network/ 目录中找到,以及在BSP中的 meta-ampliphy/recipes-core/systemd/systemd-conf 目录中。

IP地址可以在*.network文件中进行配置。eth0的默认IP地址和子网掩码为:

eth0: 192.168.3.11/24

根据您的硬件配置,设备树的以太网设置可能会分为两个文件:核心板的DT文件和底板的DT。FEC以太网IP核心的设备树设置,其中以太网PHY被集成在核心板上,可以在这里找到:https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L50

The device tree set up for EQOS Ethernet IP core where the PHY is populated on the phyBOARD-Pollux can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L179.

7.3.1. 网络配置

7.3.1.1. U-boot网络环境

  • 要在bootloader中查找以太网设置:

    u-boot=> printenv ipaddr serverip netmask
    
  • 在将主机设置为IP 192.168.3.10和子网掩码255.255.255.0的情况下,开发板应该返回:

    u-boot=> printenv ipaddr serverip netmask
    ipaddr=192.168.3.11
    serverip=192.168.3.10
    netmask=255.225.255.0
    
  • 如果您需要进行任何更改:

    u-boot=> setenv <parameter> <value>
    

    <parameter> 应该是 ipaddr、netmask、gatewayip 或 serverip 中的一个。<value> 将是所选参数的设定值。

  • 您所做的更改目前是临时的。要保存这些更改:

    u-boot=> saveenv
    

在这里,您也可以将IP地址更改为DHCP,而不是使用静态IP地址。

  • 配置:

    u-boot=> setenv ip dhcp
    
  • 设置 TFTP 和 NFS 的路径。修改可以如下所示:

    u-boot=> setenv nfsroot /home/user/nfssrc
    

请注意,这些修改只会影响bootloader的设置。

小技巧

像nfsroot和netargs这样的变量可以被U-boot外部环境重新赋值。对于网络启动,外部环境将通过tftp加载。例如,要在 bootenv.txt 文件中设置nfsroot变量,请在tftproot目录修改:

nfsroot=/home/user/nfssrc

无需在开发板上存储这些信息。请注意,U-boot外部环境对于像 ipaddr 或 serveraddr 这样的变量不起作用,因为它们在加载外部环境之前已经被设置完成。

7.3.1.2. 内核网络环境

  • 在开发板中查找eth0的以太网设置:

    target:~$ ifconfig eth0
    eth0      Link encap:Ethernet  HWaddr 50:2D:F4:19:D6:33
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    
  • 临时调整eth0的配置:

    target:~$ ifconfig eth0 192.168.3.11 netmask 255.255.255.0 up
    

7.3.2. 无线局域网

在 phyBOARD-Pollux 上,WLAN和蓝牙由PEB-WLBT-05扩展板提供。PEB-WLBT-05的 phyBOARD-Pollux 快速入门指南向您展示了如何安装PEB-WLBT-05。

小技巧

对于BSP版本PD22.1及更新版本,需要先激活PEB-WLBT-05 Overlay,否则PEB-WLBT-05将无法被识别。

target:~$ vi /boot/bootenv.txt

之后,bootenv.txt 文件应该如下所示(它还可以包含其他设备树overlay!):

overlays=conf-imx8mp-phyboard-pollux-peb-wlbt-05.dtbo

更改将在重启后应用:

target:~$ reboot

有关设备树overlay的更多信息,请阅读 device tree 章节。

为了支持WLAN和蓝牙,我们使用来自LSR的Sterling-LWB模块。该模块支持2.4 GHz,并且可以在多种模式下运行,如客户端模式、使用WEP、WPA、WPA2加密的接入点(AP)模式等。有关该模块的更多信息,请访问 https://connectivity-staging.s3.us-east-2.amazonaws.com/2019-09/CS-DS-SterlingLWB%20v7_2.pdf

7.3.2.1. 连接到WLAN网络

首先设置您所在国家的正确监管域:

target:~$ iw reg set DE
target:~$ iw reg get

你将会看到:

country DE: DFS-ETSI
   (2400 - 2483 @ 40), (N/A, 20), (N/A)
   (5150 - 5250 @ 80), (N/A, 20), (N/A), NO-OUTDOOR
   (5250 - 5350 @ 80), (N/A, 20), (0 ms), NO-OUTDOOR, DFS
   (5470 - 5725 @ 160), (N/A, 26), (0 ms), DFS
   (57000 - 66000 @ 2160), (N/A, 40), (N/A)

设置无线接口:

target:~$ ip link
target:~$ ip link set up dev wlan0

现在您可以扫描可用的网络:

target:~$ iw wlan0 scan | grep SSID

您可以使用一个跨平台的客户端,名为wpa_supplicant,支持WEP、WPA和WPA2,以建立加密连接。

为此,请将网络凭据添加到文件 /etc/wpa_supplicant.conf 中:

country=DE
network={
    ssid="<SSID>"
    proto=WPA2
    psk="<KEY>"
}

现在可以建立连接:

target:~$ wpa_supplicant -D nl80211 -c /etc/wpa_supplicant.conf -i wlan0 -B

这会得到如下输出:

Successfully initialized wpa_supplicant

The ip address is automatically configured over DHCP. For other possible IP configurations, see section Changing the Network Configuration in the Yocto Reference Manual (scarthgap).

7.3.3. 蓝牙

Bluetooth is supported on phyBOARD-Pollux with the PEB-WLBT-05 expansion card. How this can be activated is described in the WLAN section.

Bluetooth is connected to UART3 interface. More information about the module can be found at https://connectivity-staging.s3.us-east-2.amazonaws.com/2019-09/CS-DS-SterlingLWB%20v7_2.pdf. The Bluetooth device needs to be set up manually:

target:~$ hciconfig hci0 up

target:~$ hciconfig -a

hci0:   Type: Primary  Bus: UART
        BD Address: 00:25:CA:2F:39:96  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING PSCAN
        RX bytes:1392 acl:0 sco:0 events:76 errors:0
        TX bytes:1198 acl:0 sco:0 commands:76 errors:0
        ...

现在您可以扫描环境中的可见蓝牙设备。在默认配置下,蓝牙是不可见的。

target:~$ hcitool scan
Scanning ...
       XX:XX:XX:XX:XX:XX       <SSID>

7.3.3.1. 可见性

要激活可见性:

target:~$ hciconfig hci0 piscan

要禁用可见性:

target:~$ hciconfig hci0 noscan

7.3.3.2. 连接

target:~$ bluetoothctl
[bluetooth]# discoverable on
Changing discoverable on succeeded
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# scan on
[NEW] Device XX:XX:XX:XX:XX:XX <name>
[bluetooth]# connect XX:XX:XX:XX:XX:XX

备注

如果连接失败并出现错误信息:“连接失败:org.bluez.Error.Failed”,请尝试使用以下命令重新启动PulseAudio:

target:~$ pulseaudio --start

7.4. SD/MMC 卡

该 i.MX 8M Plus 支持一个用于SD卡和MMC卡的接口,作为linux通用块设备。这些设备可以像其他任何块设备一样使用。

警告

这些设备是热插拔的。然而,您必须确保在设备仍然挂载时不要拔掉它。这可能会导致数据丢失!

插入SD/MMC卡后,内核将在/dev中生成新的设备节点。完整设备可以通过其/dev/mmcblk1设备节点访问。SD/MMC卡的分区将显示为:

/dev/mmcblk1p<Y>

<Y> 作为分区编号,从1开始计数,直到该设备的最大分区数量。分区可以使用任何类型的文件系统进行格式化,并且可以以标准方式进行处理,例如,可以使用mount 和 umount 命令进行分区挂载和卸载。

小技巧

这些分区设备节点要求SD卡包含有效的分区表(类似于“硬盘”)。如果没有分区表,则整个设备作为一个文件系统使用(类似于“软盘”)。在这种情况下,必须使用 /dev/mmcblk1 进行格式化和挂载。卡始终以可写方式挂载。

DT configuration for the MMC (SD card slot) interface can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L422

DT configuration for the eMMC interface can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L214

7.5. eMMC设备

PHYTEC模块如phyCORE-i.MX 8M Plus 配备了eMMC存储芯片作为主要存储。eMMC设备使用多层单元(MLC)或三层单元(TLC)技术来实现存储,并集成了处理ECC和磨损均衡的存储控制器。它们通过SD/MMC接口连接到 i.MX 8M Plus ,并在Linux内核中作为块设备表示,如SD卡、优盘或硬盘。

电气和协议规范由JEDEC提供(https://www.jedec.org/standards-documents/technology-focus-areas/flash-memory-ssds-ufs-emmc/e-mmc)。eMMC制造商的数据手册相对较简单,旨在与支持的JEDEC eMMC标准版本一起阅读。

PHYTEC目前使用JEDEC版本5.0和5.1的eMMC芯片。

7.5.1. 扩展CSD寄存器

通过扩展CSD寄存器可以读取eMMC设备其他的信息和配置。有关寄存器的详细列表,请参阅制造商的数据手册和JEDEC标准。

在Linux用户空间中,您可以查询寄存器:

target:~$ mmc extcsd read /dev/mmcblk2

你将会看到:

=============================================
   Extended CSD rev 1.7 (MMC 5.0)
=============================================

 Card Supported Command sets [S_CMD_SET: 0x01]
 [...]

7.5.2. 使能后台操作 (BKOPS)

与原始NAND Flash相比,eMMC设备包含一个闪存传输层(FTL),该层负责处理原始MLC或TLC的磨损均衡、块管理和错误更正码(ECC)。这需要定期执行一些维护任务(例如擦除未使用的块)。这些任务被称为 后台操作(BKOPS)

默认情况下(取决于芯片),后台操作可能会定期执行,也可能不会,他影响读写的最大延迟时间。

JEDEC标准自版本v4.41起规定了一种方法,主机可以手动触发BKOPS。有关更多详细信息,请参阅JEDEC标准章节“Background Operations”以及eMMC数据手册中寄存器BKOPS_EN(寄存器:163)和BKOPS_START(寄存器:164)的描述。

寄存器 BKOPS_EN(寄存器:163)的位 MANUAL_EN(位 0)的含义:

  • 值 0:主机不支持手动触发 BKOPS。设备写入性能会受到影响。

  • 值1:主机支持手动触发BKOPS。当主机不进行设备读写时,它会不时触发BKOPS。

自v3.7版本以来,Linux内核已经实现了触发后台操作的机制。您只需在eMMC设备上启用BKOPS_EN(详细信息见下文)。

JEDEC标准v5.1引入了一种新的自动BKOPS功能。它使主机能够定期触发后台操作,因为设备在空闲时会自动启动BKOPS(请参见寄存器BKOPS_EN(寄存器:163)中位AUTO_EN的描述)。

  • 要检查 BKOPS_EN 是否已设置,请执行:

    target:~$ mmc extcsd read /dev/mmcblk2 | grep BKOPS_EN
    

    输出将会是,例如:

    Enable background operations handshake [BKOPS_EN]: 0x01
    #OR
    Enable background operations handshake [BKOPS_EN]: 0x00
    

    值0x00表示BKOPS_EN被禁用,设备的写入性能受到影响。值0x01表示BKOPS_EN被启用,主机将不时发起后台操作。

  • 通过以下命令使能BKOPS_EN:

    target:~$ target:~$ mmc --help
    
    [...]
    mmc bkops_en <auto|manual> <device>
        Enable the eMMC BKOPS feature on <device>.
        The auto (AUTO_EN) setting is only supported on eMMC 5.0 or newer.
        Setting auto won't have any effect if manual is set.
        NOTE!  Setting manual (MANUAL_EN) is one-time programmable (unreversible) change.
    
  • 要设置BKOPS_EN位,请执行:

    target:~$ mmc bkops_en manual /dev/mmcblk2
    
  • 为了确保新设置生效并且内核能够自动触发BKOPS,请先关闭系统:

    target:~$ poweroff
    

小技巧

BKOPS_EN位是一次性可编程的,无法恢复。

7.5.3. 可靠写入

有两种不同的可靠写入选项:

  1. 对整个eMMC设备/分区的可靠写入方式。

  2. 单次写的可靠写入方式。

小技巧

不要将 eMMC 分区与 DOS、MBR 或 GPT 分区表的分区混淆(请参阅前一节)。

第一个可靠写入方式大多数情况下已经在phyCORE-i.MX 8M Plus SoM上挂载的eMMC上被启用。想要在运行的开发板上检查这一点:

target:~$ mmc extcsd read /dev/mmcblk2 | grep -A 5 WR_REL_SET
Write reliability setting register [WR_REL_SET]: 0x1f
 user area: the device protects existing data if a power failure occurs during a write o
peration
 partition 1: the device protects existing data if a power failure occurs during a write
 operation
 partition 2: the device protects existing data if a power failure occurs during a write
 operation
 partition 3: the device protects existing data if a power failure occurs during a write
 operation
 partition 4: the device protects existing data if a power failure occurs during a write
 operation
--
 Device supports writing EXT_CSD_WR_REL_SET
 Device supports the enhanced def. of reliable write

如果默认没有启用,可以使用mmc工具启用它:

target:~$ mmc --help

[...]
mmc write_reliability set <-y|-n|-c> <partition> <device>
    Enable write reliability per partition for the <device>.
    Dry-run only unless -y or -c is passed.
    Use -c if more partitioning settings are still to come.
    NOTE!  This is a one-time programmable (unreversible) change.

第二个可靠写入方式是命令CMD23中的配置位Reliable Write Request parameter(可靠写入请求参数)(位31)。自内核版本v3.0起,文件系统(例如ext4的日志)和用户空间应用程序(如fdisk的分区表)会通过内核使用该可靠写功能。在Linux内核源代码中,它通过标志REQ_META进行处理。

结论:使用挂载选项 data=journal 的 ext4 文件系统在断电情况下是安全的。文件系统检查可以在断电后恢复文件系统,但在断电前刚写入的数据可能会丢失。在各种情况下,都可以恢复文件系统的正常状态。为了确保应用程序文件的正常保存,应用程序中应使用系统函数 fdatasync 或 fsync。

7.5.4. 调整 ext4 根文件系统的大小

在将SD卡镜像写入eMMC时,ext4文件系统分区没有扩展到eMMC的末尾。可以使用parted来扩展根分区。这个示例适用于任何块设备,例如eMMC、SD卡或硬盘。

  • 获取当前设备大小:

    target:~$ parted /dev/mmcblk2 print
    
  • 输出如下:

    Model: MMC Q2J55L (sd/mmc)
    Disk /dev/mmcblk2: 7617MB
    Sect[ 1799.850385]  mmcblk2: p1 p2
    or size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags:
    
    Number  Start   End     Size    Type     File system  Flags
     1      4194kB  72.4MB  68.2MB  primary  fat16        boot, lba
     2      72.4MB  537MB   465MB   primary  ext4
    
  • 使用parted将文件系统分区调整为设备的最大大小:

    target:~$ parted /dev/mmcblk2 resizepart 2 100%
    Information: You may need to update /etc/fstab.
    
    target:~$ parted /dev/mmcblk2 print
    Model: MMC Q2J55L (sd/mmc)
    Disk /dev/mmcblk2: 7617MB
    Sector size (logical/physical): 512[ 1974.191657]  mmcblk2: p1 p2
    B/512B
    Partition Table: msdos
    Disk Flags:
    
    Number  Start   End     Size    Type     File system  Flags
     1      4194kB  72.4MB  68.2MB  primary  fat16        boot, lba
     2      72.4MB  7617MB  7545MB  primary  ext4
    
  • 将文件系统调整为新的分区大小:

    target:~$ resize2fs /dev/mmcblk2p2
    resize2fs 1.46.1 (9-Feb-2021)
    Filesystem at /dev/mmcblk2p2 is mounted on /; on-line resizing required
    [ 131.609512] EXT4-fs (mmcblk2p2): resizing filesystem
    from 454136 to 7367680 blocks
    old_desc_blocks = 4, new_desc_blocks = 57
    [ 131.970278] EXT4-fs (mmcblk2p2): resized filesystem to 7367680
    The filesystem on /dev/mmcblk2p2 is now 7367680 (1k) blocks long
    

在文件系统挂载时可以增加其大小。但您也可以从SD卡启动板,然后在eMMC分区未挂载时调整文件系统的大小。

7.5.5. 启用伪SLC模式

eMMC设备使用 MLC或TLC 来存储数据。与NAND Flash中使用的SLC相比,MLC或TLC在成本更低的情况下,可靠性较低且错误率较高。

如果您更喜欢可靠性而不是存储容量,可以启用伪SLC模式或SLC模式。这个方法采用了增强属性,该属性在JEDEC标准中有所描述,可以对设备的一个连续区域设置。JEDEC标准并未规定增强属性的实现细节和保证,这由芯片制造商自行决定。对于美光(Micron)芯片,增强属性提高了可靠性,但也将容量减半。

警告

在设备上启用增强属性时,所有数据将被丢失。

以下步骤展示了如何启用增强属性。

  • 首先使用以下命令获取eMMC设备的当前大小:

    target:~$ parted -m /dev/mmcblk2 unit B print
    

    你将收到:

    BYT;
    /dev/mmcblk2:63652757504B:sd/mmc:512:512:unknown:MMC S0J58X:;
    

    如您所见,该设备的容量为 63652757504 字节 = 60704 MiB。

  • 要获取启用伪SLC模式后的设备的大小,请使用:

    target:~$ mmc extcsd read /dev/mmcblk2 | grep ENH_SIZE_MULT -A 1
    

    例如:

    Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x000764
    i.e. 3719168 KiB
    --
    Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x000000
    i.e. 0 KiB
    

    这里的最大大小是3719168 KiB = 3632 MiB。

  • 现在,您可以通过输入以下命令为整个设备设置增强属性,例如 3719168 KiB:

    target:~$ mmc enh_area set -y 0 3719168 /dev/mmcblk2
    

    你将获得:

    Done setting ENH_USR area on /dev/mmcblk2
    setting OTP PARTITION_SETTING_COMPLETED!
    Setting OTP PARTITION_SETTING_COMPLETED on /dev/mmcblk2 SUCCESS
    Device power cycle needed for settings to take effect.
    Confirm that PARTITION_SETTING_COMPLETED bit is set using 'extcsd read' after power cycle
    
  • 为了确保新设置已生效,请关闭系统:

    target:~$ poweroff
    

    并进行上下电。建议您现在确认设置是否正确。

  • 首先,检查ENH_SIZE_MULT的值,它必须是3719168 KiB:

    target:~$ mmc extcsd read /dev/mmcblk2 | grep ENH_SIZE_MULT  -A 1
    

    您应该看到:

    Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x000764
    i.e. 3719168 KiB
    --
    Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x000764
    i.e. 3719168 KiB
    
  • 最后,检查设备的大小:

    target:~$ parted -m /dev/mmcblk2 unit B print
    BYT;
    /dev/mmcblk2:31742492672B:sd/mmc:512:512:unknown:MMC S0J58X:;
    

7.5.6. 擦除设备

可以直接擦除eMMC设备,而不是通过写零覆盖。eMMC块管理算法将擦除底层的MLC或TLC,或者将这些块标记为可丢弃。设备上的数据将丢失,并将被读取为零。

  • SD卡启动后执行:

    target:~$ blkdiscard -f --secure /dev/mmcblk2
    

    选项 --secure 确保命令在 eMMC 设备擦除所有块之前会等待。-f (强制) 选项强制擦写,当 eMMC 设备包含有效数据分区时需要使用-f选项。

小技巧

target:~$ dd if=/dev/zero of=/dev/mmcblk2 conv=fsync

该命令也会擦除设备上的所有信息,但这个命令不利于设备的磨损均衡,并且需要花费更长的时间!

7.5.7. eMMC Boot分区

eMMC设备包含四个不同的硬件分区:User分区、boot1分区、boot2分区和rpmb分区。

User分区在JEDEC标准中称为用户数据区,是主要的存储分区。分区boot1和boot2可以用于存放bootloader,并且更可靠。 i.MX 8M Plus 使用哪个分区加载bootloader由eMMC设备的引导配置控制。分区rpmb是一个小分区,只能通过受信任的机制访问。

此外,User分区可以分为四个自定义的一般用途分区。对此功能的解释不在本文件涵盖的范围。有关更多信息,请参阅JEDEC标准第7.2章分区管理。

小技巧

不要将eMMC分区与DOS、MBR或GPT分区表的分区混淆。

当前的PHYTEC BSP没有使用eMMC设备的额外分区功能。U-Boot被烧写到用户分区的开始位置。U-Boot环境被放置在U-Boot之后的固定位置。使用MBR分区表创建两个分区,一个是FAT32引导分区,另一个是ext4根文件系统分区。它们位于U-Boot和U-Boot环境之后。FAT32引导分区包含内核和设备树。

使用eMMC时,可以利用专用的boot分区备份存储bootloader。U-Boot环境仍然位于第一个分区之前的用户区。用户区仍然在出厂时包含bootloader。下面是一个示例,演示如何将bootloader烧写到两个启boot分区中的一个,并通过用户空间命令切换启动设备。

7.5.8. 通过用户空间命令

在主机上运行:

host:~$ scp imx-boot root@192.168.3.11:/tmp/

默认情况下,boot1和boot2分区是只读的。要从用户空间写入它们,您必须在sysfs中禁用force_ro。

要手动将bootloader写入eMMC boot分区,首先禁用写保护:

target:~$ echo 0 > /sys/block/mmcblk2boot0/force_ro
target:~$ echo 0 > /sys/block/mmcblk2boot1/force_ro

将bootloader写入eMMC boot分区:

target:~$ dd if=/tmp/imx-boot of=/dev/mmcblk2boot0
target:~$ dd if=/tmp/imx-boot of=/dev/mmcblk2boot1

下表是 i.MX 8M Plus SoC的偏移量:

SoC

User分区偏移量

Boot分区偏移量

eMMC设备

bootloader文件名

i.MX 8M Plus

32 kiB

0 kiB

/dev/mmcblk2

imx-boot

之后使用mmc工具从用户空间设置引导分区:

(对于 'boot0') :

target:~$ mmc bootpart enable 1 0 /dev/mmcblk2

(对于'boot1'):

target:~$ mmc bootpart enable 2 0 /dev/mmcblk2

要禁用从eMMC boot分区启动,只需输入以下命令:

target:~$ mmc bootpart enable 0 0 /dev/mmcblk2

返回到User分区启动:

target:~$ mmc bootpart enable 7 0 /dev/mmcblk2

7.5.9. 调整 ext4 根文件系统的大小

fdisk可以用来扩展根文件系统。这个例子适用于任何块设备,比如eMMC、SD卡或硬盘。

  • 获取当前设备大小:

    target:~$ fdisk -l /dev/mmcblk2
    
  • 输出如下:

    Disk /dev/mmcblk2: 7264 MB, 7616856064 bytes, 14876672 sectors 116224 cylinders, 4 heads, 32 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device       Boot StartCHS        EndCHS      StartLBA     EndLBA    Sectors   Size   Id Type
    /dev/mmcblk2p1 *    128,0,1       1023,3,32    16384       140779     124396   60.7M   c Win95 FAT32 (LBA)
    /dev/mmcblk2p2      1023,3,32     1023,3,32    141312      2192013    2050702  1001M  83 Linux
    
  • 使用fdisk删除并创建一个最大化使用设备容量的分区:

    target:~$ fdisk /dev/mmcblk2
    
    The number of cylinders for this disk is set to 116224.
    There is nothing wrong with that, but this is larger than 1024,
    and could in certain setups cause problems with:
    1) software that runs at boot time (e.g., old versions of LILO)
    2) booting and partitioning software from other OSs
       (e.g., DOS FDISK, OS/2 FDISK)
    
    Command (m for help): p
    Disk /dev/mmcblk2: 7264 MB, 7616856064 bytes, 14876672 sectors
    116224 cylinders, 4 heads, 32 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device       Boot   StartCHS        EndCHS      StartLBA     EndLBA    Sectors   Size   Id Type
    /dev/mmcblk2p1 *     128,0,1     1023,3,32         16384     140779     124396  60,7M    c Win95 FAT32 (LBA)
    /dev/mmcblk2p2     1023,3,32     1023,3,32        141312    2192013    2050702  1001M   83 Linux
    
    Command (m for help): d
    Partition number (1-4): 2
    
    Command (m for help): p
    Disk /dev/mmcblk2: 7264 MB, 7616856064 bytes, 14876672 sectors
    116224 cylinders, 4 heads, 32 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device       Boot StartCHS    EndCHS          StartLBA     EndLBA    Sectors  Size   Id Type
    /dev/mmcblk2p1 *  128,0,1     1023,3,32          16384     140779     124396  60.7M   c Win95 FAT32 (LBA)
    
    Command (m for help): n
    Partition type
       p   primary partition (1-4)
       e   extended
    p
    Partition number (1-4): 2
    First sector (32-14876671, default 32): 141456
    Last sector or +size{,K,M,G,T} (141456-14876671, default 14876671):
    Using default value 14876671
    
    Command (m for help): p
    Disk /dev/mmcblk2: 7264 MB, 7616856064 bytes, 14876672 sectors
    116224 cylinders, 4 heads, 32 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device       Boot StartCHS      EndCHS        StartLBA     EndLBA    Sectors  Size   Id Type
    /dev/mmcblk2p1 *   128,0,1      1023,3,32        16384     140779     124396  60.7M   c Win95 FAT32 (LBA)
    /dev/mmcblk2p2   1023,3,32      1023,3,32       141456   14876671   14735216  7194M  83 Linux
    

可以在文件系统挂载时修改文件系统的大小。这是一个在线调整大小的操作。但您也可以从SD卡启动,然后在eMMC分区未挂载时调整其文件系统的大小。此外,必须重启板子,以便读取新的分区表。

7.6. SPI主设备

i.MX 8M Plus 控制器包含一个 FlexSPI 和一个 ECSPI IP 核。FlexSPI 主控制器支持两个 SPI 通道,最多可连接 4 个设备。每个通道支持单通道/双通道/四通道/八通道模式的数据传输(1/2/4/8 条数据线)。ECSPI 控制器支持 3 个 SPI 接口,每个接口都有一个专用的CS(chip select)引脚。由于CS也可通过 GPIO 实现,因此每个通道上可以连接多个设备。

7.6.1. SPI NOR 烧写

phyCORE-i.MX 8M Plus 配备有一个 QSPI NOR Flash,该 Flash 连接到 i.MX 8M Plus 的 FlexSPI 接口。QSPI NOR Flash 可用于启动。有关烧写和启动模式设置的详细信息,请参见不同的章节。由于 SPI NOR Flash 的空间有限,因此仅可存储bootloader。默认情况下,内核、设备树和根文件系统来自 eMMC。

bootloader程序通过EEPROM数据检测是否安装了SPI Flash。如果没有安装SPI Flash,则在启动期间应用设备树overlay,通过扩展命令禁用SPI Flash设备树节点。如果没有可用的EEPROM数据,SPI NOR Flash节点将始终启用。有关更多信息,请参阅设备树overlay部分。

bootloader程序还可以通过内核的mtdparts启动参数修改设备树,将SPI MTD分区表传递给Linux。BSP中的默认分区布局设置为:

mtdparts=30bb0000.spi:3840k(u-boot),128k(env),128k(env_redund),-(none)

这是一个预定义的bootloader环境变量,可以在运行时更改。从Linux用户空间,可以通过/dev/mtd<N>设备访问NOR Flash分区,其中<N>是与要访问的NOR Flash分区相关联的MTD设备编号。要找到分区的正确MTD设备编号,请在目标上运行:

root@phyboard-pollux-imx8mp-3:~$ mtdinfo --all
Count of MTD devices:           4
Present MTD devices:            mtd0, mtd1, mtd2, mtd3
Sysfs interface supported:      yes

mtd0
Name:                           u-boot
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          60 (3932160 bytes, 3.7 MiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:0
Bad blocks are allowed:         false
Device is writable:             true

mtd1
Name:                           env
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          2 (131072 bytes, 128.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:2
Bad blocks are allowed:         false
Device is writable:             true

mtd2
Name:                           env_redund
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          2 (131072 bytes, 128.0 KiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:4
Bad blocks are allowed:         false
Device is writable:             true

mtd3
Name:                           none
Type:                           nor
Eraseblock size:                65536 bytes, 64.0 KiB
Amount of eraseblocks:          448 (29360128 bytes, 28.0 MiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:6
Bad blocks are allowed:         false
Device is writable:             true

它列出了所有MTD设备及其对应的分区名称。闪存节点在模块DTS中的SPI主节点内定义。SPI节点包含连接到此SPI总线的所有设备,在这种情况下只有SPI NOR Flash。

设备树中SPI主节点的定义可以在这里找到:

https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L76

7.7. GPIOs

phyBOARD-Pollux 具有一组专门用于GPIO的引脚。这些引脚直接连接到 i.MX 8M Plus 引脚,并被复用为 GPIO。它们可以直接在 Linux 用户空间中使用。处理器将其 GPIO 组织为5个GPIO组(GPIO1 – GPIO5),每个组包含 32 个GPIO。gpiochip0、gpiochip32、gpiochip64、gpiochip96 和 gpiochip128 是这些内部 i.MX 8M Plus GPIO 组 GPIO1 – GPIO5 的 sysfs 表示。

GPIO被标识为GPIO<X>_<Y>(例如:GPIO5_07)。<X>表示GPIO Bank,从1计数到5,而<Y>表示该Bank内的GPIO。<Y>从0计数到31(每个bank有32个GPIO)。

相比之下,Linux内核使用一个单一的整数来枚举系统中所有可用的GPIO。计算正确数字的公式是:

Linux GPIO number: <N> = (<X> - 1) * 32 + <Y>

从用户空间访问GPIO将使用libgpiod。它提供了一个库和工具,用于与Linux GPIO字符设备进行交互。以下是一些工具的用法示例:

  • 检测芯片上的gpiochips:

    target:~$ gpiodetect
    gpiochip0 [30200000.gpio] (32 lines)
    gpiochip1 [30210000.gpio] (32 lines)
    gpiochip2 [30220000.gpio] (32 lines)
    gpiochip3 [30230000.gpio] (32 lines)
    gpiochip4 [30240000.gpio] (32 lines)
    
  • 显示关于gpiochips的详细信息,包括它们的名称、consumer、方向、活动状态和附加flag:

    target:~$ gpioinfo -c gpiochip0
    
  • 读取GPIO的值(例如从gpiochip0的GPIO 20):

    target:~$ gpioget -c gpiochip0 20
    
  • 将gpiochip0上的GPIO 20的值设置为0并退出工具:

    target:~$ gpioset -z -c gpiochip0 20=0
    
  • gpioset的帮助文本显示了可能的选项:

    target:~$ gpioset --help
    Usage: gpioset [OPTIONS] <line=value>...
    
    Set values of GPIO lines.
    
    Lines are specified by name, or optionally by offset if the chip option
    is provided.
    Values may be '1' or '0', or equivalently 'active'/'inactive' or 'on'/'off'.
    
    The line output state is maintained until the process exits, but after that
    is not guaranteed.
    
    Options:
          --banner            display a banner on successful startup
      -b, --bias <bias>       specify the line bias
                      Possible values: 'pull-down', 'pull-up', 'disabled'.
                      (default is to leave bias unchanged)
          --by-name           treat lines as names even if they would parse as an offset
      -c, --chip <chip>       restrict scope to a particular chip
      -C, --consumer <name>   consumer name applied to requested lines (default is 'gpioset')
      -d, --drive <drive>     specify the line drive mode
                      Possible values: 'push-pull', 'open-drain', 'open-source'.
                      (default is 'push-pull')
      -h, --help              display this help and exit
      -l, --active-low        treat the line as active low
      -p, --hold-period <period>
                      the minimum time period to hold lines at the requested values
      -s, --strict            abort if requested line names are not unique
      -t, --toggle <period>[,period]...
                      toggle the line(s) after the specified period(s)
                      If the last period is non-zero then the sequence repeats.
          --unquoted  don't quote line names
      -v, --version           output version information and exit
      -z, --daemonize set values then detach from the controlling terminal
    
    Chips:
        A GPIO chip may be identified by number, name, or path.
        e.g. '0', 'gpiochip0', and '/dev/gpiochip0' all refer to the same chip.
    
    Periods:
        Periods are taken as milliseconds unless units are specified. e.g. 10us.
        Supported units are 's', 'ms', and 'us'.
    
    *Note*
        The state of a GPIO line controlled over the character device reverts to default
        when the last process referencing the file descriptor representing the device file exits.
        This means that it's wrong to run gpioset, have it exit and expect the line to continue
        being driven high or low. It may happen if given pin is floating but it must be interpreted
        as undefined behavior.
    

警告

某些GPIO用于特殊功能。在使用某个GPIO之前,请参考您板子的原理图或硬件手册,以确保该IO未被其他功能占用。

7.7.1. 通过sysfs访问GPIO

警告

通过sysfs访问GPIO已经过时了,我们建议使用libgpiod。

默认情况下不再支持通过sysfs访问GPIO。只有手动在内核配置中启用 CONFIG_GPIO_SYSFS 后才能支持。要在menuconfig中使 CONFIG_GPIO_SYSFS 可见,必须首先启用选项 CONFIG_EXPERT

您也可以将此选项添加到您在 Linux 内核源代码 arch/arm64/configs/ 目录下使用的 defconfig 中。例如,我们基于 NXP 的BSP版本,这个defconfig可以是 imx8_phytec_distro.config

..
CONFIG_EXPERT=y
CONFIG_GPIO_SYSFS=y
..

Otherwise you can create a new config fragment. This is described in our Yocto Reference Manual.

7.8. LED灯

如果有任何LED灯连接到GPIO管脚,您可以通过特定的LED驱动程序接口访问它们,而不是使用通用的GPIO接口(请参见GPIO部分)。您将通过 /sys/class/leds/ 而不是 /sys/class/gpio/ 来访问它们。LED的最大亮度可以从 max_brightness 文件中读取。brightness文件将设置LED的亮度(取值范围从0到max_brightness)。大多数LED硬件上不支持调整亮度,所以在所有非零亮度下都会点亮。

下面是一个简单的例子。

要获取所有可用的LED,请输入:

target:~$ ls /sys/class/leds
led-1@  led-2@  led-3@  mmc1::@  mmc2::@

这里的 LED 灯包括蓝色的 mmc、绿色的 心跳和红色的 emmc,它们都在 phyBOARD-Pollux 上。

  • 打开LED灯:

    target:~$ echo 255 > /sys/class/leds/led-1/brightness
    
  • 关闭LED:

    target:~$ echo 0 > /sys/class/leds/led-1/brightness
    

Device tree configuration for the User I/O configuration can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L255

7.9. I²C总线

该 i.MX 8M Plus 包含多个多主支持快速模式的 I²C模块。PHYTEC板提供了许多不同的I²C设备,这些设备连接到 i.MX 8M Plus 的I²C模块。 本节描述了我们 phyBOARD-Pollux 中集成的一些I²C设备的基本设备使用及其设备树(DT)表示。

i2c的设备树节点包含一些设置,例如时钟频率,用于设置总线频率,以及引脚控制设置,包括scl-gpios和sda-gpios,这些是用于总线恢复的备用引脚配置。

General I²C1 bus configuration (e.g. imx8mp-phycore-som.dtsi): https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L113

General I²C2 bus configuration (e.g. imx8mp-phyboard-pollux-rdk.dts) https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L239

7.10. EEPROM

在 phyCORE-i.MX8MP 上贴了一个 i2c 接口的 EEPROM 存储。它有两个地址。主 EEPROM 空间(总线:I2C-0 地址:0x51)可以通过 Linux 中的 sysfs 接口访问。主 EEPROM 的前 256 字节和 ID 页(总线:I2C-0 地址:0x59)用于板检测,不可修改。因此,ID 页不能通过 sysfs 接口访问。覆盖保留空间将导致启动问题。

备注

如果您删除了保留的EEPROM空间数据,请联系我们的支持团队!

7.10.1. phyCORE-i.MX8MP 上的I2C EEPROM

警告

EEPROM ID页面(总线:I2C-0 地址:0x59)和正常EEPROM区域的前256个字节(总线:I2C-0 地址:0x51)不可被擦除或修改。这将影响bootloader的行为。板子可能无法正确启动。

phyCORE-i.MX8MP SoM上的I2C EEPROM连接到I2C-0总线的I2C地址0x51。可以直接对该设备进行读写操作:

target:~$ hexdump -c /sys/class/i2c-dev/i2c-0/device/0-0051/eeprom

要读取并以十六进制打印 EEPROM 的前 1024 字节,请执行:

target:~$ dd if=/sys/class/i2c-dev/i2c-0/device/0-0051/eeprom bs=1 count=1024  | od -x

要用零填充4KiB的EEPROM(总线:I2C-0 地址:0x51),并保留EEPROM数据,请使用:

target:~$ dd if=/dev/zero of=/sys/class/i2c-dev/i2c-0/device/0-0051/eeprom seek=1 bs=256 count=15

7.10.2. EEPROM SoM 检测

在 phyCORE-i.MX8MP 上配置的I2C EEPROM具有一个可通过I2C地址0x59在i2c0上寻址的独立ID页面,以及一个可通过I2C地址0x51在i2c0上寻址的正常区域。PHYTEC使用这个32字节的数据区域来存储关于SoM的信息,包括PCB版本和配置。

在启动的早期阶段读取EEPROM数据。它用于选择正确的DDR RAM配置。这使得可以使用相同的bootloader镜像来支持不同的RAM大小,并自动选择正确的DTS overlay。

如果EEPROM ID页面数据和正常区域的前256个字节被删除,bootloader程序将回退到 phyCORE-i.MX8MP Kit RAM设置,即 2GiB RAM。

警告

EEPROM ID页面(总线:I2C-0 地址:0x59)和正常EEPROM区域的前256个字节(总线:I2C-0 地址:0x51)不可被擦除或修改。这将影响bootloader的行为。板子可能无法正确启动。

使用API修订版2数据格式烧写的核心板将在早期启动阶段打印出有关模块的信息。

DT representation, e.g. in phyCORE-i.MX 8M Plus file imx8mp-phycore-som.dtsi can be found in our PHYTEC git: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L201

7.11. RTC

RTC可以通过 /dev/rtc* 访问。由于PHYTEC板通常有多个RTC,因此可能会有多个RTC设备文件。

  • 要找到RTC设备的名称,可以通过以下方式读取其sysfs条目:

    target:~$ cat /sys/class/rtc/rtc*/name
    
  • 例如,你将得到:

    rtc-rv3028 0-0052
    snvs_rtc 30370000.snvs:snvs-rtc-lp
    

小技巧

这将列出所有实时时钟(RTC),包括非I²C接口的RTC。如果存在设备树/aliases条目,Linux会根据这些条目分配RTC设备ID。

日期和时间可以通过 hwclock 工具和date命令进行操作。要显示目标上设置的当前日期和时间:

target:~$ date
Thu Jan  1 00:01:26 UTC 1970

使用日期命令更改日期和时间。日期命令以以下语法设置时间:"YYYY-MM-DD hh:mm:ss (+|-)hh:mm":

target:~$ date -s "2022-03-02 11:15:00 +0100"
Wed Mar  2 10:15:00 UTC 2022

备注

您的时区(在此示例中为 +0100)可能会有所不同。

使用date命令并不会改变实时时钟(RTC)的时间和日期,因此如果我们重启开发板,这些更改将会被丢弃。要写入RTC,我们需要使用 hwclock 命令。使用 hwclock 工具将当前的日期和时间(通过date命令设置)写入RTC,然后重启开发板以检查更改是否已应用到RTC上:

target:~$ hwclock -w
target:~$ reboot
    .
    .
    .
target:~$ date
Wed Mar  2 10:34:06 UTC 2022

要从实时时钟(RTC)设置系统时间和日期,请使用:

target:~$ date
Thu Jan  1 01:00:02 UTC 1970
target:~$ hwclock -s
target:~$ date
Wed Mar  2 10:45:01 UTC 2022

7.11.1. RTC唤醒alarm

可以从实时时钟(RTC)发出中断以唤醒系统。该格式使用Unix纪元时间,即自1970年1月1日UTC午夜以来的秒数。要在从挂起到RAM状态后的4分钟唤醒系统,请输入:

target:~$ echo "+240" > /sys/class/rtc/rtc0/wakealarm
target:~$ echo mem > /sys/power/state

备注

内部唤醒alarm时间将被向上舍入到下一个分钟,因为alarm功能不支持秒。

7.11.2. RTC参数

实时时钟(RTC)具有一些功能,可以通过 hwclock 工具进行读取和设置。

  • 我们可以通过以下方式检查RTC支持的功能:

    target:~$ hwclock --param-get features
    The RTC parameter 0x0 is set to 0x71.
    

    这个值的含义在内核中进行了编码,每个位的定义为:

    #define RTC_FEATURE_ALARM               0
    #define RTC_FEATURE_ALARM_RES_MINUTE    1
    #define RTC_FEATURE_NEED_WEEK_DAY       2
    #define RTC_FEATURE_ALARM_RES_2S        3
    #define RTC_FEATURE_UPDATE_INTERRUPT    4
    #define RTC_FEATURE_CORRECTION          5
    #define RTC_FEATURE_BACKUP_SWITCH_MODE  6
    #define RTC_FEATURE_ALARM_WAKEUP_ONLY   7
    #define RTC_FEATURE_CNT                 8
    
  • 我们可以通过以下方式检查RTC BSM(Backup Switchover Mode 备份切换模式):

    target:~$ hwclock --param-get bsm
    The RTC parameter 0x2 is set to 0x1.
    
  • 我们可以通过以下方式设置RTC BSM:

    target:~$ hwclock --param-set bsm=0x2
    The RTC parameter 0x2 will be set to 0x2.
    

    BSM位的定义为:

    #define RTC_BSM_DISABLED   0
    #define RTC_BSM_DIRECT     1
    #define RTC_BSM_LEVEL      2
    #define RTC_BSM_STANDBY    3
    

    小技巧

    您应该将BSM模式设置为DSM或LSM,以便在初始电源不可用时,RTC可以切换到备用电源。请查看 RV-3028 RTC的Datasheet,以了解LSM(电平切换模式)和DSM(直接切换模式)这两个定义的工作模式。

DT representation for I²C RTCs: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi#L208

7.12. USB主控制器

i.MX 8M Plus SoC的USB控制器为众多消费类便携设备提供了一种低成本的连接解决方案,实现USB设备之间的数据传输,传输速度可达4 Gbit/s(超高速'SS')。USB子系统具有两个独立的USB控制器。这两个控制器都能够作为USBDevice或USB Host使用。每个核心都连接到一个USB 3.0物理层(PHY)。

BSP支持大容量存储设备(优盘)和键盘。其他与USB相关的设备驱动程序必须根据需要在内核配置中启用。由于udev,所有连接的存储设备都会获得唯一的ID,并可以在 /dev/disk/by-id 中找到。这些ID可以在 /etc/fstab 中用于以不同的方式挂载不同的USB存储设备。

DT representation for USB Host: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L380

7.13. CAN FD

phyBOARD-Pollux 支持两个 flexCAN 接口,支持 CAN FD。这些接口支持 Linux 标准 CAN 框架,该框架建立在 Linux 网络层之上。使用这个框架,CAN 接口表现得像普通的 Linux 网络设备,同时具备一些 CAN 特有的附加功能。更多信息可以在 Linux 内核文档中找到:https://www.kernel.org/doc/html/latest/networking/can.html

  • 使用:

    target:~$ ip link
    

    查看接口的状态。两个CAN接口显示为can0和can1。

  • 要获取有关can0的信息,例如比特率和错误计数器,请输入:

    target:~$ ip -d -s link show can0
    

    can0的信息将如下所示:

    2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
        link/can  promiscuity 0 minmtu 0 maxmtu 0
        can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
              bitrate 500000 sample-point 0.875
              tq 50 prop-seg 17 phase-seg1 17 phase-seg2 5 sjw 1
              mcp25xxfd: tseg1 2..256 tseg2 1..128 sjw 1..128 brp 1..256 brp-inc 1
              mcp25xxfd: dtseg1 1..32 dtseg2 1..16 dsjw 1..16 dbrp 1..256 dbrp-inc 1
              clock 20000000
              re-started bus-errors arbit-lost error-warn error-pass bus-off
              0          0          0          0          0          0         numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
        RX: bytes  packets  errors  dropped overrun mcast
        0          0        0       0       0       0
        TX: bytes  packets  errors  dropped carrier collsns
        0          0        0       0       0       0
    

输出包含一组标准参数,这些参数也适用于以太网接口,因此并非所有参数对于CAN都是相关的(例如MAC地址)。以下输出参数包含有用的信息:

can0

接口名称

NOARP

CAN无法使用ARP协议

MTU

最大传输单元

RX packets

接收的数据包数量

TX packets

发送的数据包数量

RX bytes

接收字节数

TX bytes

发送字节数

errors...

总线错误统计信息

CAN配置是在systemd配置文件 /lib/systemd/network/can0.network 中完成的。为了持久化更改(例如,默认比特率),请在BSP中更改根文件系统下的 ./meta-ampliphy/recipes-core/systemd/systemd-conf/can0.network 中的配置,并重新编译根文件系统。

[Match]
Name=can0

[Can]
BitRate=500000

比特率也可以手动更改,例如,设置为灵活比特率(flexible bitrate):

target:~$ ip link set can0 down
target:~$ ip link set can0 txqueuelen 10 up type can bitrate 500000 sample-point 0.75 dbitrate 4000000 dsample-point 0.8 fd on

您可以使用cansend发送消息,或使用candump接收消息:

target:~$ cansend can0 123#45.67
target:~$ candump can0

要生成用于测试目的的随机CAN流量,请使用cangen:

target:~$ cangen

cansend --helpcandump --help 提供了关于选项和用法的帮助信息。

警告

mcp2518fd SPI到CAN FD只支持从125kB/s开始的波特率。可以选择更慢的速率,但可能无法正常工作。

Device Tree CAN configuration of imx8mp-phyboard-pollux-rdk.dts: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L203

7.14. PCIe

phyCORE-i.MX 8M Plus 具有一个 Mini-PCIe 插槽。一般来说,PCIe 会自动检测总线上的新设备。在连接设备并启动系统后,您可以使用命令 lspci 查看所有被识别的 PCIe 设备。

  • 输入:

    target:~$ lspci -v
    
  • 你将收到:

    00:00.0 PCI bridge: Synopsys, Inc. Device abcd (rev 01) (prog-if 00 [Normal decode])
            Flags: bus master, fast devsel, latency 0, IRQ 218
            Memory at 18000000 (64-bit, non-prefetchable) [size=1M]
            Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
            I/O behind bridge: None
            Memory behind bridge: 18100000-181fffff [size=1M]
            Prefetchable memory behind bridge: None
            [virtual] Expansion ROM at 18200000 [disabled] [size=64K]
            Capabilities: [40] Power Management version 3
            Capabilities: [50] MSI: Enable+ Count=1/1 Maskable+ 64bit+
            Capabilities: [70] Express Root Port (Slot-), MSI 00
            Capabilities: [100] Advanced Error Reporting
            Capabilities: [148] L1 PM Substates
            Kernel driver in use: dwc3-haps
    
    01:00.0 Network controller: Intel Corporation WiFi Link 5100
            Subsystem: Intel Corporation WiFi Link 5100 AGN
            Flags: fast devsel
            Memory at 18100000 (64-bit, non-prefetchable) [disabled] [size=8K]
            Capabilities: [c8] Power Management version 3
            Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+
            Capabilities: [e0] Express Endpoint, MSI 00
            Capabilities: [100] Advanced Error Reporting
            Capabilities: [140] Device Serial Number 00-24-d6-ff-ff-84-0d-1e
            Kernel modules: iwlwifi
    

在这个例子中,PCIe设备是 英特尔 WiFi Link 5100

对于PCIe设备,您必须在内核配置中启用正确的驱动程序。例如,这款WLAN卡是由英特尔制造的。必须启用的驱动程序选项名为 CONFIG_IWLWIFI ,可以在内核配置中的 Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate 下找到。

  • In order to activate the driver, follow the instructions from our Yocto Reference Manual.

    • linux-imx的表示为:virtual/kernel

对于某些设备,如WLAN卡,需要额外的二进制固件文件。这些固件文件必须放置在 /lib/firmware/ 目录中,才能使用该设备。

  • 输入:

    host:~$ scp -r <firmware> root@192.168.3.11:/lib/firmware
    
  • 例如,如果您尝试启动网络接口:

    target:~$ ip link set up wlp1s0
    
  • 您将在串口控制台上获得以下输出:

    [   58.682104] iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
    [   58.690822] iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
    [   58.696577] iwlwifi 0000:01:00.0: Radio type=0x1-0x2-0x0
    [   58.831022] iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
    [   58.839679] iwlwifi 0000:01:00.0: L1 Disabled - LTR Disabled
    [   58.845435] iwlwifi 0000:01:00.0: Radio type=0x1-0x2-0x0
    [   58.902797] IPv6: ADDRCONF(NETDEV_UP): wlp1s0: link is not ready
    

小技巧

某些PCIe设备,例如以太网卡,即使没有从 /lib/firmware/ 加载固件文件,也可能正常工作,而你收到了如上输出第一行所示的错误消息。这是因为一些制造商在板卡本身提供了固件作为后备。在这种情况下,设备的行为和输出在很大程度上依赖于制造商的固件。

Device Tree PCIe configuration of imx8mp-phyboard-pollux-rdk.dts: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L345

7.15. 音频

支持的播放设备包括HDMI和PEB-AV-10连接器上的TI TLV320AIC3007音频编解码器(CODEC)IC。在AV连接器上,有一个符合OMTP标准的3.5mm耳机插孔和一个8针排针。8针排针包含单声道扬声器、耳机和line-in信号。

备注

使用PEB-AV-10连接器进行显示输出时,不支持通过HDMI作为音频输出。音频输出设备必须与视频输出设备匹配。

要检查您的声卡驱动程序是否正确加载以及设备名称,请输入以下命令以查看播放设备:

target:~$ aplay -L

或输入录音设备:

target:~$ arecord -L

7.15.1. Alsamixer

要检查声卡的功能,请输入:

target:~$ alsamixer

您应该会看到很多选项,因为音频IC具有许多可以测试的功能。通过SSH打开alsamixer的图形界面比通过调试串口打开更易于使用。所有混音点都有单声道或立体声增益控制。"MM"表示该功能被静音(左右输出均为静音),可以通过按' m '切换。您还可以通过按' < ' 左和 ' > '切换右声道输出。使用 tab 键,您可以在播放和录音控制之间切换。

7.15.2. 恢复默认音量

一些默认设置存储在 /var/lib/alsa/asound.state 中。您可以使用以下命令保存当前的alsa设置:

target:~$ alsactl --file </path/to/filename> store

您可以通过以下方式恢复已保存的alsa设置:

target:~$ alsactl --file </path/to/filename> restore

7.15.3. ALSA配置

我们的BSP附带一个ALSA配置文件 /etc/asound.conf

ALSA配置文件可以根据需要进行编辑或删除,它并不是ALSA正常工作所必需的。

target:~$ vi /etc/asound.conf

要将PEB-AV-10设置为输出,请将 playback.pcm 从 "dummy" 设置为 "pebav10":

[...]

pcm.asymed {
        type asym
        playback.pcm "pebav10"
        capture.pcm "dsnoop"
}

[...]

如果听不到声音,请将播放设备更改为软件音量控制播放设备,将 playback.pcm 设置为相应的软音量播放设备,例如“softvol_pebav10”。使用alsamixer控制来调整音量级别。

[...]

pcm.asymed {
        type asym
        playback.pcm "softvol_pebav10"
        capture.pcm "dsnoop"
}

[...]

7.15.4. PulseAudio 配置

对于使用 Pulseaudio 的应用程序,请检查可用的音频输出设备:

target:~$ pactl list short sinks

要选择输出设备,请输入:

target:~$ pactl set-default-sink <sink_number>

7.15.5. 播放

运行speaker-test以检查播放功能:

target:~$ speaker-test -c 2 -t wav

要播放简单的音频流,您可以使用aplay。例如,要播放ALSA测试音频:

target:~$ aplay /usr/share/sounds/alsa/*

要播放其他格式,例如mp3,您可以使用Gstreamer:

target:~$ gst-launch-1.0 playbin uri=file:/path/to/file.mp3

7.15.6. 录音

arecord 是一个命令行工具,用于录制音频流,默认输入源为线路输入。要选择不同的音频源,可以使用 alsamixer。例如,打开 右侧 PGA 混音器 Mic3R左侧 PGA 混音器 Mic3R,以便通过 3.5mm 插孔录制来自 TLV320 编解码器的麦克风输入音频。

target:~$ amixer -c "sndpebav10" sset 'Left PGA Mixer Mic3R' on
target:~$ amixer -c "sndpebav10" sset 'Right PGA Mixer Mic3R' on
target:~$ arecord -t wav -c 2 -r 44100 -f S16_LE test.wav

提示

由于播放和录音共享硬件接口,因此无法在同时进行播放和录音操作时使用不同的采样率和格式。

Device Tree Audio configuration: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtso#L58

7.16. 视频

7.16.1. 视频与Gstreamer

默认情况下,BSP安装了一个示例视频,路径为 /usr/share/qtphy/videos/ 。可以使用以下命令之一开始视频播放:

target:~$ gst-launch-1.0 playbin uri=file:///usr/share/qtphy/videos/caminandes_3_llamigos_720p_vp9.webm
  • 或者:

target:~$ gst-launch-1.0 -v filesrc location=/usr/share/qtphy/videos/caminandes_3_llamigos_720p_vp9.webm ! decodebin name=decoder decoder. ! videoconvert ! waylandsink
  • 或者:

target:~$ gst-play-1.0 /usr/share/qtphy/videos/caminandes_3_llamigos_720p_vp9.webm --videosink waylandsink

7.17. 显示

该 phyBOARD-Pollux 支持多达3种不同的显示输出。可以同时使用两种。下表显示了不同接口所需的扩展板和设备树overlay。

接口

扩展板

设备树overlay

HDMI

phyBOARD-Pollux

不需要overlay(默认启用)

LVDS0

PEB-AV-10

imx8mp-phyboard-pollux-peb-av-10.dtbo (默认加载)

LVDS1

phyBOARD-Pollux

如果使用PEB-AV-10 overlay,则禁用

备注

  • 在更改Weston输出时,请确保音频输出也相匹配。

  • LVDS0 (使用PEB-AV-10扩展) 和 LVDS1 (板载) 不能同时使用。

HDMI在设备树中始终启用。其他接口可以通过设备树overlay进行启用。

默认启用的接口是HDMI和LVDS0(PEB-AV-010)。我们的 PEB-AV-10 支持10英寸edt,etml1010g0dka显示屏。

备注

当前的显示驱动程序将连接到LVDS的LCD的像素时钟限制为74.25MHz(或其分频)。如果这满足不了您的需求,请联系支持团队以获得进一步的帮助。

7.17.1. Weston 配置

为了让Weston正确的显示,需要进行正确的配置。这将在/etc/xdg/weston/weston.ini中完成。

7.17.1.1. 单一显示器

在我们的BSP中,默认的Weston输出设置为HDMI。

[output]
name=HDMI-A-1
mode=preferred

[output]
name=LVDS-1
mode=off

当使用LVDS0(PEB-AV-10)作为输出时,将HDMI-A-1的输出模式设置为off,将LVDS-1的输出模式设置为current。

[output]
name=HDMI-A-1
mode=off

[output]
name=LVDS-1
mode=current

如果您想使用LVDS1(板载),则需要去掉overlay。请从bootenv.txt中移除imx8mp-phyboard-pollux-peb-av-xxx.dtbo。

7.17.1.2. 双显示器

备注

对于双显示和三显示输出,您无法同时使用LVDS1(板载)和HDMI。

在HDMI和LVDS0(PEB-AV-10)的双屏模式下进行双显示时,两个模式必须设置为:

[output]
name=HDMI-A-1
mode=preferred

[output]
name=LVDS-1
mode=current

7.17.2. Qt Demo

使用 phytec-qt6demo-image 时,Weston会在启动时启动。我们的Qt6 DEMO应用程序名为“qtphy”,可以通过以下方式停止:

target:~$ systemctl stop qtphy
  • 要重新开始Demo,请运行:

    target:~$ systemctl start qtphy
    
  • 要禁用Demo的自动启动,请运行:

    target:~$ systemctl disable qtphy
    
  • 要启用Demo的自动启动,请运行:

    target:~$ systemctl enable qtphy
    
  • Weston可以通过以下方式停止:

    target:~$ systemctl stop weston
    

备注

在关闭Weston之前,必须先关闭Qt Demo。

7.17.3. 背光控制

如果LCD连接到PHYTEC开发板,可以通过Linux内核的sysfs接口控制其背光。系统中所有可用的背光设备可以在文件夹/sys/class/backlight中找到。读取相应的文件并向其写入数据可以控制背光。

备注

一些具有多显示的开发板在 /sys/class/backlight 有多个背光控制。比如:backlight0和backlight1

  • 例如,要获取最大亮度级别(max_brightness),请执行:

    target:~$ cat /sys/class/backlight/backlight/max_brightness
    

    有效的亮度值范围是 0 到 <max_brightness>。

  • 要获取当前亮度级别,请输入:

    target:~$ cat /sys/class/backlight/backlight/brightness
    
  • 写入文件brightness以更改亮度:

    target:~$ echo 0 > /sys/class/backlight/backlight/brightness
    

    例如,关闭背光。

    有关所有文件的文档,请参见 https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-backlight

Device tree description of LVDS-1 and HDMI can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L294 https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L218

The device tree of LVDS-0 on PEB-AV-10 can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtso#L133

7.18. 电源管理

7.18.1. CPU核心频率调节

i.MX 8M Plus SoC中的CPU能够调整时钟频率和电压。这用于在不需要CPU的全部性能时节省电力。调整频率和电压被称为“动态电压和频率调整”(DVFS)。i.MX 8M Plus BSP支持DVFS功能。Linux内核提供了一个DVFS框架,允许每个CPU核心设置最小或最大频率和一个管理其运行的governor。根据使用的 i.MX 8 型号,支持几种不同的频率。

小技巧

尽管DVFS框架为每个CPU核心提供了频率设置,但一个CPU核心的频率更改会影响其他CPU核心。因此,所有CPU核心始终共享相同的DVFS设置。每个核心的单独DVFS设置是不可能的。

  • 要获取完整列表,请输入:

    target:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
    

    例如 i.MX 8MPlus CPU,最高可达约 1.6 GHz,则结果将是:

    1200000 1600000
    
  • 要查询当前的频率输入:

    target:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
    

governor 会根据它们的目标自动选择这些频率中的一个。

  • 列出所有可用的 governor,使用以下命令:

    target:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
    

    结果是:

    conservative ondemand userspace powersave performance schedutil
    
  • conservative governor 与 ondemand governor 非常相似。只是它的行为有所不同,它会更保守地增减CPU速度,而不是在CPU有任何负载的瞬间就跳到最大速度。

  • ondemand (默认)根据当前系统负载在可能的CPU核心频率之间切换。当系统负载超过特定值时,它会立即提高CPU核心频率。

  • powersave 始终选择最低的CPU核心频率。

  • performance 始终选择最高的CPU核心频率。

  • userspace 允许以root身份运行的用户或用户空间程序设置特定频率(例如,设置为1600000)。输入:

  • 要查询当前的 governor,请输入:

    target:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

    您通常会得到:

    ondemand
    
  • 切换到另一个governor(例如,userspace)可以通过以下方式完成:

    target:~$ echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    
  • 现在你可以设置频率:

    target:~$ echo 1600000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
    

有关governor的更详细信息,请参阅Linux内核代码库中的Linux内核文档,路径为 Documentation/admin-guide/pm/cpufreq.rst

7.18.2. CPU核心管理

该 i.MX 8M Plus SoC 芯片上可以有多个处理器核心。例如,该 i.MX 8M Plus 具有 4 个 ARM 核心,可以在运行时单独开启和关闭。

  • 要查看系统中所有可用的核心,请执行:

    target:~$ ls /sys/devices/system/cpu  -1
    
  • 这将显示,例如:

    cpu0    cpu1   cpu2   cpu3   cpufreq
    [...]
    

    这里系统有四个处理器核心。默认情况下,系统中所有可用的核心都被启用,以获得最佳性能。

  • 要关闭某个核,请执行:

    target:~$ echo 0 > /sys/devices/system/cpu/cpu3/online
    

    作为确认,您将看到:

    [  110.505012] psci: CPU3 killed
    

    现在核心已关闭电源,并且该核心上不再安排任何进程。

  • 您可以使用 top 命令查看核心和进程的图形概览:

    target:~$ htop
    
  • 要重新启用核心,请执行:

    target:~$ echo 1 > /sys/devices/system/cpu/cpu3/online
    

7.18.3. 挂起到RAM

phyCORE-i.MX8MP 支持基本的挂起和恢复。可以使用不同的唤醒源。挂起/恢复可以通过以下方式实现:

target:~$ echo mem > /sys/power/state
#resume with pressing on/off button

要通过串行控制台唤醒,请运行

target:~$ echo enabled > /sys/class/tty/ttymxc0/power/wakeup
target:~$ echo mem > /sys/power/state

7.19. 热管理

7.19.1. U-Boot

之前U-Boot中的温度控制不够理想。现在,U-Boot增加了温度关机功能,以防止在启动过程中板子过热。关机发生的温度与内核中的温度一致。

当前温度的各个温度范围在启动日志中显示:

CPU:   Industrial temperature grade (-40C to 105C) at 33C

7.19.2. 内核

Linux内核集成了热管理功能,能够监测芯片(SoC)温度,降低CPU频率,控制风扇,通知其他驱动程序减少功耗,并在最坏的情况下关闭系统(https://www.kernel.org/doc/Documentation/thermal/sysfs-api.txt)。

本节描述了如何在 i.MX 8M Plus SoC 平台上使用热管理内核 API。 i.MX 8 具有用于 SoC 的内部温度传感器。

  • 当前温度可以以毫摄氏度为单位读取:

    target:~$ cat /sys/class/thermal/thermal_zone0/temp
    
  • 例如,你将得到:

    49000
    

imx_thermal内核驱动注册了两个触发点。这些触发点根据CPU型号的不同而有所不同。主要区分工业版和商业版。

商业

工业

被动(警告)

85°C

95°C

严重(关机)

90°C

100°C

(请查看内核 sysfs 文件夹 /sys/class/thermal/thermal_zone0/

内核热管理使用这些触发点来触发事件并实施冷却措施。内核中可用的热政策(也称为thermal governor)包括:Step Wise、Fair Share、Bang Bang和Userspace。BSP中使用的默认策略是Step Wise。如果sysfs文件temp中的SoC温度值高于 trip_point_0 ,则CPU频率将设置为最低CPU频率。当SoC温度降到 trip_point_0 以下时,限制将被解除。

备注

由于我们安装了不同温度等级的CPU,因此热触发点的实际值可能会有所不同。

7.19.3. GPIO风扇

备注

Starting with BSP-Yocto-i.MX8MP-PD22.1.1 we have to switch from PWM fan to GPIO fan due to availability. The PWM fan will not be supported anymore and will not function with the new release.

一个GPIO控制的风扇可以连接到 phyBOARD-Pollux-i.MX 8M Plus。该SoC包含一个温度传感器,该传感器被用于热频率调节。风扇无法通过内核进行控制。我们使用lmsensors和hwmon来实现这一点。lmsensors定期读取温度,并在可配置的阈值下启用或禁用风扇。对于 phyBOARD-Pollux-i.MX 8M Plus,这个阈值是60°C。

设置可以在配置文件中进行配置:

/etc/fancontrol

风扇控制在启动时由systemd服务启动。可以通过以下方式禁用它:

target:~$ systemctl disable fancontrol

The device tree description of GPIO Fan can be found here: https://github.com/phytec/linux-phytec-imx/tree/v6.6.23-2.0.0-phy10/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts#L35

7.20. 看门狗

PHYTEC i.MX 8M Plus 模块包含一个硬件看门狗,当系统挂起时能够重置开发板。看门狗在 U-Boot 中默认启动,超时时间为 60 秒。因此,即使在早期内核启动过程中,看门狗也已经开始运行。Linux 内核驱动程序控制看门狗,并确保它有被踢到。本节将解释如何使用 systemd 在 Linux 中配置看门狗,以避免系统挂起和重启期间的情况。

7.20.1. Systemd中的看门狗支持

Systemd 从版本 183 开始支持硬件看门狗。

  • 要启用看门狗支持,需要通过启用选项来配置 /etc/systemd/ 中的文件system.conf文件:

    RuntimeWatchdogSec=60s
    ShutdownWatchdogSec=10min
    

RuntimeWatchdogSec 定义了看门狗的超时时间,而 ShutdownWatchdogSec 定义了系统重启时的超时时间。有关 systemd 下硬件看门狗的更多详细信息,请访问 http://0pointer.de/blog/projects/watchdog.html。更改将在重启后生效,或者运行:

target:~$  systemctl daemon-reload

7.21. snvs电源按键

连接到开关按钮的 X_ONOFF 引脚可以长按以触发关机,而无需软件干预,或用于唤醒系统以退出挂起状态。使用 snvs_pwrkey 驱动程序时,当按下按钮时,KEY_POWER 事件也会报告给用户空间。默认情况下,systemd 被配置为忽略此类事件。关机而无需软件干预的功能以及从挂起状态唤醒的功能未被配置。可以在 /etc/systemd/logind.conf 中配置按下开/关按钮时通过 systemd 触发关机,配置方法如下:

HandlePowerKey=poweroff

7.22. NPU

i.MX 8M Plus SoC包含一个高达2.3 TOPS的人工智能运算加速器。有关NPU的信息,请参考我们最新的phyCORE-i.MX 8M Plus AI套件指南,该指南可以在phyCORE-i.MX 8M Plus 下载部分找到:L-1015e.A1 phyCORE-i.MX 8M Plus AI Kit Guide

7.23. ISP

i.MX 8M Plus SoC包含一个图像信号处理器(ISP)。有关更多信息,请参阅|sbc| i.MX 8M Plus 文档中的使用ISP部分。

7.24. 片上一次性可编程控制器 (OCOTP_CTRL) - eFuse

该 i.MX 8M Plus 提供一次性可编程fuse,用于存储信息,例如 MAC 地址、启动配置和其他永久设置(在 i.MX 8M Plus reference manual中称为“片上 OTP 控制器 (OCOTP_CTRL)”)。以下列表摘自 i.MX 8M Plus reference manual,包括 OCOTP_CTRL 中的一些有用寄存器(基地址为0x30350000):

名称

Bank

内存偏移量为0x30350000

描述

OCOTP_MAC_ADDR0

9

0

0x640

包含ENET0 MAC地址的低32位

OCOTP_MAC_ADDR1

9

1

0x650

包含ENET0 MAC地址的高16位和ENET1 MAC地址的低16位

OCOTP_MAC_ADDR2

9

2

0x660

包含 ENET1 MAC 地址的高 32 位

关于OCOTP_CTRL中的fuse与启动配置之间的完整列表和详细映射,请参阅 i.MX 8M Plus Security Reference Manual中的 "Fuse Map" 部分。

7.24.1. 在uBoot中读取fuse的值

您可以使用内存映射的shadow寄存器读取fuse寄存器。要计算内存地址,请使用以下公式计算:

OCOTP_MAC_ADDR:

u-boot=> fuse read 9 0

7.24.2. 在Linux中读取fuse值

要访问Linux中的fuse内容,NXP提供了NVMEM_IMX_OCOTP模块。所有内存映射的shadow寄存器的fuse内容可以通过sysfs访问:

target:~$ hexdump /sys/devices/platform/soc@0/30000000.bus/30350000.efuse/imx-ocotp0/nvmem

8. i.MX 8M Plus M7 Core

除了Cortex-A53核心外,SoC中还集成了一个Cortex-M7 Core 作为MCU。我们的Yocto-Linux-BSP在A53核心上运行,而 M7 Core 可以作为辅助CPU,用于使用裸机或RTOS固件执行额外任务。两种核心都可以访问相同的外设,因此外设的使用需要在 M7 Core 的固件或Linux操作系统的设备树中进行限制。本节将描述如何编译固件示例以及如何在 phyBOARD-Pollux 上运行它们。

phyBOARD-Pollux 目前由 NXP MCUXpresso SDK 和 Zephyr 项目支持。本节仅描述 NXP MCUXpresso SDK,因为目前 MCUXpresso SDK 支持的功能更多。

如果您想在Zephyr项目中使用 M7 Core ,请参考Zephyr项目文档:

8.1. 获取固件示例

固件可以使用NXP MCUxpresso SDK和兼容的编译工具链通过命令行工具进行编译。

8.1.1. 获取源代码

MCUX SDK以及 i.MX 8M Plus 的示例可以从PHYTEC的GitHub页面获取:

  1. 通过west初始化MCUX SDK:

    host:~$ west init -m https://github.com/phytec/mcux-sdk/ --mr <VERSION> mcuxsdk
    

    这将创建一个 mcuxsdk 目录,并在其中包含 mcux-sdk 仓库。mcux-sdk-phytec-examples 仓库将自动克隆到 mcuxsdk 目录中。给定的参数 <VERSION> 是 mcux-sdk 仓库的分支名称,代表 MCUX SDK 版本。要获取最新的测试版本,您可以使用 2.13.0。

    备注

    west 是一个仓库管理工具,也是 Zephyr 项目的一部分。要安装 west,您可以使用 pip。在这个示例中,west 被安装在一个 Python 虚拟环境中:

    host:~$ sudo apt install python3-venv python3-pip
    host:~$ python3 -m venv west-env
    host:~$ source west-env/bin/activate
    (west-env) host:~$ pip3 install west
    
  2. 更新依赖项:

    host:~$ cd mcuxsdk
    host:~/mcuxsdk$ west update
    

    目录 examples-phytec 包含了所有移植并测试过的示例,适用于 phyBOARD-Pollux 和版本为 2.13.0 的 MCUX。

    要编译固件,需要一个编译器工具链和make/cmake。GNU ARM 嵌入式工具链可能在您的主机linux发行版的仓库中可用,例如Ubuntu。

    host:~$ sudo apt install gcc-arm-none-eabi binutils-arm-none-eabi make cmake
    

    编译器工具链也可以直接从 https://developer.arm.com/ 获取。在解压缩文件后,必须将 ARMGCC_DIR 添加到环境变量中,例如,对于位于主目录中的 ARM toolchain 10-2020-q4-major 版本:

    host:~$ export ARMGCC_DIR=~/gcc-arm-none-eabi-10-2020-q4-major
    

8.1.2. 编译固件

要编译PHYTEC示例,需要先设置环境

host:~/mcuxsdk$ source scripts/setenv

编译固件的脚本位于 <sdk-directory>/phytec-mcux-boards/phyboard-pollux/<example_category>/<example>/armgcc。每个可运行的内存位置都有相应的编译脚本,例如:

host:~$ ./build_release.sh

要编译运行在 M7 Core 的 TCM 上的固件。输出将放置在 armgcc 目录下的 release/ 中。.bin 文件可以在 U-Boot 中运行,而 .elf 文件可以在 Linux 中运行。

要编译在DRAM上运行的固件,请运行脚本build_ddr_release。例如。

host:~$ ./build_ddr_release.sh

输出将放置在armgcc目录下的ddr_release/中。.bin文件可以在U-Boot中运行,而.elf文件可以在Linux中运行。

8.2. 运行 M7 Core 示例

有两种方法可以运行 M7 Core 的固件,在Linux中使用Remoteproc以及在U-Boot。

要接收调试信息,请在您的主机PC上启动您喜欢的终端软件(例如Minicom、Tio或Tera Term),并将其配置为115200波特率、8个数据位、无奇偶校验和1个停止位(8n1),且不使用握手。

一旦Micro USB电缆连接到 phyBOARD-Pollux 上的USB调试端口,就会注册两个ttyUSB设备。一个打印来自A53核心的调试UART的消息,另一个打印来自 M7 Core 的调试UART的消息。

8.2.1. 从U-Boot运行示例

要使用bootloader U-Boot加载固件,可以使用bootaux命令:

  1. 准备一张烧写了BSP镜像的SD卡

  2. 将生成的 .bin 文件复制到 SD 卡的第一个分区

  3. 通过按任意键停止自动启动

  4. 根据固件类型输入命令:

对于在 M7 Core 的TCM中运行的固件:

u-boot=> fatload mmc 1:1 0x48000000 firmware.bin;cp.b 0x48000000 0x7e0000 20000;
u-boot=> bootaux 0x7e0000
## Starting auxiliary core stack = 0x20020000, pc = 0x000004CD...

用于在DRAM中运行的固件:

u-boot=> fatload mmc 1:1 0x80000000 firmware.bin
u-boot=> dcache flush
u-boot=> bootaux 0x80000000
## Starting auxiliary core stack = 0x80400000, pc = 0x80000539...

程序的输出应显示在 M7 Core 的调试UART上。

8.2.2. 通过Remoteproc在Linux上运行示例

Remoteproc是一个模块,允许您在运行时从Linux控制 M7 Core 。可以加载为TCM编译的固件,并可以启动或停止执行。要使用Remoteproc,需要设置设备树Overlay:

在开发板的/boot目录中编辑bootenv.txt文件,添加 conf-imx8mp-phycore-rpmsg.dtbo :

overlays=conf-imx8mp-phycore-rpmsg.dtbo

重启目标并在U-Boot中执行:

u-boot=> run prepare_mcore

M7 Core 的固件 .elf 文件可以在 /lib/firmware 下找到。要加载固件,请输入:

target:~$ echo /lib/firmware/<firmware>.elf > /sys/class/remoteproc/remoteproc0/firmware
target:~$ echo start > /sys/class/remoteproc/remoteproc0/state

要加载不同的固件,M7 Core 需要停止:

target:~$ echo stop > /sys/class/remoteproc/remoteproc0/state

备注

在开发板上找到的 /lib/firmware 中的例子来自NXP的Yocto层meta-imx。要使用您通过MCUX SDK自己编译的样本,请在编译后将它们复制到开发板的 /lib/firmware 中。