当前位置:首页>Linux>Linux驱动学习日记(26) Linux SPI 驱动

Linux驱动学习日记(26) Linux SPI 驱动

  • 2026-03-26 16:02:10
Linux驱动学习日记(26) Linux SPI 驱动

Linux 下的 SPI 驱动框架简介

  SPI 驱动框架和 I2C 很类似,都分为主机控制器驱动和设备驱动,主机控制器也就是 SOC 的 SPI 控制器接口。

SPI 主机驱动

  SPI 主机驱动也就是 SOC 的 SPI 控制器驱动,类似 I2C 驱动里面的适配器驱动。Linux 使用 spi_controller 表示 SPI 主机驱动,spi_controller 是个结构体,定义在 include/linux/spi/spi.h:

structspi_controller {structdevicedev;structlist_headlist;/* Other than negative (== assign one dynamically), bus_num is fully        * board-specific.  usually that simplifies to being SOC-specific.        * example:  one SOC has three SPI controllers, numbered 0..2,        * and one board's schematics might show it using SPI-2.  software        * would normally use bus_num=2 for that controller.        */    s16  bus_num;/* chipselects will be integral to many controllers; some others        * might use board-specific GPIOs.        */    u16  num_chipselect;/* Some SPI controllers pose alignment requirements on DMAable        * buffers; let protocol drivers know about these requirements.        */    u16  dma_alignment;/* spi_device.mode flags understood by this controller driver */    u32  mode_bits;/* spi_device.mode flags override flags for this controller */    u32  buswidth_override_bits;/* Bitmask of supported bits_per_word for transfers */    u32  bits_per_word_mask;······

  SPI 主机驱动的核心就是申请 spi_controller,然后初始化,最后向 Linux 内核注册。

1、spi_master 申请与释放  spi_alloc_master 函数用于申请 spi_master,函数原型如下:

staticinline struct spi_controller *spi_alloc_master(struct device *host, unsignedint size)

  函数参数和返回值含义如下   dev:设备,一般是 platform_device 中的 dev 成员变量。   size:私有数据大小,可以通过 spi_maser_get_devdata 函数获取到这些私有数据。   返回值:申请到的 spi_controller。

  spi_master 的释放通过 spi_controller_put 来完成,当我们删除一个 SPI 主机驱动的时候就需要释放掉前面申请的 spi_master,其函数原型如下:

staticinlinevoidspi_controller_put(struct spi_controller *ctlr)

  其中,ctrl 就是要释放的 spi_master。

2、spi_master 的注册与注销  当 spi_master 初始化完成以后就要将其注册到 Linux 内核,spi_master 注册函数为 spi_register_controller,函数原型如下:

intspi_register_controller(struct spi_controller *ctlr);

  其中 ctlr 表示要注册的 spi_controller,返回值为 0 时成功,为负值时失败。   如果要注销的话可以使用 spi_unregister_controller 函数,此函数原型如下

voidspi_unregister_controller(struct spi_controller *ctlr);

  其中,ctlr 就是要注销的 spi_controller。

SPI 设备驱动

  spi 设备驱动和 i2c 设备驱动也很类似,Linux 内核使用 spi_driver 来表示 spi 设备驱动,其原型如下:

structspi_driver {conststructspi_device_id *id_table;int      (*probe)(struct spi_device *spi);void      (*remove)(struct spi_device *spi);void      (*shutdown)(struct spi_device *spi);structdevice_driverdriver;};

  可以看出,spi_driver 和 i2c_driver、platform_driver 基本一样,当 SPI 设备和驱动匹配成功以后 probe 函数就会执行。   同样的,spi_driver 初始化完成以后也需要向 Linux 内核注册,spi_driver 注册函数为 spi_register_driver,其原型如下:

#define spi_register_driver(driver) \    __spi_register_driver(THIS_MODULE, driver)

  driver 就表示要注册的 spi_driver,返回值为 0 表示注册成功,为负值表示失败。   注销 SPI 设备驱动以后也需要注销掉前面注册的 spi_driver,使用 spi_unregister_driver 函数完成 spi_driver 的注销,函数原型如下:

voidspi_unregister_driver(struct spi_driver *sdrv)

  其中,sdrv 就表示需要注销的 spi_driver。

SPI 设备驱动编写流程

SPI 设备信息概述

1、IO 的 pinctrl 子节点的创建与修改  首先肯定是根据所使用的 IO 来创建和修改 pinctrl 子节点,一定要注意检查相应的 IO 有没有被其他设备所占用!!!

2、SPI 设备节点的创建与修改  采用设备树的情况下,SPI 设备信息描述就通过创建相应的设备子节点来完成,我们可以打开 imx6ull-14x14-evk.dtsi 文件,找到 spi 相关的配置:

spi-4 {    compatible = "spi-gpio";    pinctrl-names = "default";    pinctrl-0 = <&pinctrl_spi4>;    status = "okay";    gpio-sck = <&gpio5 11 0>;               // 配置时钟线    gpio-mosi = <&gpio5 10 0>;              // 配置数据线(主到从)    cs-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;  // 配置片选线,设置为低有效     num-chipselects = <1>;                  // 配置设备数量,表示只有 1 个设备    #address-cells = <1>;    #size-cells = <0>;    gpio_spi: gpio@0 {                      // 表示通道 0        compatible = "fairchild,74hc595";   // 设备类型        gpio-controller;                            #gpio-cells = <2>;        reg = <0>;        registers-number = <1>;        spi-max-frequency = <100000>;       // spi最大频率        enable-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;  // 使能控制引脚,低有效    };};

SPI 设备数据收发处理流程

  SPI 设备驱动的核心时 spi_driver,这个我们之前学习过了。当我们向Linux内核注册成功以后就可以使用 SPI 核心层提供的 API 函数来对设备进行读写操作了。首先是 spi_transfer 结构体,此结构体用于描述 SPI 传输信息,其内容如下:

structspi_transfer {/* It's ok if tx_buf == rx_buf (right?)    * for MicroWire, one buffer must be null    * buffers must work with dma_*map_single() calls, unless    *   spi_message.is_dma_mapped reports a pre-existing mapping    */constvoid     *tx_buf;void          *rx_buf;unsigned     len;dma_addr_t     tx_dma;dma_addr_t     rx_dma;structsg_tabletx_sg;structsg_tablerx_sg;unsigned     dummy_data:1;unsigned     cs_off:1;unsigned     cs_change:1;unsigned     tx_nbits:3;unsigned     rx_nbits:3;#define     SPI_NBITS_SINGLE     0x01 /* 1bit transfer */#define     SPI_NBITS_DUAL          0x02 /* 2bits transfer */#define     SPI_NBITS_QUAD          0x04 /* 4bits transfer */    u8          bits_per_word;structspi_delaydelay;structspi_delaycs_change_delay;structspi_delayword_delay;    u32          speed_hz;    u32          effective_speed_hz;unsignedint     ptp_sts_word_pre;unsignedint     ptp_sts_word_post;structptp_system_timestamp *ptp_sts;bool          timestamped;structlist_headtransfer_list;#define SPI_TRANS_FAIL_NO_START     BIT(0)    u16          error;};

  其中,tx_buf 保存着要发送的数据,rx_buf 保存接收到的数据。len 是要进行传输的数据长度,由于 SPI 是全双工通信,因此在一次通信中接收的字节数都是一样的。   spi_transfer 需要组织成 spi_message,spi_message 也是一个结构体,内容如下:

structspi_message {structlist_headtransfers;structspi_device    *spi;unsigned        is_dma_mapped:1;/* REVISIT:  we might want a flag affecting the behavior of the     * last transfer ... allowing things like "read 16 bit length L"     * immediately followed by "read L bytes".  Basically imposing     * a specific message scheduling algorithm.     *     * Some controller drivers (message-at-a-time queue processing)     * could provide that as their default scheduling algorithm.  But     * others (with multi-message pipelines) could need a flag to     * tell them about such special cases.     *//* Completion is reported through a callback */void            (*complete)(void *context);void            *context;unsigned        frame_length;unsigned        actual_length;int            status;/* For optional use by whatever driver currently owns the     * spi_message ...  between calls to spi_async and then later     * complete(), that's the spi_controller controller driver.     */structlist_headqueue;void            *state;/* List of spi_res reources when the spi message is processed */structlist_headresources;/* spi_prepare_message() was called for this message */bool            prepared;};

  在使用 spi_message 之前需要对其进行初始化,spi_message 初始化函数为 spi_message_init,函数原型如下:

voidspi_message_init(struct spi_message *m)

  其中,m 就表示要初始化的 spi_message。   spi_message 准备好以后就可以进行数据传输了,数据传输分为同步传输和异步传输,同步传输会阻塞的等待 SPI 数据传输完成,同步传输函数为 spi_sync,函数原型如下:

voidspi_message_add_tail(struct spi_transfer *t, struct spi_message *m)

  其中,t 表示要添加到队列中的 spi_transfer,m 表示要加入的 spi_message。

  spi_message 准备好以后就可以进行数据传输了,数据传输分为同步传输和异步传输,同步传输会阻塞的等待 SPI 数据传输完成,同步传输函数为 spi_sync,函数原型如下:

intspi_sync(struct spi_device *spi, struct spi_message *message)

  其中,spi 就是要进行数据传输的 spi_device,message 表示要传输的 spi_message。

  异步传输不会阻塞的等待 SPI 数据传输完成,异步传输需要设置 spi_message 中的 complete 成员变量,其是一个回调函数,当 SPI 异步传输完成以后此函数就会被调用。SPI 异步传输函数为 spi_async,函数原型如下:

intspi_async(struct spi_device *spi, struct spi_message *message)

  其中,spi 就是要进行数据传输的 spi_device,message 就是要传输的 spi_message。

  综上所述,SPI 数据传输步骤如下:   ①、申请并初始化 spi_transfer,设置 spi_transfer 的 tx_buf 成员变量,然后设置 rx_buf 成员变量,最后设置 len 成员变量。   ②、使用 spi_message_init 函数初始化 spi_message。   ③、使用 spi_message_add_tail 函数将前面设置好的 spi_transfer 添加到 spi_message 队列中。   ④、使用 spi_sync 函数完成 SPI 数据同步传输。

硬件分析

  我们使用 SPI 通信的 W25Q64 完成本次学习。查询原理图,得知可以将以下几个引脚复用为 SPI 功能。

图 1 spi原理图

代码编写

修改设备树

  打开 imx6ull-hcw-emmc.dtsi 文件,在 iomuxc 节点中添加一个新的子节点来描述 W25Q64 所使用的 SPI 引脚。内容如下:

pinctrl_ecspi3: w25q64{    fsl,pins = <        MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x10b0        MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b1        MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x10b1        MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x10b1    >;};

  接下来,我们在设备树文件中添加以下代码

&ecspi3 {    /delete-property/ dmas;    /delete-property/ dma-names;    fsl,spi-num-chipselects = <1>;    cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;    pinctrl-names = "default";    pinctrl-0 = <&pinctrl_ecspi3>;    status = "okay";    w25q64@0 {        compatible =  "hcw,w25q64";        reg = <0>;        spi-max-frequency = <1000000>;    };};

  检查引脚是否冲突,将冲突的设备设为 disabled,编译设备树,并使用新的 dtb 文件启动 Linux 内核。

编写代码

  新建文件,写入以下代码。   1、设备结构体

#define     W25Q64_CNT      1#define     W25Q64_NAME     "w25q64"structw25q64_dev{dev_t devid;structcdevcdev;structclass *class;structdevice *device;structdevice_node *nd;int major;void *private_data;int cs_gpio;};staticstructw25q64_devw25q64dev;

2、w25q64 spi 设备的注册与注销  对于 spi 设备驱动,首先就是要初始化并向系统注册 spi_driver,w25q64 的 spi_driver 初始化、注册、注销代码如下:

staticconststructof_device_idw25q64_of_match[] = {    {.compatible = "hcw,w25q64"},    {}};staticstructspi_driverw25q64_drv = {    .driver = {        .name = "w25q64_drv",        .owner = THIS_MODULE,        .of_match_table = w25q64_of_match,    }};staticint __init w25q64_init(void){return spi_register_driver(&w25q64_drv);}staticvoid __exit w25q64_exit(void){    spi_unregister_driver(&w25q64_drv);}module_init(w25q64_init);module_exit(w25q64_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("hcw");

3、probe&remove 函数

staticintw25q64_probe(struct spi_device *dev){if(w25q64dev.major){        w25q64dev.devid = MKDEV(w25q64dev.major, 0);        register_chrdev_region(w25q64dev.devid, W25Q64_CNT, W25Q64_NAME);    }else{        alloc_chrdev_region(&w25q64dev.devid, 0, W25Q64_CNT, W25Q64_NAME);        w25q64dev.major = MAJOR(w25q64dev.devid);    }    cdev_init(&w25q64dev.cdev, &w25q64_fops);    cdev_add(&w25q64dev.cdev, w25q64dev.devid, W25Q64_CNT);    w25q64dev.class = class_create(THIS_MODULEW25Q64_NAME);if(IS_ERR(w25q64dev.class))    {return PTR_ERR(w25q64dev.class);    }    w25q64dev.device = device_create(w25q64dev.class, NULL, w25q64dev.devid, NULL, W25Q64_NAME);if(IS_ERR(w25q64dev.device))    {return PTR_ERR(w25q64dev.device);    }    dev->mode = SPI_MODE_0;    spi_setup(dev);    w25q64dev.private_data = dev;return0;}staticvoidw25q64_remove(struct spi_device *dev){    cdev_del(&w25q64dev.cdev);    unregister_chrdev_region(w25q64dev.devid, W25Q64_CNT);    device_destroy(w25q64dev.class, w25q64dev.devid);    class_destroy(w25q64dev.class);}

4、w25q64 读取 ID 函数  SPI 驱动最终是通过读写 w25q64 寄存器来实现的,因此需要编写对应的寄存器读写函数。

staticintw25q64_readID(struct w25q64_dev *dev, void *buf){int ret = -1;unsignedchar txdata[1];unsignedchar *rxdata;structspi_messagem;structspi_transfer *t;structspi_device *spi = (structspi_device *)dev->private_data;    t = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL);if(!t)    {return -ENOMEM;    }    rxdata = kzalloc(sizeof(char) * 4, GFP_KERNEL);if(!rxdata)goto out1;    txdata[0] = 0x90;    t->tx_buf = txdata;    t->rx_buf = rxdata;    t->len = 4;    spi_message_init(&m);    spi_message_add_tail(t, &m);    ret = spi_sync(spi, &m);if(ret)goto out2;memcpy(buf, rxdata + 13); // 从 rxdata 的首地址往后偏移 1 个字节开始拷贝,用来过滤掉第一个无效数据out2:    kfree(rxdata);out1:    kfree(t);return ret;}

修复错误

  写好后,编译模块装载,运行测试程序,但是并没有如预想中的一样输出设备 ID。是怎么回事呢?我们查阅 STM32 平台下的标准代码可以得知,我们应该依次发送 90 00 00 00 ff ff。最终代码放在最后

uint16_tw25qxx_read_id(void){uint16_t id = 0;//片选有效    SPI_CS = 0;//发送0x90,读取厂商ID和设备ID    spi_read_writeByte(0x90);//发送24位地址(3个字节)  前面两个字节可以任意,第三个字节必须是0x00    spi_read_writeByte(0x00);    spi_read_writeByte(0x00);    spi_read_writeByte(0x00);//一定是0x00//随便发2个字节的数据    id |= spi_read_writeByte(0xFF)<<8//id:0xEF17  厂商ID:0xEF        id |= spi_read_writeByte(0xFF);    //设备ID:0x17//片选无效    SPI_CS = 1;return id;}

图 2 读到ID

/* * @Author: 胡城玮 * @FilePath: w25q64.c * @Date: 2026-03-22 * @Description:  * @Version: 0.1 */#include<linux/types.h>#include<linux/kernel.h>#include<linux/delay.h>#include<linux/init.h>#include<linux/module.h>#include<linux/errno.h>#include<linux/gpio.h>#include<linux/cdev.h>#include<linux/device.h>#include<linux/of_gpio.h>#include<linux/semaphore.h>#include<linux/timer.h>#include<linux/i2c.h>#include<linux/spi/spi.h>#include<linux/of.h>#include<linux/of_address.h>#include<linux/of_gpio.h>#include<linux/platform_device.h>#include<asm/mach/map.h>#include<asm/uaccess.h>#include<asm/io.h>#define     W25Q64_CNT      1#define     W25Q64_NAME     "w25q64"structw25q64_dev{dev_t devid;structcdevcdev;structclass *class;structdevice *device;structdevice_node *nd;int major;void *private_data;int cs_gpio;};staticstructw25q64_devw25q64dev;staticconststructof_device_idw25q64_of_match[] = {    {.compatible = "hcw,w25q64"},    {}};staticconststructspi_device_idw25q64_id[] = {    { "w25q64"0 },    { }};MODULE_DEVICE_TABLE(of, w25q64_of_match);staticintw25q64_readID(struct w25q64_dev *dev, void *buf){int ret = -1;unsignedchar txdata[6] = {0x900x000x000x00,0xff,0xff};unsignedchar *rxdata;structspi_messagem;structspi_transfer *t;structspi_device *spi = (structspi_device *)dev->private_data;    t = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL);if(!t)    {return -ENOMEM;    }    rxdata = kzalloc(sizeof(char) * 6, GFP_KERNEL);if(!rxdata)goto out1;    t->tx_buf = txdata;    t->rx_buf = rxdata;    t->len = 6;    spi_message_init(&m);    spi_message_add_tail(t, &m);    ret = spi_sync(spi, &m);if(ret)goto out2;memcpy(buf, rxdata + 42); // 从 rxdata 的首地址往后偏移 4 个字节开始拷贝,用来过滤掉4个无效数据out2:    kfree(rxdata);out1:    kfree(t);return ret;}staticintw25q64_open(struct inode *nd, struct file *filp){    filp->private_data = &w25q64dev;return0;}staticssize_tw25q64_read(struct file *filp, char __user *buf, size_t cnt, loff_t *oft){int ret = 0;uint8_t data[3];    ret = w25q64_readID(&w25q64dev, data);if(ret)return ret;    printk("read id = %02x %02x %02x\n", data[0], data[1], data[2]);int err = copy_to_user(buf, data, 3);if(err)    {return -EFAULT;    }return3;}staticintw25q64_release(struct inode *inode, struct file *filp){return0;}staticstructfile_operationsw25q64_fops = {    .owner = THIS_MODULE,    .read = w25q64_read,    .open = w25q64_open,    .release = w25q64_release};staticintw25q64_probe(struct spi_device *dev){    printk("matched!!!\r\n");if(w25q64dev.major){        w25q64dev.devid = MKDEV(w25q64dev.major, 0);        register_chrdev_region(w25q64dev.devid, W25Q64_CNT, W25Q64_NAME);    }else{        alloc_chrdev_region(&w25q64dev.devid, 0, W25Q64_CNT, W25Q64_NAME);        w25q64dev.major = MAJOR(w25q64dev.devid);    }    cdev_init(&w25q64dev.cdev, &w25q64_fops);    cdev_add(&w25q64dev.cdev, w25q64dev.devid, W25Q64_CNT);    w25q64dev.class = class_create(THIS_MODULEW25Q64_NAME);if(IS_ERR(w25q64dev.class))    {return PTR_ERR(w25q64dev.class);    }    w25q64dev.device = device_create(w25q64dev.class, NULL, w25q64dev.devid, NULL, W25Q64_NAME);if(IS_ERR(w25q64dev.device))    {return PTR_ERR(w25q64dev.device);    }    dev->mode = SPI_MODE_0;    spi_setup(dev);    w25q64dev.private_data = dev;return0;}staticvoidw25q64_remove(struct spi_device *dev){    cdev_del(&w25q64dev.cdev);    unregister_chrdev_region(w25q64dev.devid, W25Q64_CNT);    device_destroy(w25q64dev.class, w25q64dev.devid);    class_destroy(w25q64dev.class);}staticstructspi_driverw25q64_drv = {    .driver = {        .name = "w25q64_drv",        .owner = THIS_MODULE,        .of_match_table = w25q64_of_match,    },    .probe = w25q64_probe,    .remove = w25q64_remove,    .id_table = w25q64_id,};staticint __init w25q64_init(void){return spi_register_driver(&w25q64_drv);}staticvoid __exit w25q64_exit(void){    spi_unregister_driver(&w25q64_drv);}module_init(w25q64_init);module_exit(w25q64_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("hcw");

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-27 18:28:59 HTTP/2.0 GET : https://f.mffb.com.cn/a/482183.html
  2. 运行时间 : 0.180928s [ 吞吐率:5.53req/s ] 内存消耗:4,951.80kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=a0ad30beecb2f67e0e726e5792f32b07
  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.001122s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001640s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000743s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000679s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001350s ]
  6. SELECT * FROM `set` [ RunTime:0.000620s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001482s ]
  8. SELECT * FROM `article` WHERE `id` = 482183 LIMIT 1 [ RunTime:0.001289s ]
  9. UPDATE `article` SET `lasttime` = 1774607340 WHERE `id` = 482183 [ RunTime:0.003867s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.002210s ]
  11. SELECT * FROM `article` WHERE `id` < 482183 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000420s ]
  12. SELECT * FROM `article` WHERE `id` > 482183 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000385s ]
  13. SELECT * FROM `article` WHERE `id` < 482183 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001226s ]
  14. SELECT * FROM `article` WHERE `id` < 482183 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000643s ]
  15. SELECT * FROM `article` WHERE `id` < 482183 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004252s ]
0.184956s