当前位置:首页>Linux>不懂 Linux SPI 驱动,看完这篇就明白了

不懂 Linux SPI 驱动,看完这篇就明白了

  • 2026-06-16 08:27:08
不懂 Linux SPI 驱动,看完这篇就明白了

在嵌入式 Linux 开发中,SPI 是使用率极高的高速串行通信总线,广泛用于驱动 Flash、显示屏、传感器、ADC 等外设。很多嵌入式开发者熟悉 SPI 基础协议与时序,但在接触 Linux 内核 SPI 驱动时,常常因为内核分层架构、总线匹配机制和设备树配置复杂而难以理解。相比于裸机单片机的简单寄存器操作,Linux SPI 驱动采用标准化总线框架,拥有固定的注册、匹配、传输流程,新手很容易混淆设备、总线与驱动三者的工作关系。

其实 Linux SPI 驱动有着清晰、固定的开发逻辑,并不需要死记复杂源码。本文将用通俗易懂的方式,从零讲解 Linux SPI 驱动的整体框架、分层原理、设备树匹配方式与数据传输流程,避开晦涩的底层源码堆砌,梳理核心工作机制。帮助新手快速理清 SPI 驱动的运行逻辑,彻底看懂 Linux SPI 通信的底层原理,解决开发中看不懂、写不出、调不通的常见问题。

一、温故 SPI 总线协议

面试题写作模版

1.1 什么是 SPI?

SPI,即串行外设接口(Serial Peripheral Interface) ,是一种高速、全双工、同步的通信总线,由摩托罗拉公司于上世纪 80 年代开发,在嵌入式系统中广泛应用,用于微控制器与各种外设之间的通信,如传感器、存储器、显示屏等。

SPI 采用主从架构,一个 SPI 系统中,必然有一个主设备,同时可以连接一个或多个从设备 。主设备就像乐队的指挥,掌控着整个通信的节奏和流程,负责发起通信并产生时钟信号(SCK);从设备则像乐队的成员,听从主设备的指挥,根据主设备提供的时钟信号进行数据的接收和发送。比如在一个智能手表的系统中,主控芯片作为 SPI 主设备,与作为从设备的心率传感器、加速度传感器等进行通信,获取各种数据。

SPI 通信硬件简单,通常仅需四条线即可完成通信,这四条线分别是:串行时钟线(SCK)、主机输出 / 从机输入数据线(MOSI)、主机输入 / 从机输出数据线(MISO)和从机选择线(SS/CS,Slave Select/Chip Select) 。这种简单的硬件架构,不仅节约了芯片的管脚资源,也让 PCB 的布局更加简洁,为电路设计带来了极大的便利。

1.2 SPI 硬件组成与信号解析

SPI 通信依靠四条信号线实现数据交互。MISO 为主入从出线路,负责从设备向主设备传输数据,比如主设备读取温度传感器信息时,传感器就通过这条线路传回数据。MOSI 为主出从入线路,用于主设备向从设备下发指令、地址和待写入数据,像主设备向 Flash 存储器保存数据,数据便会经由这条线路完成传输。

SCK 是由主设备产生的串行时钟信号,相当于通信的节拍器,用来同步主从设备的数据收发节奏,时钟频率越高,传输速度也就越快。SS/CS 为片选信号,在多从设备的系统中,主设备通过拉低对应电平选中目标设备,未被选中的设备保持静默,不会响应总线上的信号。

1.3 SPI 通信原理与过程

SPI 通信基于串行移位寄存器来实现数据传输。在通信前,主设备和从设备都配置好相同的通信参数,包括数据位宽、时钟极性(CPOL)、时钟相位(CPHA)以及数据传输顺序(MSB 先还是 LSB 先)等。以主设备向从设备发送数据 0x55(二进制为 01010101),同时从设备向主设备发送数据 0xAA(二进制为 10101010)为例:

  1. 片选阶段:主设备首先将目标从设备的 SS/CS 信号拉低,通知该从设备准备通信 。这就像是老师点名叫某个学生来回答问题,学生听到自己的名字后,就做好回答问题的准备。
  2. 时钟与数据传输阶段:主设备开始产生 SCK 时钟信号。在每个时钟周期内,主设备通过 MOSI 线将数据 0x55 的一位发送出去,从设备在 SCK 信号的边沿(根据 CPHA 的设置,可能是上升沿或下降沿)接收该位数据,并将其移入自己的移位寄存器;同时,从设备通过 MISO 线将数据 0xAA 的一位发送给主设备,主设备也在相应的时钟边沿接收该位数据并移入自己的移位寄存器 。这个过程就像是两个人在传递纸条,一个人写一个字递过去,另一个人同时也写一个字递回来,而且他们的动作要按照一定的节奏(时钟信号)来进行。
  3. 数据接收与处理阶段:经过 8 个时钟周期(假设数据位宽为 8 位),主设备和从设备都完成了一个字节数据的发送和接收。主设备将接收到的数据存储起来进行后续处理,从设备也同样处理接收到的数据 。比如主设备接收到从设备发送的温度数据后,可能会进行分析、显示等操作;从设备接收到主设备发送的控制指令后,会根据指令执行相应的动作。
  4. 通信结束阶段:主设备完成数据传输后,将 SS/CS 信号拉高,结束与该从设备的通信 。这就像是老师和学生交流完问题后,让学生坐下,结束这次交流。

二、Linux SPI 驱动架构剖析

面试题写作模版

2.1 驱动分层与分离设计思想

Linux 驱动设计秉持着分层与分离的精妙思想 ,这一思想在 SPI 驱动中展现得淋漓尽致。分层,就如同搭建高楼,每一层都有其独特的职责与功能。SPI 驱动主要分为核心层、主机控制器驱动层和设备驱动层 。核心层位于中间位置,起着承上启下的关键作用,它向上为设备驱动提供统一的 API 接口,向下则为不同的主机控制器驱动提供通用的管理机制 。

而分离思想,则是让主机控制器驱动和设备驱动各自专注于自己的领域 。主机控制器驱动负责与硬件层面的 SPI 控制器打交道,根据具体的硬件手册操作控制器,产生 SPI 总线上的各种波形信号,它不关心连接的具体外设是什么;设备驱动则聚焦于特定的外设,如温度传感器、Flash 存储器等,通过核心层提供的 API 来与主机控制器进行通信,无需了解主机控制器的硬件细节 。

这种分层与分离的设计,极大地提升了代码的可维护性、可扩展性以及复用性。比如,当更换不同型号的 SPI 主机控制器时,只需要修改主机控制器驱动层的代码,设备驱动层和核心层可以保持不变;同样,当连接新的 SPI 外设时,只需编写对应的设备驱动,主机控制器驱动和核心层也无需改动 。

2.2 核心层功能与关键 API

SPI 核心层是整个 SPI 驱动架构的中枢神经,它承担着注册 SPI 总线、管理 SPI 设备和驱动的注册与匹配,以及提供通用的 SPI 通信 API 等重要职责。在 SPI 核心层中,有许多关键的 API,它们是开发者与 SPI 驱动交互的重要工具。

①spi_register_driver (struct spi_driver *sdrv):用于注册一个 SPI 设备驱动。当我们编写好一个 SPI 设备驱动,想要让内核识别并使用它时,就需要调用这个函数。例如,我们为一个 SPI 接口的加速度传感器编写了驱动,通过 spi_register_driver 将其注册到内核中,内核就会开始管理这个驱动,并在合适的时候调用它的相关函数。

// SPI 驱动注册示例(对应 spi_register_driver)staticstruct spi_driver spi_sensor_driver = {    .probe = sensor_probe,      // 设备匹配成功后执行    .remove = sensor_remove,    // 设备移除时执行    .driver = {        .name = "spi_sensor",   // 驱动名        .owner = THIS_MODULE,    },};// 注册驱动到内核static int __init sensor_init(void){    return spi_register_driver(&spi_sensor_driver);}// 卸载驱动static void __exit sensor_exit(void){    spi_unregister_driver(&spi_sensor_driver);}module_init(sensor_init);module_exit(sensor_exit);

②spi_sync (struct spi_device *spi, struct spi_message *message):实现同步数据传输。它会阻塞当前线程,直到 SPI 数据传输完成。在实际应用中,当我们需要确保数据准确无误地传输完成后再进行下一步操作时,就可以使用 spi_sync。比如在向 SPI Flash 写入数据时,调用 spi_sync 可以保证数据完整写入后,再进行后续的处理,避免因数据传输未完成而导致的错误。

// SPI 同步传输示例(对应 spi_sync)struct spi_message msg;struct spi_transfer xfer = {    .tx_buf = write_buf,   // 要发送的数据    .rx_buf = read_buf,    // 接收数据的缓冲区    .len = 8,              // 数据长度};// 初始化并提交同步传输spi_message_init(&msg);spi_message_add_tail(&xfer, &msg);// 阻塞等待传输完成spi_sync(spi_dev, &msg);

2.3 主机驱动 spi_master 核心解析

spi_master 结构体是 SPI 主机驱动的核心数据结构,它就像是 SPI 主机控制器的 “身份名片”,包含了众多描述主机控制器特性和功能的成员。

①s16 bus_num:表示 SPI 主机控制器的编号。在一个系统中可能存在多个 SPI 主机控制器,bus_num 用于唯一标识每个控制器。比如,一个开发板上有两个 SPI 主机控制器,它们的 bus_num 可能分别为 0 和 1,通过这个编号,内核可以准确地区分和管理不同的控制器。

// 定义 SPI 主机编号,唯一标识控制器.bus_num = 0,   // 该主机控制器编号为 0

②u16 num_chipselect:定义了控制器支持的片选数量,即该控制器能够连接并控制的 SPI 从设备的数量。如果 num_chipselect 的值为 4,那就意味着这个 SPI 主机控制器最多可以连接 4 个 SPI 从设备,通过不同的片选信号来选择与之通信的从设备。

// 配置主机最多支持 4 个片选从设备.num_chipselect = 4,

③int (*setup)(struct spi_device *spi):这是一个函数指针,指向用于设置 SPI 设备工作参数的函数。在 SPI 设备与主机控制器进行通信前,需要对 SPI 设备的工作模式(如 CPOL、CPHA)、时钟频率等参数进行设置,setup 函数就是用来完成这些设置工作的。例如,我们可以在 setup 函数中设置 SPI 设备的工作模式为 SPI_MODE_0,时钟频率为 1MHz。

// SPI 主机 setup 配置函数示例static int my_spi_setup(struct spi_device *spi){    // 设置模式:SPI_MODE_0,时钟频率 1MHz    spi->mode = SPI_MODE_0;    spi->max_speed_hz = 1000000;    return 0;}// 挂载到 spi_master.setup = my_spi_setup,

④int (*transfer)(struct spi_device *spi, struct spi_message *mesg):同样是函数指针,指向 SPI 数据传输函数。当 SPI 设备需要进行数据传输时,就会调用 transfer 函数。它负责将 spi_message 结构体中包含的数据按照 SPI 协议的要求,通过主机控制器发送到 SPI 总线上,并接收从设备返回的数据。

// SPI 主机底层传输函数实现static int my_spi_transfer(struct spi_device *spi, struct spi_message *mesg){    // 调用硬件控制器,完成 SPI 数据收发    spi_hw_transfer(spi, mesg);    mesg->status = 0;    spi_message_complete(mesg);    return 0;}// 挂载到 spi_master.transfer = my_spi_transfer,

2.4 设备驱动 spi_driver 实现要点

spi_driver 结构体是 SPI 设备驱动的关键组成部分,它定义了设备驱动与内核交互的接口和行为。

①const struct spi_device_id *id_table:设备 ID 表,用于匹配设备驱动和设备。在这个表中,列出了该驱动能够支持的 SPI 设备的 ID。当内核检测到一个 SPI 设备时,会将设备的 ID 与 id_table 中的 ID 进行比对,如果匹配成功,就会调用该驱动的 probe 函数。

// SPI 设备 ID 匹配表示例(对应 id_table)static conststruct spi_device_id spi_sensor_ids[] = {    { "temp_sensor", 0 },   // 支持温度传感器    { "imu_sensor", 1 },    // 支持惯性传感器    { },};MODULE_DEVICE_TABLE(spi, spi_sensor_ids);

②int (*probe)(struct spi_device *spi):探测函数,当设备驱动与设备匹配成功后,内核会调用 probe 函数。在 probe 函数中,主要完成设备的初始化工作,例如申请设备资源(如内存、中断等)、设置设备的工作参数、创建设备节点等。以 SPI 温度传感器为例,在 probe 函数中,我们可以初始化传感器的寄存器,设置数据读取的格式和频率,同时创建一个设备节点,以便用户空间能够通过该节点与传感器进行交互。

// SPI 设备 probe 实现示例static int spi_sensor_probe(struct spi_device *spi){    // 1. 设置 SPI 通信模式、时钟    spi_setup(spi);    // 2. 初始化传感器硬件    sensor_init_reg(spi);    // 3. 创建设备节点,供用户层使用    misc_device_create(&sensor_dev);    printk("SPI 传感器探测成功\n");    return 0;}

probe 函数和 id_table 在设备驱动中至关重要,它们是设备驱动与设备建立联系的桥梁。准确实现 probe 函数,正确设置 id_table,是确保 SPI 设备驱动能够正常工作的关键。

三、SPI 设备与驱动的匹配机制

面试题写作模版

3.1 设备树匹配方式

在基于设备树(Device Tree)的嵌入式系统中,设备树匹配是 SPI 设备与驱动匹配的主要方式 。设备树是一种描述硬件资源的数据结构,它以树形结构组织,包含了系统中各种设备的信息,如设备的名称、地址、中断号、SPI 通信参数等 。

在设备树中,每个 SPI 设备都有一个对应的节点,节点中的 compatible 属性用于描述设备的兼容性信息 。例如,对于一个 SPI 接口的 Flash 存储器,其设备树节点可能如下:

spi1: spi@02100000 {    compatible = "fsl,imx6ul-ecspi", "fsl,imx6q-ecspi";    reg = <0x02100000 0x4000>;    interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;    status = "okay";    flash: flash@0 {        compatible = "micron,n25q128a13ef";        reg = <0>;        spi-max-frequency = <50000000>;    };};

其中,flash 节点的 compatible 属性值为"micron,n25q128a13ef",它表示这个设备是美光(Micron)公司的 N25Q128A13EF 型号的 SPI Flash 。

在 SPI 设备驱动中,会定义一个 of_match_table 数组,用于存储驱动支持的设备树 compatible 属性值 。例如:

static conststruct of_device_id my_spi_flash_of_match[] = {    {.compatible = "micron,n25q128a13ef"},    {},};MODULE_DEVICE_TABLE(of, my_spi_flash_of_match);

当内核启动时,会解析设备树,创建对应的 spi_device 对象 。同时,当 SPI 设备驱动注册时,内核会调用 of_driver_match_device 函数,将设备树节点的 compatible 属性值与驱动的 of_match_table 数组中的值进行比较 。如果找到匹配的项,就认为设备和驱动匹配成功,内核会调用驱动的 probe 函数,对设备进行初始化 。

3.2 ACPI 匹配与传统匹配

ACPI(Advanced Configuration and Power Interface,高级配置与电源管理接口)匹配主要用于 x86 平台以及一些支持 ACPI 的系统中 。在 ACPI 系统中,每个设备都有一个 ACPI 名称空间,通过硬件 ID(HID)和兼容 ID(CID)来标识设备 。SPI 设备驱动可以通过定义 acpi_match_table 数组来匹配 ACPI 设备 。例如:

static conststruct acpi_device_id my_spi_acpi_ids[] = {    {"ACPI0001", 0},  // 匹配 ACPI 设备的硬件 ID    {},};MODULE_DEVICE_TABLE(acpi, my_spi_acpi_ids);

当内核检测到 ACPI 设备时,会将设备的 HID 和 CID 与驱动的 acpi_match_table 中的值进行比较,若匹配成功,则完成设备与驱动的匹配 。

在没有设备树的情况下,SPI 设备与驱动的匹配采用传统的匹配方式 。一种方式是对比驱动 id_table 中的设备名 。驱动中定义 id_table 数组,包含支持的设备名称 。例如:

static conststruct spi_device_id my_spi_sensor_ids[] = {    {"my_sensor", 0},    {},};MODULE_DEVICE_TABLE(spi, my_spi_sensor_ids);

内核将 spi_device 的 modalias 与 id_table 中的设备名进行比较,若一致则匹配成功 。另一种方式是直接校验 spi_device 的 modalias 与驱动 name 是否一致 。若相同,也可认为设备与驱动匹配 。不过,随着设备树的广泛应用,这种传统匹配方式在现代嵌入式开发中使用相对较少 。

四、编写 SPI 驱动实战:以温度传感器为例

面试题写作模版

4.1 前期准备:硬件与内核环境搭建

开发 SPI 设备驱动前,首先要排查 SPI 控制器与外设的物理连接,重点检查 SCK、MOSI、MISO、SS/CS 四条核心信号线,以及供电、接地等辅助线路,线路的通断与稳定性直接决定 SPI 通信能否正常进行。其中 SCK 时钟线异常,会造成主从设备数据传输时序错乱;MOSI 主机输出线故障,会导致主机数据无法下发给从设备;MISO 从机输出线异常,主机就接收不到外设的反馈数据;而 SS/CS 片选线连接错误,主设备将无法精准匹配目标从设备,引发通信异常。我们可以借助万用表检测线路连通性,排查短路、断路、线路松动等问题,保障硬件基础连接稳定可靠。

硬件检查完成后,需要配置内核,开启 SPI 子系统与对应控制器的驱动支持,这是 SPI 驱动正常运行的软件基础。我们只需进入内核源码目录,执行 make menuconfig 命令打开内核配置界面,在设备驱动选项中开启 SPI 基础功能支持,同时根据开发板芯片型号,选中对应的 SPI 控制器驱动。除此之外,可根据开发需求灵活开启 SPI 调试、DMA 传输等辅助功能,方便后续开发调试工作。完成所有配置后保存退出,内核就具备了 SPI 设备的运行基础环境,后续即可开展 SPI 设备树配置与驱动开发工作。

4.2 定义设备 ID 表与兼容设备树节点

在 SPI 设备驱动中,需要声明支持的设备名列表和 OF 匹配表 。首先,定义设备 ID 表,它用于匹配设备驱动和设备 。例如:

static conststruct spi_device_id my_temp_sensor_ids[] = {    {"my_temp_sensor", 0},    {},};MODULE_DEVICE_TABLE(spi, my_temp_sensor_ids);

这里定义了一个 my_temp_sensor_ids 数组,其中包含了驱动支持的设备名 my_temp_sensor 。

同时,在基于设备树的系统中,要定义 OF 匹配表,用于与设备树中的设备节点进行匹配 。假设温度传感器的设备树节点 compatible 属性值为"vendor,my-temp-sensor" ,则 OF 匹配表的定义如下:

static conststruct of_device_id my_temp_sensor_of_match[] = {    {.compatible = "vendor,my-temp-sensor"},    {},};MODULE_DEVICE_TABLE(of, my_temp_sensor_of_match);

这样,当内核检测到设备树中的设备节点时,会将其 compatible 属性值与驱动的 OF 匹配表进行比对,若匹配成功,就会调用驱动的 probe 函数 。

4.3 实现 probe 函数与数据读写操作

probe 函数是 SPI 设备驱动的核心函数之一,当设备驱动与设备匹配成功后,内核会调用 probe 函数 。在 probe 函数中,首先要初始化硬件相关的资源 。例如,分配设备私有数据结构体,用于存储与设备相关的信息 :

static int my_temp_sensor_probe(struct spi_device *spi) {    int ret;    // 分配设备私有数据结构体struct my_temp_sensor_private *priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);    if (!priv)        return -ENOMEM;    spi_set_drvdata(spi, priv);

接着,设置 SPI 工作模式、时钟频率等参数 。假设温度传感器要求 SPI 工作在模式 0,时钟频率为 1MHz :

spi->mode = SPI_MODE_0;    spi->max_speed_hz = 1000000;    ret = spi_setup(spi);    if (ret) {        dev_err(&spi->dev, "spi setup failed: %d\n", ret);        return ret;    }

完成硬件初始化后,就可以实现数据读写操作了 。以读取温度传感器的数据为例,使用 spi_sync 函数进行同步数据传输 :

// 构建 SPI 传输消息结构体struct spi_transfer tr = {   .tx_buf = NULL,   .rx_buf = priv->rx_buffer,   .len = sizeof(priv->rx_buffer),};struct spi_message msg;spi_message_init(&msg);spi_message_add_tail(&tr, &msg);ret = spi_sync(spi, &msg);if (ret) {    dev_err(&spi->dev, "SPI read failed: %d\n", ret);    return ret;}// 解析读取到的数据,获取温度值// 这里假设温度数据存储在 rx_buffer 的前两个字节,并且需要进行一定的转换uint16_t temp_raw = ((uint16_t)priv->rx_buffer[0] << 8) | priv->rx_buffer[1];float temperature = convert_temp(temp_raw);

4.4 注册驱动与配置设备树

定义 spi_driver 结构并注册驱动是让驱动生效的关键步骤 。定义 spi_driver 结构如下:

staticstruct spi_driver my_temp_sensor_driver = {   .driver = {       .name = "my_temp_sensor_driver",       .owner = THIS_MODULE,       .of_match_table = my_temp_sensor_of_match,    },   .id_table = my_temp_sensor_ids,   .probe = my_temp_sensor_probe,   .remove = my_temp_sensor_remove,};

然后,在驱动模块加载时,使用 spi_register_driver 函数注册驱动 :

static int __init my_temp_sensor_init(void) {    return spi_register_driver(&my_temp_sensor_driver);}module_init(my_temp_sensor_init);

在设备树中添加 SPI 设备描述信息,确保设备树与驱动能够正确匹配 。假设 SPI 控制器节点为 spi1 ,温度传感器连接到 spi1 的片选 0,设备树节点示例如下:

spi1: spi@02100000 {    compatible = "fsl,imx6ul-ecspi", "fsl,imx6q-ecspi";    reg = <0x02100000 0x4000>;    interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;    status = "okay";    temp_sensor: temp_sensor@0 {        compatible = "vendor,my-temp-sensor";        reg = <0>;        spi-max-frequency = <1000000>;    };};

其中,compatible 属性与驱动的 OF 匹配表中的值一致,spi-max-frequency 指定了 SPI 通信的时钟频率 。

4.5 编译、调试与优化

将编写好的 SPI 设备驱动代码编译为内核模块,可以通过修改驱动目录下的 Makefile 文件来实现 。假设驱动源文件为 my_temp_sensor_driver.c ,Makefile 文件内容示例如下:

obj-m += my_temp_sensor_driver.oall:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

执行 make 命令,即可生成内核模块文件 my_temp_sensor_driver.ko 。

调试 SPI 驱动时,可以使用 dmesg 命令查看内核日志,了解驱动加载过程中是否有错误信息 。例如,执行 dmesg | grep spi ,可以查看与 SPI 相关的日志 。若发现问题,可以在驱动代码中添加 printk 语句,输出调试信息 。

优化驱动性能方面,可以从多个角度入手 。比如,合理设置 SPI 的工作模式和时钟频率,以平衡数据传输速度和稳定性;优化数据读写算法,减少不必要的内存拷贝和系统调用次数 。同时,要注意资源的合理使用,避免内存泄漏和资源竞争等问题 。

end

如果这篇文章对你有所启发,欢迎点赞、在看,转发三连。星标⭐账号,还可以第一时间收到推送,感谢你的收看,我们下期再见~

往期干货推荐

【专栏模块嵌入式Linux
专栏模块】性能优化
专栏模块】面试八股文
专栏模块项目实战
【硬核干货缺了这些,别说你懂 Linux内核
硬核干货】缺了这些,别说你懂 Linux C/C++
【学习思维导图】Linux内核源码自主学习路线

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-02 23:26:22 HTTP/2.0 GET : https://f.mffb.com.cn/a/498562.html
  2. 运行时间 : 0.646206s [ 吞吐率:1.55req/s ] 内存消耗:4,952.69kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=26a1594cd530e2a20acf1dc63e2bb779
  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.000951s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001743s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.002298s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.001584s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001684s ]
  6. SELECT * FROM `set` [ RunTime:0.010546s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001526s ]
  8. SELECT * FROM `article` WHERE `id` = 498562 LIMIT 1 [ RunTime:0.016655s ]
  9. UPDATE `article` SET `lasttime` = 1783005982 WHERE `id` = 498562 [ RunTime:0.016665s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.022572s ]
  11. SELECT * FROM `article` WHERE `id` < 498562 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.011377s ]
  12. SELECT * FROM `article` WHERE `id` > 498562 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.039621s ]
  13. SELECT * FROM `article` WHERE `id` < 498562 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.078662s ]
  14. SELECT * FROM `article` WHERE `id` < 498562 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.209549s ]
  15. SELECT * FROM `article` WHERE `id` < 498562 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.031482s ]
0.649525s