当前位置:首页>Linux>嵌入式Linux嵌入式Linux驱动开发:板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环

嵌入式Linux嵌入式Linux驱动开发:板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环

  • 2026-06-30 14:35:34
嵌入式Linux嵌入式Linux驱动开发:板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环

嵌入式Linux嵌入式Linux驱动开发:板级DTS实操与完整实战演练——从修改设备树到点亮LED的完整闭环

仓库已经开源!所有教程,主线内核移植,跑新版本imx-linux/uboot都在这里,或者一起来尝试跑7.0的Linux!欢迎各位大佬观摩!喜欢的话点个⭐!

仓库地址:https://github.com/Awesome-Embedded-Learning-Studio/imx-forge

静态网页:https://awesome-embedded-learning-studio.github.io/imx-forge/

前言:从理论到实践的跨越

跟着教程一路走过来,你现在应该对设备树有了相当全面的了解:知道它是什么、语法怎么写、OF API 怎么用。上一章我们也完成了从硬编码驱动到设备树驱动的改造。但说实话,这些知识如果不动手,永远只是"纸上谈兵"。

很多朋友在这个阶段会遇到一个尴尬的问题:教程里的示例都看懂了,但面对自己手里的开发板,却不知道从哪里下手。厂商给的设备树文件一大堆,动辄几千行,看着就头皮发麻。这一章,我们要把之前学的所有知识串起来,从空白开始走完整个流程:确认板级 DTS 位置、编写 DTS 文件、编译 DTB、编写驱动代码、编译驱动模块、部署到板子、加载驱动测试。这六步走完,你就真正掌握了设备树驱动开发的完整闭环。

我们的实验目标是点亮 LED。这个实验足够简单,不会让你在硬件调试上浪费太多时间,同时又涵盖了设备树驱动的所有核心要素——描述硬件,而不是编码硬件,这就是现代驱动开发的分水岭。


环境准备:先搞清楚我们在改什么

在动手之前,最重要的一步是搞清楚"我们要改什么"。

确认开发板型号

首先确认你手里的开发板型号。最可靠的方法是看串口启动信息,你会看到类似这样的输出:

Model: Freescale i.MX6 UltraLite 14x14 EVK Board

或者:

Machine: ALIENTEK ATK-IMX6ULL

找到板级 DTS 文件

确认板子型号之后,找到对应的 DTS 文件。在我们的 imx-forge 项目中,设备树文件存放在 driver/device_tree/alpha-board/ 目录下。如果使用 NXP 官方 BSP,通常在内核源码的 arch/arm/boot/dts/ 目录下。

典型的设备树目录结构:

arch/arm/boot/dts/
├── imx6ull.dtsi              # SOC 级通用定义(类似 C 语言头文件)
├── imx6ull-14x14-evk.dts     # 官方 EVK 板级文件
├── imx6ull-14x14-evk.dtb     # 编译后的二进制文件
└── ...

三种文件的区别:

  • .dtsi
    :SOC 级或模块级的通用定义,可被多个 .dts 引用
  • .dts
    :具体的板级定义,包含这块板子特有的硬件配置
  • .dtb
    :编译后的二进制设备树,内核真正读取的文件

重要原则:永远不要直接修改 .dtsi 文件! 这些文件是公用的,修改会影响所有引用它的板子。正确做法是在你的 .dts 文件里通过引用标签来修改或追加内容。

备份原有文件

修改之前养成备份的习惯:

# 备份原始文件
cp imx6ull-aes-led.dts imx6ull-aes-led.dts.bak

# 或者用 git
git stash save "修改前的备份"
git checkout -b experiment/device-tree-modification

步骤1:编写 DTS 设备树文件

确定寄存器地址

根据 IMX6ULL 芯片手册,控制 LED 需要操作以下寄存器:

寄存器
地址
用途
CCM_CCGR1
0x020C406C
时钟使能
SW_MUX_GPIO1_IO03
0x020E0068
GPIO 复用
SW_PAD_GPIO1_IO03
0x020E02F4
GPIO 电气属性
GPIO1_DR
0x0209C000
GPIO 数据
GPIO1_GDIR
0x0209C004
GPIO 方向

编写设备节点

打开设备树文件(在我们的项目中位于 driver/device_tree/alpha-board/device_tree_try_03/imx6ull-aes-led.dts),在根节点 / 下添加 LED 节点:

/dts-v1/;
#include "imx6ull.dtsi"
#include "imx6ull-aes.dtsi"

/ {
    model = "Awesome Embedded Studio IMX6ULL Example Driver";
    compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";

    imx_aes_led {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "atkalpha-led";
        status = "okay";
        reg = < 0X020C406C 0X04    /* CCM_CCGR1_BASE */
                0X020E0068 0X04    /* SW_MUX_GPIO1_IO03_BASE */
                0X020E02F4 0X04    /* SW_PAD_GPIO1_IO03_BASE */
                0X0209C000 0X04    /* GPIO1_DR_BASE */
                0X0209C004 0X04 >; /* GPIO1_GDIR_BASE */
    };
};

逐行解析关键部分:

  • 节点名 imx_aes_led
    :直接挂在根节点下,完整路径是 /imx_aes_led,驱动代码通过这个路径查找节点
  • #address-cells = <1>
    :子节点 reg 属性中,地址占 1 个单元格(32 位)
  • #size-cells = <1>
    :子节点 reg 属性中,长度占 1 个单元格(32 位)
  • compatible = "atkalpha-led"
    :驱动匹配标识,平台设备驱动中会用它来自动匹配
  • status = "okay"
    :设备启用;如果设为 "disabled",内核会跳过这个设备
  • reg 属性
    :寄存器地址列表,格式为"地址1 长度1 地址2 长度2...",5 个寄存器共 10 个 u32 值

新手易踩的坑:reg 里的数字必须严格遵循 #address-cells 和 #size-cells 定义的格式。我们定义了都是 1,所以格式就是地址、长度、地址、长度……以此类推。

节点位置选择

你可能会问:为什么把这个节点直接放在根节点下面?答案取决于设备连接方式:

  • 设备挂在 SOC 内部总线上(比如直接操作 GPIO 寄存器)→ 放在根节点下
  • 设备挂在外部总线上(I2C、SPI)→ 放在对应的总线节点下

如果需要修改现有节点而不是添加新节点,可以通过 &label 引用:

&i2c1 {
    clock-frequency = <100000>;
    status = "okay";  /* 覆盖原来的 "disabled" */

    mag3110@0e {
        compatible = "fsl,mag3110";
        reg = <0x0e>;
    };
};

语法检查

编译之前先检查语法:

dtc -I dts -O dtb -o /dev/null imx6ull-aes-led.dts

没有报错就说明语法基本正确。


步骤2:编译 DTB

内核只能读取二进制的 DTB 文件,不能直接读取 DTS 文本文件。

使用构建脚本

在 imx-forge 项目中最简单的方式:

cd /home/charliechen/imx-forge
./scripts/driver_helper/build_driver.sh device_tree_try_03 alpha-board

脚本会自动完成:查找源码和设备树文件 → 编译驱动生成 .ko → 编译设备树生成 .dtb → 产物放到 out/driver_artifacts/device_tree_try_03/alpha-board/

手动编译

# 基本编译
dtc -I dts -O dtb -o imx6ull-aes-led.dtb imx6ull-aes-led.dts

# 带 include 路径(DTS 引用了其他文件时)
dtc -I dts -O dtb -i driver/device_tree/alpha-board/ \
    -o imx6ull-aes-led.dtb \
    driver/device_tree/alpha-board/device_tree_try_03/imx6ull-aes-led.dts

反编译验证

把编译出来的 DTB 反编译回 DTS 格式,对比确认正确性:

dtc -I dtb -O dts -o test_from_dtb.dts imx6ull-aes-led.dtb
grep -A 10 "imx_aes_led" test_from_dtb.dts

反编译的 DTS 在格式上可能和原始 DTS 有差异,但节点结构和属性值应该一致。


步骤3:编写设备树驱动代码

设备树准备好了,现在编写驱动。核心逻辑:去设备树里把刚才填的值"抠"出来,然后操作寄存器控制 LED

我们的驱动代码分为两个文件:led_hw.c 负责硬件操作,device_tree_try_03_driver_main.c 负责字符设备框架。这种分离让代码结构更清晰,也便于以后复用。

头文件与结构体

#include<linux/of.h>
#include<linux/of_address.h>

structled_handle {
void __iomem* ccm_ccgr1;
void __iomem* sw_mux_gpio;
void __iomem* sw_pad_gpio;
void __iomem* gpio_dr;
void __iomem* gpio_gdir;
structdevice_nodedevice_tree_node;
};

staticstructled_handleled;

linux/of.h 提供设备树基础 API(of_find_node_by_pathof_property_read_string 等),linux/of_address.h 提供地址映射 API(of_iomap)。结构体最后一个成员 device_tree_node 保存设备树节点指针,后续所有操作都靠它。

硬件初始化:从设备树获取信息

真正的重头戏在 led_hw_init 里——数据从 DTS 流向内核内存,再流向驱动变量:

intled_hw_init(void) {
    u32 regdata[10];
int ret;
constchar* str;
structpropertyproper;
    u32 val;

/* 1. 获取设备节点 */
    led.device_tree_node = of_find_node_by_path("/imx_aes_led");
if (led.device_tree_node == NULL) {
        pr_err("dtsled node can not found!\n");
return -EINVAL;
    }
    pr_info("dtsled node has been found!\n");

第一步:找人。of_find_node_by_path 就像在电话簿里按名字找人。路径必须和 DTS 里写的一样(包括根节点 /)。如果返回 NULL,说明设备树里没这个节点或者路径写错了。

注意:of_find_node_by_path 成功时会增加节点引用计数,用完后必须调用 of_node_put 释放,否则会内存泄漏。

/* 2. 获取 compatible 属性(验证性读取) */
    proper = of_find_property(led.device_tree_node, "compatible"NULL);
if (proper == NULL) {
        pr_err("compatible property find failed\n");
    } else {
        pr_info("compatible = %s\n", (char*)proper->value);
    }

第二步:查户口。of_find_property 找具体的属性,proper->value 指向属性值的原始数据。对于字符串属性,可以直接转成 char* 打印。这里主要是验证性读取——我们通过路径查找节点而非通过 compatible 匹配,所以失败也不中断。

/* 3. 获取 status 属性 */
    ret = of_property_read_string(led.device_tree_node, "status", &str);
if (ret < 0) {
        pr_err("status read failed!\n");
    } else {
        pr_info("status = %s\n", str);
    }

第三步:看状态。of_property_read_string 专读字符串属性。标准值是 "okay"(可用)和 "disabled"(禁用)。第三个参数是 const char**,函数会把字符串地址存到这个指针指向的位置,不需要调用者手动释放内存。

/* 4. 获取 reg 属性(关键) */
    ret = of_property_read_u32_array(led.device_tree_node, "reg", regdata, 10);
if (ret < 0) {
        pr_err("reg property read failed!\n");
        of_node_put(led.device_tree_node);
return -EINVAL;
    }

    pr_info("reg data:\n");
for (int i = 0; i < 10; i++) {
        pr_cont("%#X ", regdata[i]);
    }
    pr_cont("\n");

第四步:拿地址。 DTS 里 5 组寄存器,每组"地址+长度"两个值,共 10 个 u32。执行完这一句,regdata 数组里就存满了我们在 DTS 里写的那串十六进制数字。

注意:这里读取失败时我们手动调用了 of_node_put 释放节点引用,因为直接 return 了,不会走到后面的统一清理逻辑。这个细节很容易遗忘,但忘记释放会导致内存泄漏。

内存映射:使用 of_iomap

拿到了物理地址,下一步是映射。of_iomap 可以直接从 reg 属性中取第 N 组地址进行映射:

/* 5. 使用 of_iomap 进行寄存器地址映射 */
    led.ccm_ccgr1 = of_iomap(led.device_tree_node, 0);
    led.sw_mux_gpio = of_iomap(led.device_tree_node, 1);
    led.sw_pad_gpio = of_iomap(led.device_tree_node, 2);
    led.gpio_dr = of_iomap(led.device_tree_node, 3);
    led.gpio_gdir = of_iomap(led.device_tree_node, 4);

if (!led.ccm_ccgr1 || !led.sw_mux_gpio || !led.sw_pad_gpio ||
        !led.gpio_dr || !led.gpio_gdir) {
        pr_err("ioremap failed!\n");
        of_node_put(led.device_tree_node);
return -ENOMEM;
    }

of_iomap(node, index) 的设计非常巧妙:驱动代码不需要知道具体的地址值,只需要知道"我需要第几个寄存器"。索引 0 对应 reg 属性第一组 0X020C406C 0X04,索引 1 对应第二组,以此类推。具体的地址是什么,那是设备树的事情。 换一块板子,只需要改设备树文件,驱动代码完全不用动。

of_iomap 内部会调用 ioremap,失败时返回 NULL。它还会自动处理 reg 属性中的地址转换(某些架构上设备树地址可能不是直接的物理地址)。

配置寄存器

映射完成后,操作寄存器和硬编码版本完全一样:

/* 6. 使能 GPIO1 时钟 */
    val = readl(led.ccm_ccgr1);
    val &= ~(3 << 26);
    val |= (3 << 26);
    writel(val, led.ccm_ccgr1);

/* 7. 设置 GPIO1_IO03 复用为 GPIO */
    writel(5, led.sw_mux_gpio);

/* 8. 设置 GPIO1_IO03 电气属性 */
    writel(0x10B0, led.sw_pad_gpio);

/* 9. 设置 GPIO1_IO03 为输出 */
    val = readl(led.gpio_gdir);
    val |= (1 << 3);
    writel(val, led.gpio_gdir);

/* 10. 默认关闭 LED(高电平) */
    val = readl(led.gpio_dr);
    val |= (1 << 3);
    writel(val, led.gpio_dr);

    pr_info("LED Init OK!\n");
return0;
}

无论地址来自硬编码还是设备树,硬件寄存器的操作方式不变。这正是"配置与代码分离"的好处。

LED 控制与资源清理

voidled_set_status(bool status) {
    u32 val = readl(led.gpio_dr);
if (status) {
        val &= ~(1 << 3); /* 低电平点亮 */
    } else {
        val |= (1 << 3);  /* 高电平熄灭 */
    }
    writel(val, led.gpio_dr);
}

boolled_get_status(void) {
    u32 val = readl(led.gpio_dr);
return (val & (1 << 3)) == 0;
}

voidled_hw_deinit(void) {
if (led.ccm_ccgr1) { iounmap(led.ccm_ccgr1); led.ccm_ccgr1 = NULL; }
if (led.sw_mux_gpio) { iounmap(led.sw_mux_gpio); led.sw_mux_gpio = NULL; }
if (led.sw_pad_gpio) { iounmap(led.sw_pad_gpio); led.sw_pad_gpio = NULL; }
if (led.gpio_dr) { iounmap(led.gpio_dr); led.gpio_dr = NULL; }
if (led.gpio_gdir) { iounmap(led.gpio_gdir); led.gpio_gdir = NULL; }

if (led.device_tree_node) {
        of_node_put(led.device_tree_node);
        led.device_tree_node = NULL;
    }
}

资源清理的几个要点:

  1. 检查 NULL 再释放
     — 防止 led_hw_deinit 被调用两次时的双重释放
  2. 释放后置 NULL
     — 防止悬空指针,错误使用时至少触发空指针异常而非内存破坏
  3. 最后调用 of_node_put
     — 释放设备树节点引用,这是设备树 API 的要求

字符设备框架代码(file_operations、cdev、class、device 等)和传统驱动完全一样,此处不再赘述,完整代码请参考项目中的 device_tree_try_03_driver_main.c


步骤4:编译驱动模块

驱动代码写好了,编译生成 .ko 文件。

使用构建脚本

cd /home/charliechen/imx-forge
./scripts/driver_helper/build_driver.sh device_tree_try_03 alpha-board

脚本会自动处理:设置交叉编译工具链 → 指定内核源码路径 → 调用 make 编译 → 产物放到输出目录。

手动编译

cd driver/device_tree_try_03/alpha-board
make

Makefile 大致如下:

obj-m := device_tree_try_03_driver.o
device_tree_try_03_driver-y := device_tree_try_03_driver_main.o led_hw.o

ARCH := arm
CROSS_COMPILE := arm-none-linux-gnueabihf-
KDIR := $(PROJECT_ROOT)/third_party/linux-${KERNEL_TYPE}

modules:
$(MAKE) -C $(KDIR) M=$(CURDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules

注意驱动由两个 .o 文件组成,链接成一个 .ko 模块。

检查编译结果

ls -lh out/driver_artifacts/device_tree_try_03/alpha-board/
# 预期产物:
# device_tree_try_03_driver.ko    (约14K)
# imx6ull-aes-led.dtb             (约35K)

modinfo device_tree_try_03_driver.ko
# 查看 vermagic 确认内核版本匹配

如果 vermagic 显示的内核版本和板子运行的内核不一致,模块加载会因版本不匹配而失败。


步骤5:部署到板子

编译好了 .ko 和 .dtb,部署到开发板上。

部署 DTB 文件(TFTP)

# 使用部署脚本
./scripts/driver_helper/deploy_driver.sh device_tree_try_03 alpha-board --target=tftp

# 或手动拷贝
sudocp out/driver_artifacts/device_tree_try_03/alpha-board/imx6ull-aes-led.dtb \
    /srv/tftp/imx6ull-aes.dtb

注意目标文件名是 imx6ull-aes.dtb,不是 imx6ull-aes-led.dtb。U-Boot 启动时加载的 DTB 文件名由环境变量 fdt_file 决定:

=> printenv fdt_file
fdt_file=imx6ull-aes.dtb

如果不确定自己的板子用哪个文件名,在 U-Boot 命令行输入 printenv 查看。

部署 KO 文件

# 通过 NFS
./scripts/driver_helper/deploy_driver.sh device_tree_try_03 alpha-board --target=nfs

# 或通过 scp
scp device_tree_try_03_driver.ko root@192.168.1.100:/lib/modules/

重启并验证设备树

部署 DTB 后重启板子,验证设备树是否正确加载:

# 查看节点是否存在
ls /proc/device-tree/imx_aes_led/

# 查看属性
cat /proc/device-tree/imx_aes_led/compatible
# 输出:atkalpha-led

cat /proc/device-tree/imx_aes_led/status
# 输出:okay

hexdump -C /proc/device-tree/imx_aes_led/reg
# 输出寄存器地址列表

如果节点不存在,说明 DTB 没有正确加载或者节点路径写错了。如果属性值不对,说明 DTS 里的属性定义有问题。


步骤6:加载驱动测试

终于到了见证结果的时刻。

加载驱动

insmod device_tree_try_03_driver.ko

# 查看内核日志
dmesg | tail -30

预期日志:

[   12.345678] dtsled node has been found!
[   12.345679] compatible = atkalpha-led
[   12.345680] status = okay
[   12.345681] reg data:
[   12.345682] 0X20C406C 0X4 0X20E0068 0X4 0X20E02F4 0X4 0X209C000 0X4 0X209C004 0X4
[   12.345683] LED Init OK!
[   12.345684] LED handle get the device number: major: 245, minor: 0

这串日志意味着:内核找到了 imx_aes_led 节点、成功读取了属性、reg data 和 DTS 文件中写的完全一致、寄存器映射成功、字符设备创建成功。

测试 LED 控制

# 检查设备文件
ls -l /dev/AES_LED

# 点亮 LED(低电平有效)
echo 1 > /dev/AES_LED

# 熄灭 LED
echo 0 > /dev/AES_LED

# 读取 LED 状态
cat /dev/AES_LED

看板子上的 LED,亮了吗?如果亮了,恭喜——你完成了完整的设备树驱动开发!

卸载驱动

rmmod device_tree_try_03_driver
dmesg | tail
# [  234.567890] Deinit LED Hardware

调试技巧与常见问题

即使严格按教程操作,也可能会遇到各种问题。这里总结最常见的坑点。

dmesg 日志分析

dmesg 是你最好的调试朋友:

dmesg | tail -20           # 最近的消息
dmesg | grep -i "led"# 过滤关键词
dmesg -w                   # 实时监控

常见错误排查

dtsled node can not found! — 节点找不到

  • 检查节点路径(注意大小写和前导 /
  • 检查 DTB 是否正确部署
  • 在 /proc/device-tree 中查看节点是否存在

reg property read failed! — reg 属性读取失败

  • 检查 DTS 中 reg 属性是否存在
  • 确认格式正确(地址和长度成对出现)
  • 用 hexdump -C /proc/device-tree/imx_aes_led/reg 查看实际值

ioremap failed! — 内存映射失败

  • reg 属性中的地址可能无效
  • of_iomap 的索引可能超出 reg 属性中定义的组数
  • 检查是否已有其他驱动占用了这些地址

编译通过但内核报 "Duplicate node" — 节点重复

  • 你在 .dts 里定义了一个 .dtsi 里已存在的节点
  • 改用 &label 引用现有节点,或用 /delete-node/ 删除

DTB 部署后不生效 — 加载的不是你的 DTB

  • U-Boot 中执行 printenv fdt_file 确认加载的文件名
  • 检查 TFTP 目录下是否有旧文件
  • 手动在 U-Boot 里加载:tftp 0x83000000 imx6ull-aes.dtb; bootm 0x80800000 - 0x83000000

DTC 编译报错 "FDT_ERR_BADSTRUCTURE" — 编译失败但信息模糊

  • 检查所有 #include 指令,确保文件存在
  • 用 -i 选项指定 include 路径
  • 单独编译被 include 的 .dtsi 文件排查

系统排查清单

按以下顺序逐一排查:

  1. 设备树是否加载?
     — /proc/device-tree 中有无对应节点
  2. 驱动是否加载?
     — lsmod 中有无模块,dmesg 有无报错
  3. 设备文件是否创建?
     — /dev 目录下有无设备文件,权限是否正确
  4. 硬件是否正常?
     — LED 连接的 GPIO 是否正确,用万用表测量电平
  5. 驱动逻辑是否正确?
     — 添加更多调试打印,或用 strace 跟踪用户态调用

总结

这一章我们把所有知识串起来,走完了从修改设备树到点亮 LED 的完整闭环。回顾一下:

  • 环境准备
    :确认板子型号、找到 DTS 文件、备份
  • 编写 DTS
    :在设备树中"描述"硬件,而不是在代码中"编码"硬件
  • 编译 DTB
    :用构建脚本或手动 DTC 编译
  • 编写驱动
    :通过 OF API 从设备树获取硬件信息,用 of_iomap 映射寄存器
  • 编译部署
    :交叉编译 .ko 模块,通过 TFTP/NFS 部署到板子
  • 测试验证
    :加载驱动、测试功能、分析日志

核心思想只有一个:把"硬件描述"和"驱动逻辑"彻底解耦。驱动只负责"怎么操作一个 GPIO",设备树负责"这个 GPIO 在哪里"。以前移植驱动需要改代码重新编译 .ko,现在只需改 .dts 重新编译 DTB(几秒钟的事),驱动代码连动都不用动

这就是 Linux 内核引入设备树模型的初衷,也是构建可移植嵌入式系统的基石。

当然,我们展示的还是最基础的使用方式。在实际工程中,你还会遇到中断、DMA、时钟、电源管理……这些都可以通过设备树描述,但万变不离其宗。在未来的学习中,你会接触到 Platform 设备驱动框架,届时你会发现今天折腾的 device_node 和 OF 函数,在 Platform 驱动里以更标准、更优雅的方式被封装起来。

现在,找一块开发板,把这一章的流程完整走一遍。只有在实践中,理论才能变成你自己的技能。


相关阅读

  1. 04. OF API 基础与验证——从 DTS 到代码的桥梁 - 相似度 100%

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 16:52:18 HTTP/2.0 GET : https://f.mffb.com.cn/a/494311.html
  2. 运行时间 : 0.136688s [ 吞吐率:7.32req/s ] 内存消耗:4,992.59kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=bbae33934359dbf79ec82f06060383c2
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000572s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000904s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000360s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000271s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000479s ]
  6. SELECT * FROM `set` [ RunTime:0.000207s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000532s ]
  8. SELECT * FROM `article` WHERE `id` = 494311 LIMIT 1 [ RunTime:0.000499s ]
  9. UPDATE `article` SET `lasttime` = 1783068738 WHERE `id` = 494311 [ RunTime:0.004265s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000307s ]
  11. SELECT * FROM `article` WHERE `id` < 494311 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000503s ]
  12. SELECT * FROM `article` WHERE `id` > 494311 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002054s ]
  13. SELECT * FROM `article` WHERE `id` < 494311 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.020860s ]
  14. SELECT * FROM `article` WHERE `id` < 494311 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.010942s ]
  15. SELECT * FROM `article` WHERE `id` < 494311 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.023161s ]
0.138294s