LWN:U-Boot的最新状态!

关注了就能看到更多这么棒的文章哦~

A status update for U-Boot

By Jake Edge
July 26, 2023
EOSS
ChatGPT assisted translation
https://lwn.net/Articles/938769/

U-Boot(universal boot loader)在嵌入式 Linux 领域有广泛使用。在 2023 年嵌入式开源峰会(EOSS)上,Simon Glass 做了一个关于该项目状况的演讲(幻灯片 https://static.sched.com/hosted_files/eoss2023/b3/Recent%20Advances%20in%20U-Boot.pdf ,YouTube 视频 https://www.youtube.com/watch?v=YlJBsVZJkDI ),重点介绍了过去几年中添加的新功能。他还想介绍一下在 firmware 这个世界中的复杂性,他认为这种复杂性在增加,以及 U-Boot 如何有助于管理这种复杂性。这次演讲涉及了在这个项目中日益庞大的各种想法和变化。

Background

U-Boot 背后的理念是要有通用性;"在任何设备上启动任何操作系统",Glass 说。这个项目已经存在了大约 20 年,目前正在积极开发中,每年有 6000 次提交。U-Boot 按照固定的时间表发布,每年四次。

它有大约 300 万行 C 代码,还有一些额外的 Python 工具。U-Boot 与 Linux 内核有很多相似之处:它有相同的代码风格,使用 Kconfig 进行构建时配置,并且有一些兼容层,可以将 Linux 子系统和驱动程序移植到 U-Boot "不会有太多麻烦"。U-Boot 拥有一个持续集成(CI)测试系统,"涵盖了 boot loader 程序的大部分功能"。

U-Boot 受欢迎主要是源于其拥有大量的功能,但"它也容易被黑客攻击";很容易进来向代码库中添加一个新的命令或功能。它是单线程的应用程序,这使得开发起来更容易,因为不需要加锁;"它并不会试图成为一个操作系统"。U-Boot 的开发者通常对新的想法和功能持开放态度,这也有助于项目的发展。

Complexity

"在这个世界里,一切都变得更加复杂",他说。在我们设备中使用的 SoC(systems-on-chip)现在有了更多的功能,它们需要固件 firmware 来完成工作。固件需要打包成一个镜像文件,但这个过程也变得更加复杂。现在固件需要满足安全和签名要求,以确保系统使用了正确的固件。十年前,这种问题要少得多。

fd8d03fbfb48983954f6aa4f3df2551c.png

[Simon Glass]
启动流程也变得多样化;系统现在需要"在多个项目中来回跳转,使用不同的二进制文件等等,以启动操作系统"。此外,不同设备型号的差异也越来越大,彼此各有不同,需要为每个模型都提供不同的固件镜像文件。处理这么多的多样性并不容易。

U-Boot 的驱动模型可以把 SoC 的复杂性处理得"相当好",Glass 说。有一个 device tree,其中设备属于不同的类别;各个设备之间有关联,并使用设备树将它们联系在一起。

其中一个最复杂的事情是处理时钟;与过去不同,现在的板卡数据手册甚至都没有提供时钟图。但是 U-Boot 利用自己的基础设施使得这些工作变得容易得多。"你可以说'请给我 MMC 设备'",然后 U-Boot 会设置所有所需的时钟和 pin 脚复用,打开任何所需的供电通路,并把这个 device 返回回来。"用手动操作的话会非常复杂",他说。

以前如果要支持多个略有不同的设备型号的话需要为每个型号使用不同的引导加载程序,但 U-Boot 可以在运行时更改其配置,这样就只需要一个固件镜像就够了。它使用了不同的 device tree 来表示各种型号。针对某个型号的 device tree 可以稍后添加到引导镜像中,甚至可以作为产线生产制造过程的一部分。

有很多不同的方式来打包固件,每个人或项目可能都有自己的方式。初看的话似乎并不难,所以人们写了一些脚本,但最终整个构建系统都发展成了专门用于打包固件了。Binman 是一个试图解决这个问题的工具;它随附在 U-Boot 中,但也适用于其他项目,比如 Zephyr。它有一个配置文件,描述了需要放入固件镜像中的所有各个组成部分,并支持各种固件格式,因此可以创建适合安装到闪存内的正确文件格式。

Binman 解决了许多问题,它可以很容易更改镜像文件的内容,并提供镜像中存在内容的文档。无需使用各种不同的工具对二进制镜像进行解码,只需查阅 binman 配置即可。它还具有获取和构建需要对于 firmware 中一些 bit 上进行处理的工具的机制(例如签名,供应商特有的格式化任务)。

Standard boot

"标准引导"功能的目的是使 U-Boot 的引导更加标准化。传统的 U-Boot bootm 命令可用于引导各种以 flat device tree(FIT)格式生成的镜像,它会处理签名验证和图像解压缩等操作,但缺少一种方法来确定应使用哪些镜像以及确定这些镜像在设备上的位置。目前使用脚本来完成这一任务。在过去几年里,随 U-Boot 提供的 distro_bootcmd 脚本被用于提供处理引导所需的正确部分和组件。

标准引导,就添加了一个更高级的接口,使 U-Boot 能够完全看到设备上可用的引导设备和镜像;然后可以向用户提供一个菜单来选择选项。bootdev 是在存储设备(例如 MMC)之上的一个层,它可以列举其包含的可引导镜像。然后,bootmeth 可以列举描述系统特定引导流程的可用 bootflow 文件。"distro" bootmeth 将在由 bootdev 发现的文件系统中查找名为 extlinux/extlinux.conf 的文件。这些文件描述了特定发行版(如 Android、Fedora、Ubuntu、Chrome OS 等)的引导流程。这是一个简单的模型,但可能有点难以理解,他说,而 U-Boot 还在逐步转换到使用这种模型。

U-Boot 长期以来支持 UEFI,并可以直接通过 UEFI 引导发行版,如 Fedora 和 Ubuntu。它还支持 UEFI Secure Boot,并可以处理使用可信平台模块(TPM, Trusted Platform Module)对引导过程进行测量和验证。如果需要,U-Boot 还可以直接作为 EFI 应用程序来运行。

现在,UEFI 有一个替代方案。也就是 Verified Boot for Embedded (VBE),它的出现主要是为了回答一个问题:“如果我们不打算使用 UEFI,那会是什么样子?” 他不想详细介绍 VBE,因此参考他去年的 Open Source Firmware Conference (OSFC)的演讲以获取更多信息。VBE 基于现有的标准,如 FIT 格式。与 UEFI Secure Boot 中从引导镜像到 U-Boot 的一堆回调不同,VBE 提供了引导镜像需要的一切内容,这是一种更简单的方法,他认为。

在过去的几年里,U-Boot 项目已经开始使用 Sphinx 进行文档编写。之前有过一份 U-Boot 手册,但是在制作过程中“就逐渐被抛弃了”。新文档的好处在于它存储在源代码树中,因此添加新功能或命令的 patch 可以同时包含文档(也希望还包含相关 test)。大部分现有文档已经转换为 reStructuredText 格式,但仍有一些命令和功能缺乏文档。希望在不久的将来弥补这个差距。

U-Boot 的测试和持续集成系统的功能在过去几年里也“显著扩展”。Glass 指出,在 EOSS 有一个关于使用 emulated device 进行测试的 Zephyr 讲座;U-Boot 也使用这些模拟器,因此可以在 Linux 工作站上模拟 SPI 闪存测试 U-Boot。这样就可以编写各种无需硬件即可运行的测试;模拟器可以更改“硬件”以检查需要验证的内容。现在,如果有人提交了没有测试过的 patch,可以要求他们提供一个 test,而且不是一个巨大的负担。

Devicetree and beyond

U-Boot 在 2011 年左右就引入了 devicetree,与 Linux 差不多同时,这带来了一个问题,它们之间的 binding (属性、节点等)是有差异的。这些差异正在逐步解决。另一个问题是,U-Boot 一直没有能够将其 schema 需求推送到内核 upstream 上,不过这也在发生变化。最终希望 U-Boot 可以从 Linux 获取其 device tree,并且只要从 device tree 中明确了所需的硬件驱动程序,U-Boot 就可以直接使用它。

虽然 U-Boot 使用 Kconfig 的时间至少和 Glass 在上面工作的时间(将近十年)一样长,但它仍然有许多散布在头文件中的#define 配置语句,不过这些在今年年初都得到了整理。现在有一个文本文件描述了配置,这意味着完全可以不需要任何跟特定 board 关联起来的 config.h 文件;完全可以在配置文本文件中定义清楚一个 board 的需求。

该项目还添加了链接时优化(LTO, link-time optimization)。"它会让你的 board 的构建时间变长四倍,但 size 会减小 5%。"这通常来说是有好处的,所以大多数 Arm 板默认开启了 LTO。此外,events 功能提供了一种监视设备创建等相关事件的方法;这是 weak function 的一个替代方案,他不不很喜欢 weak function,因为很难确定是在哪里被真正调用的。一个 event 会被发布出来,其他地方可以告知说对特定事件感兴趣,然后在 event 发生时进行处理;所有这些监听事件的地方都可以使用工具轻松列出来,所以有着更好的可见性。

目前正在进行的工作之一是允许固件的不同部分把配置数据和其他信息传递给固件的下一阶段。目前可能会有多个阶段(包括验证程序加载器(VPL, verifying program loader)、二级程序加载器(SPL, secondary program loader)、可信执行环境或可信固件(trusted execution environment or trusted firmware)以及 U-Boot),这些都是互相独立的项目,每个项目都有自己的配置机制。固件传递规范(Firmware Handoff specification)是用来“简单标记数据结构的”,可在这些组件之间进行传递。

近年来,U-Boot 的网络支持发生了很多变化,包括添加了 TCP/IP,这意味着可以使用 Wget 命令,非常方便。TFTP 支持已经存在一段时间了,但功能较为有限。现在还支持 IPv6 和新的 PHY API。目前正在进行讨论来决定是否应该切换到轻量级 TCP/IP 协议栈 lwIP 还是继续使用自己的实现。

U-Boot 现在支持 21 种不同的 RISC-V 开发板。在 x86 上引导发行版的支持也几乎完全成型了,只需一些尚未合入的 patch。在 x86 上使用 U-Boot 作为 coreboot 的 payload 得到了增强。coreboot 可以用于系统的初始引导,设置硬件,包括 ACPI 表,然后跳转到 U-Boot 引导操作系统。这个过程现在“更加完善”。

为了调查引导时的性能瓶颈在哪里,可以在 U-Boot 中使用 tracing 功能。tracer 会记录函数的进入和退出情况,并将其存储在内存缓冲区中,以便后续导出在另一个系统中进行分析。tracing 功能在 U-Boot 中已经存在了一段时间了,但最近进行了更新,以使用 trace-cmd 接口。

U-Boot 是单线程的,这使得它易于处理,但有时也可能有些麻烦。例如,如果进行 USB 扫描,你必须等待扫描完成,等待端口超时等,如果有很多端口,就可能需要几秒钟。希望有一种方式可以启动扫描过程,并同时执行其他任务,这正是 cyclic 子系统的用武之地。

当 U-Boot 处于空闲状态时,它会进入 cyclic scheduler 调度器。多年来,cyclic 子系统一直用于对看门狗定时器进行 reset,但现在它也可供系统中的其他场景使用了。他有许多地方都计划使用这个功能(包括用于 USB 扫描),但也期待看到其他人的创意。

还有一个实验性的新功能,就是使用 expo menu 添加一个类似图形用户界面的功能。这些菜单是一组被称为 scene 的屏幕内容,用户可以使用键盘导航来设置或更改各种参数。它们看起来以及操作起来都类似于简化的 x86 BIOS 菜单。

之后,演讲者进行了一系列快速演示,以展示他在演讲中提到的一些不同功能。他首先展示了在 QEMU 中的标准引导过程,然后运行了 binman 以显示所使用的启动镜像的内容。他还演示了如何使用 binman 去获取缺失的工具(例如 fiptool),以便用于构建固件镜像。此外,他还推送了一个分支到 GitLab,并简要浏览了 CI 系统,根据 tracing 的输出创建了火焰图,并展示了 expo GUI。

之后,他回答了一些观众提出的问题;问题之一是关于标准引导中的优先级问题。是否可以指定某些 bootdevs(或存储类型,例如可移动或不可移动)优先于其他设备?演讲者表示每种 bootdev 类型确实有一个可以指定的优先级,但是没有基于媒体是否可移动的区分,所以这可能需要今后增加。启动顺序也可以根据设备出现在环境变量中的顺序来指定。

[I would like to thank LWN's travel sponsor, the Linux Foundation, for assisting with my travel to Prague.]

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

format,png

/* * iford.dtsi- Sigmastar * * Copyright (c) [2019~2020] SigmaStar Technology. * * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License version 2 for more details. * */ #include <generated/autoconf.h> #include "../../../../drivers/sstar/include/iford/irqs.h" #include "../../../../drivers/sstar/include/iford/gpio.h" #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/input/input.h> #include <linux/kconfig.h> / { cpus { #address-cells = <1>; #size-cells = <0>; cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a32"; clock-frequency = <1000000000>; clocks = <&CLK_cpu_pll>; reg = <0x0>; operating-points-v2 = <&cpu0_opp_table>; }; #ifdef CONFIG_SMP cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a32"; clock-frequency = <1000000000>; clocks = <&CLK_cpu_pll>; reg = <0x1>; #if CONFIG_ENABLE_METHOD_PSCI enable-method = "psci"; #endif }; #endif }; cpu0_opp_table: opp_table0 { compatible = "operating-points-v2"; opp-shared; opp00 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <910000 890000 910000>; status = "ok"; }; }; xtal: oscillator { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <24000000>; }; #if CONFIG_ARM_PSCI psci { compatible = "arm,psci-1.0"; method = "smc"; }; #endif aliases { console = &uart0; serial0 = &uart0; serial1 = &uart1; serial2 = &fuart; serial3 = &pm_fuart; serial4 = &pm_fuart1; }; #ifdef CONFIG_OPTEE firmware { optee { compatible = "linaro,optee-tz"; method = "smc"; #interrupt-cells = <3>; interrupt-parent = <&gic>; interrupts = <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>; }; }; #endif soc { compatible = "simple-bus"; interrupt-parent = <&sstar_main_intc>; #address-cells = <1>; #size-cells = <1>; ranges; gic: gic@16000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; #address-cells = <1>; #size-cells = <1>; interrupt-controller; interrupt-parent = <&gic>; redistributor-stride = <0x0 0x20000>; #redistributor-regions = <1>; reg = <0x16000000 0x20000>, <0x16040000 0x80000>; }; sstar_main_intc: sstar_main_intc { compatible = "sstar,main-intc"; #interrupt-cells = <3>; #address-cells = <1>; #size-cells = <1>; interrupt-parent=<&gic>; interrupt-controller; }; sstar_pm_main_intc: sstar_pm_main_intc { compatible = "sstar,pm-main-intc"; #interrupt-cells = <1>; interrupt-parent=<&sstar_main_intc>; interrupt-controller; interrupts = <GIC_SPI INT_IRQ_IRQ_FRM_PM IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_IRQ_FRM_PM IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; sstar_pm_gpi_intc: sstar_pm_gpi_intc { compatible = "sstar,pm-gpi-intc"; #interrupt-cells = <1>; interrupt-parent=<&sstar_main_intc>; interrupt-controller; interrupts = <GIC_SPI INT_IRQ_PM_SLEEP IRQ_TYPE_LEVEL_HIGH>; }; sstar_gpi_intc: sstar_gpi_intc { compatible = "sstar,gpi-intc"; #interrupt-cells = <1>; interrupt-parent=<&sstar_main_intc>; interrupt-controller; interrupts = <GIC_SPI INT_IRQ_GPI_OUT IRQ_TYPE_LEVEL_HIGH>; }; arch_timer { compatible = "arm,cortex-a32-timer", "arm,armv8-timer"; interrupt-parent=<&gic>; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; clock-frequency = <6000000>; /* arch_timer must use clock-frequency*/ }; pmu { compatible = "arm,cortex-a53-pmu"; interrupt-parent=<&gic>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; }; clks: clocks{ #address-cells = <1>; #size-cells = <1>; ranges; }; cpufreq { compatible = "sstar,infinity-cpufreq"; clocks = <&CLK_sar>; status = "ok"; }; miu { compatible = "sstar,miu"; interrupts=<GIC_SPI INT_IRQ_MIU IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; light_misc_control { compatible = "sstar,light_misc_control"; lightsensor-i2c = <0>; ir-ctrlmode = /bits/ 8 <0>; // 0:GPIO 1:PWM default is 0 ir-pad = <PAD_PM_PSPI0_INT>; //ir-pad = /bits/ 64 <8 41666 11249>; // <pwm_channel> <period> <duty> ircut-pad = <PAD_PM_GPIO9 PAD_PM_GPIO10>; status = "ok"; }; mmu { compatible = "sstar,mmu"; interrupts=<GIC_SPI INT_IRQ_MMU IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; /* timer_clockevent: timer@1F006040 { compatible = "sstar,piu-clockevent"; reg = <0x1F006040 0x100>; interrupts=<GIC_SPI INT_FIQ_TIMER_0 IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_xtali_12m>; }; */ uart0: uart0@1F221000 { compatible = "sstar,uart"; reg = <0x1F221000 0x100>, <0x1F220E00 0x100>; interrupts= <GIC_SPI INT_IRQ_FUART0 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART0_MERGE IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART0_MERGE IRQ_TYPE_LEVEL_HIGH>; #if !(defined(CONFIG_SS_DUALOS) || defined(CONFIG_OPTEE)) dma-enable; #endif rx_fifo_level = <0>; tx_fifo_level = <0>; digmux = <0>; clocks = <&CLK_fuart0>, <&CLK_mcu>; status = "ok"; }; uart1: uart1@1F221200 { compatible = "sstar,uart"; reg = <0x1F221200 0x100>, < 0x1F221C00 0x100>; interrupts= <GIC_SPI INT_IRQ_FUART1 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART1_MERGE IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART1_MERGE IRQ_TYPE_LEVEL_HIGH>; #if !(defined(CONFIG_SS_DUALOS) || defined(CONFIG_OPTEE)) dma-enable; #endif #if defined(CONFIG_PM_MCU_USE_UART1) no-suspend; #endif rx_fifo_level = <0>; tx_fifo_level = <0>; digmux = <3>; clocks = <&CLK_fuart1>, <&CLK_mcu>; status = "ok"; }; fuart: fuart@1F220400 { compatible = "sstar,uart"; reg = <0x1F220400 0x100>, <0x1F220600 0x100>; interrupts= <GIC_SPI INT_IRQ_FUART IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART_MERGE IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_FUART_MERGE IRQ_TYPE_LEVEL_HIGH>; #if !(defined(CONFIG_SS_DUALOS) || defined(CONFIG_OPTEE)) dma-enable; #endif #if defined(CONFIG_PM_MCU_USE_FUART) no-suspend; #endif sctp_enable = <0>; rx_fifo_level = <0>; tx_fifo_level = <0>; digmux = <1>; clocks = <&CLK_fuart>, <&CLK_mcu>; status = "ok"; }; pm_fuart: pm_fuart@1F006C00 { compatible = "sstar,uart"; reg = <0x1F006C00 0x100>, <0x1F006E00 0x100>; interrupt-parent = <&sstar_pm_main_intc>; interrupts= <INT_PMSLEEP_IRQ_PM_FUART>, <INT_PMSLEEP_IRQ_PM_FUART_MERGE>, <INT_PMSLEEP_IRQ_PM_FUART_MERGE>; #if !(defined(CONFIG_SS_DUALOS) || defined(CONFIG_OPTEE)) dma-enable; #endif sctp_enable = <0>; rx_fifo_level = <0>; tx_fifo_level = <0>; clocks = <&CLK_pm_fuart0>; status = "okay"; }; pm_fuart1: pm_fuart1@1F00A400 { compatible = "sstar,uart"; reg = <0x1F00A400 0x100>, <0x1F00A600 0x100>; interrupt-parent = <&sstar_pm_main_intc>; interrupts= <INT_PMSLEEP_IRQ_PM_FUART1>, <INT_PMSLEEP_IRQ_PM_FUART1_MERGE>, <INT_PMSLEEP_IRQ_PM_FUART1_MERGE>; #if !(defined(CONFIG_SS_DUALOS) || defined(CONFIG_OPTEE)) dma-enable; #endif sctp_enable = <0>; rx_fifo_level = <0>; tx_fifo_level = <0>; clocks = <&CLK_pm_fuart1>; status = "okay"; }; dla { compatible = "sstar,dla"; interrupts = <GIC_SPI INT_IRQ_DLA_TOP_0 IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_ipupll_clk>, <&CLK_ipu>, <&CLK_ipuff>; status = "ok"; }; bdma0 { compatible = "sstar,bdma0"; interrupts = <GIC_SPI INT_IRQ_BDMA IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F200400 0x80>; clocks = <&xtal>; status = "ok"; }; bdma1 { compatible = "sstar,bdma1"; interrupts = <GIC_SPI INT_IRQ_BDMA IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F200480 0x80>; clocks = <&xtal>; status = "ok"; }; bdma2 { compatible = "sstar,bdma2"; interrupts = <GIC_SPI INT_IRQ_BDMA IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F200500 0x80>; clocks = <&xtal>; status = "ok"; }; bdma8 { compatible = "sstar,bdma8"; interrupts = <GIC_SPI INT_IRQ_PM_BDMA IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F008A00 0x80>; clocks = <&xtal>; status = "ok"; }; /* bdma9 { compatible = "sstar,bdma9"; interrupts = <GIC_SPI INT_IRQ_PM_BDMA IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F008A80 0x80>; clocks = <&xtal>; status = "ok"; }; */ /* xordma { compatible = "sstar,xordma"; interrupts = <GIC_SPI INT_IRQ_BDMA_3 IRQ_TYPE_LEVEL_HIGH>; reg = <0x1F200C00 0x100>,<0x1F201800 0x100>; clocks = <&xtal>; status = "ok"; }; */ #ifdef CONFIG_OPTEE tzsp { compatible = "sstar,tzsp"; interrupts = <GIC_SPI INT_FIQ_ERROR_RESP IRQ_TYPE_EDGE_RISING>; status = "ok"; }; tzsp_dla { compatible = "sstar,tzsp_dla"; interrupt-parent=<&gic>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; }; tzimi { compatible = "sstar,tzimi"; interrupts = <GIC_SPI INT_IRQ_TZIMI IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; tzemi { compatible = "sstar,tzemi"; interrupts = <GIC_SPI INT_IRQ_TZEMI IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; #endif fsp-qspi0 { compatible = "sstar,fsp-qspi"; reg = <0x1F201A00 0x200>, <0x1F201C00 0x200>; clocks = <&CLK_fsp_qspi>, <&CLK_spi_nonpm>, <&CLK_spi_synth_pll>; cs-num = <2>; cs-mode = <0>; //cs-ext = <PAD_GPIO0>; engine = <0>; dma = <1>; status = "ok"; }; nandflash0 { compatible = "sstar-nandflash"; engine = <0>; cs-select = <0>; fcie-interface = <0>; status = "ok"; }; #if IS_ENABLED(CONFIG_SSTAR_NOR) norflash0 { compatible = "sstar-norflash"; engine = <0>; cs-select = <0>; status = "ok"; }; /* norflash1 { compatible = "sstar-norflash"; engine = <0>; cs-select = <2>; status = "ok"; }; */ #endif #if IS_ENABLED(CONFIG_SSTAR_MSPI) spi@1f222000 { compatible = "sstar,mspi"; mspi-group = <0>; #ifdef CONFIG_CAM_CLK camclk = <CAMCLK_mspi0>; #else clocks = <&CLK_mspi0>; #endif reg = <0x1F222000 0x200>; #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI INT_IRQ_MSPI_0 IRQ_TYPE_LEVEL_HIGH>; #if !defined(CONFIG_SS_DUALOS) dma-enable; #endif cs-num = <2>; //cs-ext = <PAD_UNKNOWN>; //4to3-mode; //clk-out-mode = <27000000>; status = "ok"; #ifdef CONFIG_SS_GYRO_TRANSFER_SPI gyro@0 { compatible = "sstar,gyro_spi"; devid = <0>; reg = <0x0>; spi-max-frequency = <7000000>; }; #endif #ifdef CONFIG_SPI_SPIDEV spidev0@0 { compatible = "lwn,bk4"; spi-max-frequency = <2000000>; reg = <0>; }; spidev1@1 { compatible = "lwn,bk4"; spi-max-frequency = <2000000>; reg = <1>; }; #endif }; #endif #if IS_ENABLED(CONFIG_SSTAR_PSPI) pspi: spi@1F003200 { compatible = "sstar,pspi"; reg = <0x1F003200 0x200>; #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI INT_IRQ_PSPI02HOST IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_pm_pspi0>; #ifdef CONFIG_SPI_SLAVE pspi-slave; ready-gpios = <&gpio PAD_GPIO1 0>; #endif dma-enable; group = <1>; cs-num = <1>; status = "okay"; #ifdef CONFIG_SPI_SLAVE slave@0 { compatible = "ge,achc"; reg = <0>; }; #else spidev1@0 { compatible = "ge,achc"; reg = <0>; }; #endif }; #endif #if IS_ENABLED(CONFIG_SSTAR_I2C) i2c0: i2c@1f222800 { compatible = "sstar,i2c"; reg = <0x1F222800 0x200>; #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI INT_IRQ_MIIC IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_miic0>; #if !defined(CONFIG_SS_DUALOS) dma-enable; #endif group = <0>; #ifdef CONFIG_SS_GYRO_TRANSFER_I2C speed = <600000>; #else speed = <200000>;//if u want set tSU/tHD, do not set 0, tSU = (t-su-* / i2c-srcclk)S, tHD = (t-hd-* / i2c-srcclk)S #endif t-su-sta = <0>; t-hd-sta = <0>; t-su-sto = <0>; t-hd-sto = <0>; //1->open drain; 2->open drain + one push; 3->open drain + one push + clock push; 4->push-pull output-mode = <4>; status = "ok"; #ifdef CONFIG_SS_GYRO_TRANSFER_I2C gyro@d0 { compatible = "sstar,gyro"; devid = <0>; #ifdef CONFIG_SS_GYRO_CHIP_ICM40607 reg = <0x69>; #endif #ifdef CONFIG_SS_GYRO_CHIP_ICM42607 reg = <0x68>; #endif #ifdef CONFIG_SS_GYRO_CHIP_ICG20660 reg = <0x68>; #endif }; #endif }; #endif emac0: emac0 { compatible = "sstar-emac"; interrupts = <GIC_SPI INT_IRQ_EMAC IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_FIQ_LAN_ESD IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_EMAC_SCATTER IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_emac_ahb>; reg = <0x1F2A2000 0x800>, <0x1F304200 0x600>, <0x1F2A3000 0x600>; // reg = <0x1F2A2000 0x800>, <0x1F304200 0x600>, <0x00000000 0x000>; pad = <0x1F203C38 0x0001 0x0001>; // pad selection from 0x0001 bus-mode = <1>;//1:MII 2:RMII phy-handle = <&phy0>; cpu-affinity = <0>; //0:single cpu 1:multi cpu status = "ok"; mdio-bus@emac0 { phy0: ethernet-phy@0 { // phy-mode = "rmii"; phy-mode = "mii"; }; }; }; #if IS_ENABLED(CONFIG_SSTAR_SDMMC) #ifdef CONFIG_SSTAR_SELECT_EMMC sstar_sdmmc0: sstar_sdmmc0 { compatible = "sstar,sdmmc"; bus-width = <4>; max-frequency = <48000000>; non-removable; //broken-cd; cap-mmc-highspeed; //sd-uhs-sdr50; //sd-uhs-sdr104; //sd-uhs-ddr50; //cap-sdio-irq; no-sdio; no-sd; //no-mmc; //reg = <0x1F008400 0x200>; reg = <0x1F282600 0x200>; pll-reg = <0x1F283200 0x200>; //cifd-reg = <0x1F008600 0x200>; cifd-reg = <0x1F282800 0x200>; //pwr-save-reg = <0x1F008800 0x200>; pwr-save-reg = <0x1F282A00 0x200>; ip-order = /bits/ 8 <0>; pad-order = /bits/ 8 <0>; //pad-order = /bits/ 8 <1>; trans-mode = /bits/ 8 <1>; // 0:dma 1:adma default is 1 fake-cdz = /bits/ 8 <0>; rev-cdz = /bits/ 8 <0>; //cdz-pad = <PAD_PM_SD_CDZ>; //pwr-pad = <PAD_FUART_RTS>; pwr-on-delay = <1>; pwr-off-delay = <30>; //sdio-use-1bit = /bits/ 8 <0>; cifd-mcg-off = /bits/ 8 <0>; // mcg on/off in cifd support-cmd23 = /bits/ 8 <1>; clk-driving = <1>; cmd-driving = <1>; data-driving = <1>; en-clk-phase = /bits/ 8 <0>; //0/1 rx-clk-phase = <0>; //0-3 tx-clk-phase = <0>; //0-3 en-eight-phase = /bits/ 8 <0>; //0/1 rx-eight-phase = /bits/ 8 <0>; //0/1 tx-eight-phase = /bits/ 8 <0>; //0/1 interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_SDIO IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mie0_irq", "mie1_irq"; clocks = <&CLK_sd>, <&CLK_pm_sdio>, <&CLK_mcu_pm>; clock-names = "clk_sdmmc0", "clk_sdmmc1", "pm_mcu_sdmmc1"; status = "ok"; }; sstar_sdmmc1: sstar_sdmmc1 { compatible = "sstar,sdmmc"; bus-width = <4>; max-frequency = <50000000>; //non-removable; //broken-cd; cap-mmc-highspeed; cap-sd-highspeed; //sd-uhs-sdr50; //sd-uhs-sdr104; //sd-uhs-ddr50; cap-sdio-irq; //no-sdio; //no-sd; no-mmc; reg = <0x1F008400 0x200>; //reg = <0x1F282600 0x200>; pll-reg = <0x1F283400 0x200>; cifd-reg = <0x1F008600 0x200>; //cifd-reg = <0x1F282800 0x200>; pwr-save-reg = <0x1F008800 0x200>; //pwr-save-reg = <0x1F282A00 0x200>; ip-order = /bits/ 8 <1>; pad-order = /bits/ 8 <0>; trans-mode = /bits/ 8 <1>; // 0:dma 1:adma default is 1 cifd-mcg-off = /bits/ 8 <0>; // mcg on/off in cifd support-runtime-pm = /bits/ 8 <0>; // sd/sdio runtime-pm default disable support-cmd23 = /bits/ 8 <1>; fake-cdz = <0>; rev-cdz = /bits/ 8 <0>; cdz-pad = <PAD_PM_SDIO_INT>; pwr-pad = <PAD_PM_GPIO12>; //cdz-pad = <PAD_SD0_CDZ>; //pwr-pad = <PAD_PM_GPIO11>; pwr-on-delay = <1>; pwr-off-delay = <30>; sdio-use-1bit = /bits/ 8 <0>; clk-driving = <1>; cmd-driving = <1>; data-driving = <1>; en-clk-phase = /bits/ 8 <0>; //0/1 rx-clk-phase = <0>; //0-3 tx-clk-phase = <0>; //0-3 en-eight-phase = /bits/ 8 <0>; //0/1, only support:000,001,010,011,100 rx-eight-phase = /bits/ 8 <0>; //0/1 tx-eight-phase = /bits/ 8 <0>; //0/1 interrupts = <GIC_SPI INT_IRQ_SDIO IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_FIQ_PAD2SDIO_SD_CDZ IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mie1_irq", "cdz_slot1_irq"; //interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>, // <GIC_SPI INT_FIQ_SD_CDZ_0 IRQ_TYPE_LEVEL_HIGH>; //interrupt-names = "mie0_irq", "cdz_slot0_irq"; clocks = <&CLK_sd>, <&CLK_pm_sdio>, <&CLK_mcu_pm>; clock-names = "clk_sdmmc0", "clk_sdmmc1", "pm_mcu_sdmmc1"; status = "ok"; }; #else sstar_sdmmc0: sstar_sdmmc0 { compatible = "sstar,sdmmc"; bus-width = <4>; max-frequency = <50000000>; non-removable; //broken-cd; cap-mmc-highspeed; //sd-uhs-sdr50; //sd-uhs-sdr104; //sd-uhs-ddr50; //cap-sdio-irq; no-sdio; no-sd; //no-mmc; reg = <0x1F008400 0x200>; //reg = <0x1F282600 0x200>; pll-reg = <0x1F283200 0x200>; cifd-reg = <0x1F008600 0x200>; //cifd-reg = <0x1F282800 0x200>; pwr-save-reg = <0x1F008800 0x200>; //pwr-save-reg = <0x1F282A00 0x200>; ip-order = /bits/ 8 <1>; pad-order = /bits/ 8 <0>; //pad-order = /bits/ 8 <1>; trans-mode = /bits/ 8 <1>; // 0:dma 1:adma default is 1 fake-cdz = /bits/ 8 <0>; rev-cdz = /bits/ 8 <0>; //cdz-pad = <PAD_PM_SD_CDZ>; //pwr-pad = <PAD_FUART_RTS>; pwr-on-delay = <1>; pwr-off-delay = <30>; //sdio-use-1bit = /bits/ 8 <0>; cifd-mcg-off = /bits/ 8 <0>; // mcg on/off in cifd support-cmd23 = /bits/ 8 <1>; clk-driving = <1>; cmd-driving = <1>; data-driving = <1>; en-clk-phase = /bits/ 8 <0>; //0/1 rx-clk-phase = <0>; //0-3 tx-clk-phase = <0>; //0-3 en-eight-phase = /bits/ 8 <0>; //0/1, only support:000,001,010,011,100 rx-eight-phase = /bits/ 8 <0>; //0/1 tx-eight-phase = /bits/ 8 <0>; //0/1 interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_IRQ_SDIO IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mie0_irq", "mie1_irq"; clocks = <&CLK_sd>, <&CLK_pm_sdio>, <&CLK_mcu_pm>; clock-names = "clk_sdmmc0", "clk_sdmmc1", "pm_mcu_sdmmc1"; status = "ok"; }; sstar_sdmmc1: sstar_sdmmc1 { compatible = "sstar,sdmmc"; bus-width = <4>; max-frequency = <48000000>; //non-removable; //broken-cd; cap-mmc-highspeed; cap-sd-highspeed; //sd-uhs-sdr50; //sd-uhs-sdr104; //sd-uhs-ddr50; cap-sdio-irq; //no-sdio; //no-sd; no-mmc; //reg = <0x1F008400 0x200>; reg = <0x1F282600 0x200>; pll-reg = <0x1F283400 0x200>; //cifd-reg = <0x1F008600 0x200>; cifd-reg = <0x1F282800 0x200>; //pwr-save-reg = <0x1F008800 0x200>; pwr-save-reg = <0x1F282A00 0x200>; ip-order = /bits/ 8 <0>; pad-order = /bits/ 8 <0>; trans-mode = /bits/ 8 <1>; // 0:dma 1:adma default is 1 cifd-mcg-off = /bits/ 8 <0>; // mcg on/off in cifd support-runtime-pm = /bits/ 8 <0>; // sd/sdio runtime-pm default disable support-cmd23 = /bits/ 8 <1>; fake-cdz = <0>; rev-cdz = /bits/ 8 <0>; //cdz-pad = <PAD_PM_SDIO_INT>; //pwr-pad = <PAD_PM_GPIO12>; cdz-pad = <PAD_SD0_CDZ>; pwr-pad = <PAD_PM_GPIO11>; pwr-on-delay = <1>; pwr-off-delay = <30>; sdio-use-1bit = /bits/ 8 <0>; clk-driving = <1>; cmd-driving = <1>; data-driving = <1>; en-clk-phase = /bits/ 8 <0>; //0/1 rx-clk-phase = <0>; //0-3 tx-clk-phase = <0>; //0-3 en-eight-phase = /bits/ 8 <0>; //0/1 rx-eight-phase = /bits/ 8 <0>; //0/1 tx-eight-phase = /bits/ 8 <0>; //0/1 //interrupts = <GIC_SPI INT_IRQ_SDIO IRQ_TYPE_LEVEL_HIGH>, // <GIC_SPI INT_FIQ_PAD2SDIO_SD_CDZ IRQ_TYPE_LEVEL_HIGH>; //interrupt-names = "mie1_irq", "cdz_slot1_irq"; interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_FIQ_SD_CDZ_0 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "mie0_irq", "cdz_slot0_irq"; clocks = <&CLK_sd>, <&CLK_pm_sdio>, <&CLK_mcu_pm>; clock-names = "clk_sdmmc0", "clk_sdmmc1", "pm_mcu_sdmmc1"; status = "ok"; }; #endif #endif hst0to1 { compatible = "sstar,hst0to1"; // mailbox int interrupts = <GIC_SPI INT_FIQ_CPU0TO2_TOP IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; #if IS_ENABLED(CONFIG_SSTAR_RIU_DBG) riu { #address-cells = <1>; #size-cells = <1>; compatible = "sstar,riu"; ranges; status = "ok"; #if CONFIG_SSTAR_RIU_TIMEOUT timeout { reg = <0x1F000200 0x200>, <0x1F200200 0x200>, <0x1F2CE000 0x200>; interrupts = <GIC_SPI INT_FIQ_PM_XIU_TIMEOUT IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_FIQ_XIU_TIMEOUT IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI INT_FIQ_XIU_XIU_TIMEOUT IRQ_TYPE_LEVEL_HIGH>; print-on; //bug-on; status = "ok"; }; #endif #if CONFIG_SSTAR_RIU_RECORDER recorder { reg = <0x1F229600 0x200>, <0x1F229800 0x200>, <0x1F229A00 0x200>, <0x1F229C00 0x200>; interrupts = <GIC_SPI INT_IRQ_RIU_RECORDING IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_wdma>; print-on; //bug-on; status = "ok"; }; #endif }; #endif #if IS_ENABLED(CONFIG_SSTAR_TIMER) timer0: timer0@0x1F006040 { compatible = "sstar,timer"; clocks = <&CLK_mcu_pm_p>; reg = <0x1F006040 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer1: timer1@0x1F006080 { compatible = "sstar,timer"; clocks = <&CLK_mcu_pm_p>; reg = <0x1F006080 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer2: timer2@0x1F0060C0 { compatible = "sstar,timer"; clocks = <&CLK_mcu_pm_p>; reg = <0x1F0060C0 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer3: timer3@0x1F006100 { compatible = "sstar,timer"; clocks = <&CLK_mcu_pm_p>; reg = <0x1F006100 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer4: timer4@0x1F006140 { compatible = "sstar,timer"; clocks = <&CLK_pm_timer4>; clock-on-demand; reg = <0x1F006140 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer5: timer5@0x1F006180 { compatible = "sstar,timer"; clocks = <&CLK_pm_timer5>; clock-on-demand; reg = <0x1F006180 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer6: timer6@0x1F0061C0 { compatible = "sstar,timer"; clocks = <&CLK_pm_timer6>; clock-on-demand; reg = <0x1F0061C0 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer7: timer7@0x1F006440 { compatible = "sstar,timer"; clocks = <&CLK_pm_timer7>; clock-on-demand; reg = <0x1F006440 0x40>; interrupts = <GIC_SPI INT_FIQ_TIMER IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; timer8: timer8@0x1F2CDE40 { compatible = "sstar,timer"; clocks = <&CLK_mcu>; reg = <0x1F2CDE40 0x40>; interrupts = <GIC_SPI INT_FIQ_NONPM_TIMER_0 IRQ_TYPE_EDGE_RISING>; status = "ok"; }; timer9: timer9@0x1F2CDE80 { compatible = "sstar,timer"; clocks = <&CLK_mcu>; reg = <0x1F2CDE80 0x40>; interrupts = <GIC_SPI INT_FIQ_NONPM_TIMER_1 IRQ_TYPE_EDGE_RISING>; status = "ok"; }; timer10: timer10@0x1F2CDEC0 { compatible = "sstar,timer"; clocks = <&CLK_mcu>; reg = <0x1F2CDEC0 0x40>; interrupts = <GIC_SPI INT_FIQ_NONPM_TIMER_2 IRQ_TYPE_EDGE_RISING>; status = "ok"; }; timer11: timer11@0x1F2CDF00 { compatible = "sstar,timer"; clocks = <&CLK_mcu>; reg = <0x1F2CDF00 0x40>; interrupts = <GIC_SPI INT_FIQ_NONPM_TIMER_3 IRQ_TYPE_EDGE_RISING>; status = "ok"; }; #endif watchdog0 { compatible = "sstar,wdt"; clocks = <&CLK_wdt>; reg = <0x1F006000 0x40>; interrupts = <GIC_SPI INT_FIQ_WDT IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; #if defined(CONFIG_SSTAR_LH_RTOS_VIRTIO) rpmsg: rpmsg { compatible = "sstar,sstar-lh-rtos-virtio"; }; #endif aesdma { compatible = "sstar,aesdma"; interrupts=<GIC_SPI INT_IRQ_WADR_ERR IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_aesdma>; #ifdef CONFIG_CAM_CLK camclk = <CAMCLK_aesdma>; #endif status = "ok"; }; rng { compatible = "sstar,rng"; clocks = <&CLK_miu_boot>; status = "ok"; }; gpio: gpio { compatible = "sstar,gpio"; #gpio-cells = <2>; status = "ok"; }; clkinit { compatible = "sstar,clkinit"; #ifdef CONFIG_SSTAR_CLK_PSPI_EXT clocks = <&CLK_pm_high_ext>; default-parent = <2>; #endif status = "ok"; }; #if IS_ENABLED(CONFIG_SSTAR_ADCLP) adclp0: adclp0@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x1F002800 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <0>; ref-voltage = <1800>; upper-bound = <0x3FF>; lower-bound = <0>; #io-channel-cells = <1>; status = "ok"; }; adclp1: adclp1@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x1F002800 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <1>; ref-voltage = <1800>; upper-bound = <0x3FF>; lower-bound = <0>; #io-channel-cells = <1>; status = "ok"; }; adclp2: adclp2@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x1F002800 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <2>; ref-voltage = <1800>; upper-bound = <0x3FF>; lower-bound = <0>; #io-channel-cells = <1>; status = "ok"; }; adclp3: adclp3@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x1F002800 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <3>; ref-voltage = <1800>; upper-bound = <0x3FF>; lower-bound = <0>; #io-channel-cells = <1>; status = "ok"; }; adclp4: adclp4@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x1F002800 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <4>; ref-voltage = <1800>; upper-bound = <0x3FF>; lower-bound = <0>; #io-channel-cells = <1>; status = "ok"; }; #endif #if IS_ENABLED(CONFIG_SSTAR_RTC) rtcpwc: rtcpwc { compatible = "sstar,rtcpwc"; reg = <0x1F006800 0x200>; interrupts=<GIC_SPI INT_IRQ_FLAG_POC IRQ_TYPE_LEVEL_HIGH>; // io0-hiz; // io2-wos = <1>; //0:CMPHL 1:CMPHL 2:CMPL 3:CMPH // io2-wos-v = <0x2 0x3>; //<vl vh> 0<vl<8 0<vh<8 // io3-pu; // offset-count = <100>; // offset-nagative; // iso-auto-regen; /* * io4 control source selection * io0/io1/io2/io3 ctrl bit0 * alarm ctrl bit1 * sw ctrl bit2 * support the combination of above ways */ io4-enable = <3>; /* * io5 control source selection * io4 ctrl bit0 * alarm ctrl bit1 * sw ctrl bit2 * support the combination of above ways */ io5-enable = <7>; // for demo board,use 3,default hight // io5-no-poweroff; // io5 keep when excute 'poweroff' use for wakeup pm51 status = "ok"; #ifdef CONFIG_SSTAR_PWC_IO_POLLING poll-interval = <10>; #endif /* CONFIG_SSTAR_PWC_IO_POLLING */ io1 { num = <1>; keycode = <KEY_WAKEUP>; #ifdef CONFIG_SSTAR_PWC_IO_POLLING debounce-interval = <10>; #endif /* CONFIG_SSTAR_PWC_IO_POLLING */ #ifdef CONFIG_SSTAR_PWC_IO_INTERRUPT interrupt-parent = <&sstar_pm_gpi_intc>; interrupts = <INT_PM_GPI_FIQ_PAD_RTC_IO1>; #endif /* CONFIG_SSTAR_PWC_IO_INTERRUPT */ }; }; #endif #if IS_ENABLED (CONFIG_SSTAR_PWM) pwm0: pwm@0x1F203200{ compatible = "sstar,pwm"; reg = <0x1F203200 0x37>; #pwm-cells = <3>; channel = <0>; group = <0>; clocks = <&CLK_pwm>; clk-select = <0>; interrupts=<GIC_SPI INT_IRQ_PWM IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; pwm1: pwm@0x1F203280 { compatible = "sstar,pwm"; reg = <0x1F203280 0x37>; #pwm-cells = <3>; channel = <1>; group = <0>; clocks = <&CLK_pwm>; clk-select = <0>; interrupts=<GIC_SPI INT_IRQ_PWM IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; pwm2: pwm@0x1F203300 { compatible = "sstar,pwm"; reg = <0x1F203300 0x37>; #pwm-cells = <3>; channel = <2>; group = <0>; clocks = <&CLK_pwm>; clk-select = <0>; interrupts=<GIC_SPI INT_IRQ_PWM IRQ_TYPE_LEVEL_HIGH>; status = "ok"; }; #endif #if IS_ENABLED(CONFIG_SSTAR_IR) ir: ir@1F007A00 { compatible = "sstar,ir"; reg = <0x1F007A00 0x200>; clocks = <&CLK_ir>; interrupts = <GIC_SPI INT_FIQ_IR IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI INT_FIQ_IR_RC IRQ_TYPE_LEVEL_HIGH>; group = <0>; /* * decode mode selection * FULL 1 Format: NEC/NECX * RAW 2 Format: NEC/NECX * RC5 3 Format: RC5 * SW 4 Format: / */ mode = <2>; //choose enum rc_proto for sw mode protocol = <9>; vendor = <0x000E>; product = <0x3412>; //rc-map-table = <customer_code + command_code input_key_code> rc-map-table = //NEC Remote Control NO.1 <0x00FFA8 KEY_POWER>, <0x00FFC0 KEY_F5>, <0x00FFDD KEY_GREEN>, <0x00FF44 KEY_F19>, <0x00FFCA KEY_UP>, <0x00FFD2 KEY_DOWN>, <0x00FF99 KEY_LEFT>, <0x00FFC1 KEY_RIGHT>, <0x00FFCE KEY_ENTER>, <0x00FFCB KEY_BACK>, <0x00FF87 KEY_HOMEPAGE>, <0x00FF97 KEY_COMPOSE>, <0x00FF41 KEY_PLAYPAUSE>, <0x00FF0F KEY_F16>, <0x00FF60 KEY_F20>, <0x00FF90 KEY_VOLUMEUP>, <0x00FF98 KEY_VOLUMEDOWN>, <0x00FFD1 KEY_MUTE>, //NEC Remote Control NO.2 <0x807F46 KEY_POWER>, <0x807F50 KEY_0>, <0x807F49 KEY_1>, <0x807F55 KEY_2>, <0x807F59 KEY_3>, <0x807F4D KEY_4>, <0x807F51 KEY_5>, <0x807F5D KEY_6>, <0x807F48 KEY_7>, <0x807F54 KEY_8>, <0x807F58 KEY_9>, <0x807F47 KEY_RED>, <0x807F4B KEY_GREEN>, <0x807F57 KEY_YELLOW>, <0x807F5B KEY_BLUE>, <0x807F52 KEY_UP>, <0x807F13 KEY_DOWN>, <0x807F06 KEY_LEFT>, <0x807F1A KEY_RIGHT>, <0x807F0F KEY_ENTER>, <0x807F1F KEY_CHANNELUP>, <0x807F19 KEY_CHANNELDOWN>, <0x807F16 KEY_VOLUMEUP>, <0x807F15 KEY_VOLUMEDOWN>, <0x807F03 KEY_PAGEUP>, <0x807F05 KEY_PAGEDOWN>, <0x807F17 KEY_HOME>, <0x807F07 KEY_MENU>, <0x807F1B KEY_BACK>, <0x807F5A KEY_MUTE>, <0x807F0D KEY_RECORD>, <0x807F42 KEY_HELP>, <0x807F14 KEY_INFO>, <0x807F40 KEY_KP0>, <0x807F04 KEY_KP1>, <0x807F0E KEY_REWIND>, <0x807F12 KEY_FORWARD>, <0x807F4C KEY_ZOOM>, <0x807F02 KEY_PREVIOUSSONG>, <0x807F1E KEY_NEXTSONG>, <0x807F01 KEY_PLAY>, <0x807F1D KEY_PAUSE>, <0x807F11 KEY_STOP>, <0x807F44 KEY_AUDIO>, <0x807F56 KEY_CAMERA>, <0x807F5C KEY_CHANNEL>, <0x807F45 KEY_SLEEP>, <0x807F4A KEY_EPG>, <0x807F10 KEY_LIST>, <0x807F53 KEY_SUBTITLE>, <0x807F41 KEY_FN_F1>, <0x807F4E KEY_FN_F2>, <0x807F0A KEY_FN_F3>, <0x807F09 KEY_FN_F4>, <0x807F1C KEY_FN_F5>, <0x807F08 KEY_FN_F6>, <0x807F0B KEY_F1>, <0x807F18 KEY_F2>, <0x807F00 KEY_F3>, <0x807F0C KEY_F4>, <0x807F4F KEY_F5>, <0x807F5E KEY_F6>, <0x807F43 KEY_F7>, <0x807F5F KEY_F8>, <0x807FFE KEY_POWER2>, <0x807FFF KEY_OK>, //RC5 Remote Control <0x150C KEY_POWER>, <0x153F KEY_AUX>, <0x141D KEY_MEDIA_REPEAT>, <0x141C KEY_SHUFFLE>, <0x100D KEY_MUTE>, <0x104F KEY_F4>, <0x143F KEY_F1>, <0x112D KEY_F2>, <0x112E KEY_F3>, <0x1010 KEY_VOLUMEUP>, <0x1011 KEY_VOLUMEDOWN>, <0x1521 KEY_PREVIOUSSONG>, <0x1520 KEY_NEXTSONG>, <0x1536 KEY_PAUSE>, <0x1535 KEY_PLAY>, <0x151F KEY_BACK>, <0x151E KEY_FORWARD>, <0x1063 KEY_MAX>, <0x1040 KEY_F6>, <0x1120 KEY_CHANNELUP>, <0x1121 KEY_CHANNELDOWN>; status = "ok"; }; #endif #if IS_ENABLED(CONFIG_USB_SUPPORT) usb2phy1_utmi: utmi@0x1f284200 { compatible="syscon"; reg = <0x1f284200 0x200>; reg-io-width = <2>; }; usb2phy1_bc: bc@0x1f284400 { compatible="syscon"; reg = <0x1f284400 0x200>; reg-io-width = <2>; }; usb2phy1_usbc: usbc@0x1f284600 { compatible="syscon"; reg = <0x1f284600 0x200>; reg-io-width = <2>; }; usb2phy1_uhc: uhc@0x1f284800 { compatible="syscon"; reg = <0x1f284800 0x200>; reg-io-width = <2>; }; sstar_u2phy1: u2phy1 { compatible = "sstar, u2phy1"; syscon-utmi = <&usb2phy1_utmi>; syscon-uhc = <&usb2phy1_uhc>; syscon-usbc = <&usb2phy1_usbc>; syscon-bc = <&usb2phy1_bc>; //utmi_dp_dm_swap = <0>; #phy-cells = <0>; status = "okay"; }; #endif #if IS_ENABLED(CONFIG_USB_EHCI_HCD) sstar-ehci-1 { compatible = "sstar-ehci-1"; reg-names = "ehc_base"; reg = <0x1f284800 0x200>; syscon-utmi = <&usb2phy1_utmi>; syscon-usbc = <&usb2phy1_usbc>; syscon-bc = <&usb2phy1_bc>; clocks = <&CLK_upll_960m>; interrupts = <GIC_SPI INT_IRQ_UHC IRQ_TYPE_LEVEL_HIGH>; phys = <&sstar_u2phy1>; phy-names = "usb"; support_high_2g_access_patch; //gpio_vbus_power = <PAD_GPIO8>; status = "ok"; }; #endif #if IS_ENABLED(CONFIG_USB_SUPPORT) msb250x-udc-p0 { compatible = "sstar,msb250x-udc"; reg = <0x1f284200 0x200>, <0x1f284600 0x200>, <0x1f284a00 0x400>, <0x1f203c00 0x200>; reg-names = "utmi", "usb0", "otg", "chiptop"; interrupts = <GIC_SPI INT_IRQ_OTG IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msb250x_udc_p0"; maximum-speed = "high-speed"; ep_name = "ep0", "ep1" , "ep2", "ep3", "ep4", "ep5", "ep6"; ep_maxpkt_limit = <64>, <1024>, <1024>, <64>, <512>, <512>, <64>; ep_fifo_size = <64>, <8192>, <1024>, <64>, <512>, <512>, <64>; dma_channel_num = <7>; clocks = <&CLK_upll_960m>; status = "okay"; }; #endif }; }; &clks { #include "../../../../drivers/sstar/include/iford/reg_clks.h" #if defined(CONFIG_SSTAR_DUALOS_DRIVER) #include "iford-clks-dualos-lite.dtsi" #else #include "iford-clks.dtsi" #endif };
10-11
【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍了基于Matlab的建模与仿真方法。通过对四轴飞行器的动力学特性进行分析,构建了非线性状态空间模型,并实现了姿态与位置的动态模拟。研究涵盖了飞行器运动方程的建立、控制系统设计及数值仿真验证等环节,突出非线性系统的精确建模与仿真优势,有助于深入理解飞行器在复杂工况下的行为特征。此外,文中还提到了多种配套技术如PID控制、状态估计与路径规划等,展示了Matlab在航空航天仿真中的综合应用能力。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及从事无人机系统开发的工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:①用于四轴飞行器控制系统的设计与验证,支持算法快速原型开发;②作为教学工具帮助理解非线性动力学系统建模与仿真过程;③支撑科研项目中对飞行器姿态控制、轨迹跟踪等问题的深入研究; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注动力学建模与控制模块的实现细节,同时可延伸学习文档中提及的PID控制、状态估计等相关技术内容,以全面提升系统仿真与分析能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值