Frame Buffer设备驱动 (ili9488 3.5寸tft屏)

Frame Buffer设备驱动

  • Frame Buffer设备
  • ili9488介绍
  • 驱动编写
  • 代码编写
    • ili9488.c
    • 设备树修改
    • 测试
    • ili9488代码分析
  • LCD资料下载

Frame Buffer设备

  在早期的输出显示设备中,大部分为CRT显示器,随着技术的不断发展,现在大部分使用的是液晶显示器。这些显示设备在linux中统称为Frame Buffer设备,即帧缓冲设备,简称FB。
  需要说明的是,并不是只有显示屏这种设备才是帧缓存设备,实际上帧缓冲设备只是一种显示原理,将显示缓冲区中的数据重定向到输出设备中,也许有些输出设备仅仅只是一个虚拟的设备,那为何叫帧缓冲设备?这主要是因为帧缓冲设备的显示原理是在内存中开辟一块特定的暂存区,这块暂存区记录着所有像素数据,在一定的时间内将这个数据一一对应的写入到输出设备中,这样输出设备上就是我们需要显示的信息了。

ili9488介绍

  对于我购买的3.5寸TFT显示屏,其驱动芯片是ILI9488,采用的4线制spi,
在这里插入图片描述
其数据传输方式如下图所示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

驱动编写

驱动主要是根据厂商提供的stm32例程来改的,在该例程里面有如下函数
在这里插入图片描述
从这里可以看出他是RGB565转的RGB666,在编写代码的时候也采用同样的思路

代码编写

ili9488.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/io.h> //含有 ioremap 函数 iounmap 函数
#include <asm/uaccess.h> //含有 copy_from_user 函数和含有 copy_to_user 函数
#include <linux/device.h> //含有类相关的设备函数
#include <linux/cdev.h>
#include <linux/platform_device.h> //包含 platform 函数
#include <linux/of.h> //包含设备树相关函数
#include <linux/fb.h> //包含 frame buffer
#include <linux/spi/spi.h>
#include <linux/regmap.h>
#include <linux/gpio.h>static struct fb_info *myfb;                 //定义一个fb_info
static struct task_struct *fb_thread;        //定义一个线程刷新屏幕
static struct spi_device *fbspi;             //保存spi驱动指针
static struct gpio_desc *dc_pin;             //dc引脚
static struct gpio_desc *reset_pin;          //reset引脚
static u32    pseudo_palette[16];            //调色板缓存区/*
@function : write an 8-bit command to the LCD screen
@param : reg: comnmand value to be written
@return : none
*/
static void fb_write_reg(struct spi_device *spi, u8 reg)
{gpiod_set_value(dc_pin, 0);              //低电平,命令spi_write(spi, &reg, 1);}/*
@function : write an 16-bit data into registers,rgb565->rgb666
@param : data:data to be written
@return : none
*/
static void fb_write_data_u16(struct spi_device *spi, u16 data)
{u8 buf[3];buf[0] = ((u8)(data>>8))&0xF8;  //REDbuf[1] = ((u8)(data>>3))&0xFC;  //GREENbuf[2] = ((u8)(data<<3));       //BLUEgpiod_set_value(dc_pin, 1); //高电平,数据spi_write(spi, &buf[0], 1);spi_write(spi, &buf[1], 1);spi_write(spi, &buf[2], 1);
}/*
@function :write an 8-bit data to the lcd screen
@param :data:data value to written
@return : none
*/
static void fb_write_data_u8(struct spi_device *spi, u8 data)
{gpiod_set_value(dc_pin, 1); //高电平,数据spi_write(spi, &data, 1);
}/*
@function :setting lcd display window
@param :xstar: the begining x coordinate of the lcd display windowystar: the begining y coordinate of the lcd display windowxEnd:  the ending x coordinate of the lcd display windowyEnd:  the ending y coordinate of the lcd display window
*/
static void fb_set_win(struct spi_device *spi, u16 xStar, u16 yStar, u16 xEnd, u16 yEnd){fb_write_reg(spi,  0x2a);fb_write_data_u8(spi, xStar >> 8);fb_write_data_u8(spi, xStar & 0xFF);fb_write_data_u8(spi, xEnd >> 8);fb_write_data_u8(spi, xEnd & 0xff);fb_write_reg(spi, 0x2b);fb_write_data_u8(spi, yStar >> 8);fb_write_data_u8(spi, yStar & 8);fb_write_data_u8(spi, yEnd >> 8);fb_write_data_u8(spi, yEnd & 0xff);fb_write_reg(spi, 0x2c);    //  开始写入GRAM,即往lcd的GRAM写数据,LCD随即显示到屏幕上
}static void myfb_init(struct spi_device *spi){gpiod_set_value(reset_pin, 0);  //设置低电平msleep(100);gpiod_set_value(reset_pin, 1);  //设高电平msleep(50);/*   写寄存器,初始化*/fb_write_reg(spi, 0xf7);fb_write_data_u8(spi, 0xa9);fb_write_data_u8(spi, 0x51);fb_write_data_u8(spi, 0x2c);fb_write_data_u8(spi, 0x82);fb_write_reg(spi, 0xc0);fb_write_data_u8(spi, 0x11);fb_write_data_u8(spi, 0x09);fb_write_reg(spi, 0xc1);fb_write_data_u8(spi, 0x41);fb_write_reg(spi, 0xc5);fb_write_data_u8(spi, 0x00);fb_write_data_u8(spi, 0x0a);fb_write_data_u8(spi, 0x80);fb_write_reg(spi, 0xb1);fb_write_data_u8(spi, 0xB0);fb_write_data_u8(spi, 0x11);fb_write_reg(spi, 0xb4);fb_write_data_u8(spi, 0x02);fb_write_reg(spi, 0xb6);fb_write_data_u8(spi, 0x02);fb_write_data_u8(spi, 0x42);fb_write_reg(spi, 0xb7);fb_write_data_u8(spi, 0xc6);fb_write_reg(spi, 0xbe);fb_write_data_u8(spi, 0x00);fb_write_data_u8(spi, 0x04);fb_write_reg(spi, 0xe9);fb_write_data_u8(spi, 0x00);fb_write_reg(spi, 0x36);fb_write_data_u8(spi, (1<<3)|(0<<7)|(1<<6)|(1<<5));fb_write_reg(spi, 0x3a);fb_write_data_u8(spi, 0x66);fb_write_reg(spi, 0xe0);fb_write_data_u8(spi, 0x00);fb_write_data_u8(spi, 0x07);fb_write_data_u8(spi, 0x10);fb_write_data_u8(spi, 0x09);fb_write_data_u8(spi, 0x17);fb_write_data_u8(spi, 0x0b);fb_write_data_u8(spi, 0x41);fb_write_data_u8(spi, 0x89);fb_write_data_u8(spi, 0x4b);fb_write_data_u8(spi, 0x0a);fb_write_data_u8(spi, 0x0c);fb_write_data_u8(spi, 0x0e);fb_write_data_u8(spi, 0x18);fb_write_data_u8(spi, 0x1b);fb_write_data_u8(spi, 0x0f);fb_write_reg(spi, 0xe1);fb_write_data_u8(spi, 0x00);fb_write_data_u8(spi, 0x17);fb_write_data_u8(spi, 0x1a);fb_write_data_u8(spi, 0x04);fb_write_data_u8(spi, 0x0e);fb_write_data_u8(spi, 0x06);fb_write_data_u8(spi, 0x2f);fb_write_data_u8(spi, 0x45);fb_write_data_u8(spi, 0x43);fb_write_data_u8(spi, 0x02);fb_write_data_u8(spi, 0x0a);fb_write_data_u8(spi, 0x09);fb_write_data_u8(spi, 0x32);fb_write_data_u8(spi, 0x36);fb_write_data_u8(spi, 0x0f);fb_write_reg(spi, 0x11);mdelay(50);fb_write_reg(spi, 0x29);mdelay(200);}void fb_refresh(struct fb_info *fbi, struct spi_device *spi){int x, y;u16 *p =(u16 *)(fbi->screen_base );fb_set_win(spi, 0, 0, 479, 319);for (y = 0; y < fbi->var.yres; y++){for (x = 0; x < fbi->var.xres; x++){fb_write_data_u16(spi, *p++);}}
}int thread_func_fb(void *data){struct fb_info *fbi = (struct fb_info *)data;while(1){if(kthread_should_stop())break;fb_refresh(fbi,fbspi);}return 0;
}static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{chan &= 0xffff;chan >>= 16-bf->length;return chan << bf->offset;
}static u32 pseudo_palette[16];static int myfb_setcolreg(u32 regno, u32 red, u32 green, u32 blue, u32 transp, struct fb_info *info){unsigned int val;if (regno > 16)return 1;val = chan_to_field(red, &info->var.red);val |= chan_to_field(green, &info->var.green);val |= chan_to_field(blue, &info->var.blue);pseudo_palette[regno] = val;return 0;
}static struct fb_ops myfb_ops = {.owner        = THIS_MODULE,.fb_write     = fb_sys_write,.fb_setcolreg = myfb_setcolreg,            /* 设置颜色寄存器 */.fb_fillrect  = sys_fillrect,              /* 用像素行填充矩形框,通用库函数 */.fb_copyarea  = sys_copyarea,              /* 将屏幕的一个矩形区域复制到另一个区域,通用库函数*/.fb_imageblit = sys_imageblit,             /* 显示一幅图像,通用库函数*/           };static void myfb_update(struct fb_info *fbi, struct list_head *pagelist){/* 比较粗暴的方式,直接全部刷新 */fbi->fbops->fb_pan_display(&fbi->var,fbi);    /*将应用层数据刷新到FrameBuffer缓存中*/
}static struct fb_deferred_io myfb_defio = {.delay = HZ/20,.deferred_io = &myfb_update,};static struct fb_var_screeninfo myfb_var ={.rotate = 0,.xres   =480,.yres   =320,.xres_virtual =480,.yres_virtual =320,.bits_per_pixel =16,           //每个像素的位数.nonstd    =1,/*rgb565*/.red.offset = 11,.red.length = 5,.green.offset = 5,.green.length =6,.blue.offset = 0,.blue.length = 5,.transp.offset = 0,.transp.length = 0,.activate   =FB_ACTIVATE_NOW,.vmode     =FB_VMODE_NONINTERLACED, 
};static struct fb_fix_screeninfo myfb_fix ={.type =FB_TYPE_PACKED_PIXELS,.visual = FB_VISUAL_TRUECOLOR, //.line_length =480*2,           // width *bpp /8  就是宽度乘每个像素需要的位数除8 ,就是每行需要的字节数.accel = FB_ACCEL_NONE, //没有使用硬件加速.id    = "myfb",
};static int myfb_probe(struct spi_device *spi){int ret;void *gmem_addr;u32 gmem_size;fbspi = spi; //保存spi驱动指针printk(KERN_ERR"register myfb_spi_probe!\n");//申请GPIO用作DC引脚dc_pin = devm_gpiod_get(&spi->dev,"dc",GPIOF_OUT_INIT_LOW);if(IS_ERR(dc_pin)){printk(KERN_ERR"fail to request dc_gpios!\n");}//申请GPIO用作RESET引脚reset_pin =devm_gpiod_get(&spi->dev,"reset",GPIOF_OUT_INIT_HIGH);if(IS_ERR(reset_pin)){printk(KERN_ERR"fail to request reset-gpios!\n");return -1;}gpiod_direction_output(dc_pin, 0);  //设置输出方向gpiod_direction_output(reset_pin, 1); //设置输出方向printk(KERN_INFO"register myfb_probe dev !\n");myfb = framebuffer_alloc(sizeof(struct fb_info), &spi->dev); //向内核申请fb_info结构体//初始化底层操作结构体myfb->fbops =&myfb_ops;  //指定底层操作结构体gmem_size =320*480*2;   //设置显存大小,16bit 占2字节gmem_addr =kmalloc(gmem_size,GFP_KERNEL);  //分配Frame Buffer 显存if(!gmem_addr){printk(KERN_ERR"fail to alloc fb buffer!\n");}myfb->pseudo_palette = pseudo_palette; //假的16色调色板,里面存放了16色的数据,可以通过8bpp数据来找到调色板里面的16色颜色索引值,//模拟出16色颜色来,节省内存,不需要的话,指向一个不用的数组即可myfb->var =myfb_var;   // 设置分辨率参数myfb->fix =myfb_fix;   // 设置显示参数myfb->screen_buffer =gmem_addr; //设置显存地址myfb->screen_size = gmem_size; //设置显存大小myfb->fix.smem_len = gmem_size; //设置应用层显存大小myfb->fix.smem_start =(u32) gmem_addr; //设置应用层数据地址memset((void *)myfb->fix.smem_start, 0,myfb->fix.smem_len);  //清楚数据缓存myfb_init(spi);  //初始化显示屏myfb->fbdefio =&myfb_defio; //设置刷新参数fb_deferred_io_init(myfb);   //初始化刷新机制ret = register_framebuffer(myfb);   //注册fb驱动if(ret){framebuffer_release(myfb);unregister_framebuffer(myfb);devm_gpiod_put(&spi->dev, dc_pin);devm_gpiod_put(&spi->dev, reset_pin);printk(KERN_ERR"fail to register fb dev!\n");return -1;}//开启一个线程用来刷新显示屏fb_thread = kthread_run(thread_func_fb,myfb,spi->modalias);return 0;}int myfb_remove(struct spi_device *spi){fb_deferred_io_cleanup(myfb);  //清除刷新机制unregister_framebuffer(myfb);devm_gpiod_put(&spi->dev,dc_pin);devm_gpiod_put(&spi->dev,reset_pin);return 0;}struct of_device_id myfb_match[] ={{.compatible = "ilitek,ili9488"},{},
};struct spi_driver myfb_drv = {.driver ={.owner = THIS_MODULE,.name = "myfb_spi_driver",.of_match_table = myfb_match,},.probe =myfb_probe,.remove = myfb_remove,} ;module_spi_driver(myfb_drv);MODULE_LICENSE("GPL"); //不加的话加载会有错误提醒
MODULE_AUTHOR("2241507913@qq.com"); //作者
MODULE_VERSION("0.1"); //版本
MODULE_DESCRIPTION("myfb_spi_driver"); //简单的描述

设备树修改

在bcm2711-rpi-4-b.dts设备树修改&spi0

&spi0 {pinctrl-names = "default";pinctrl-0 = <&spi0_pins &spi0_cs_pins>;cs-gpios = <&gpio 8 1>, <&gpio 7 1>;status = "okay";ili9488@0{status = "okay";compatible = "ilitek,ili9488";reg = <0>;  /* CE0 Ƭѡ*/#address-cells = <1>;#size-cells = <0>;spi-max-frequency = <32000000>;dc-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;rotation =<90>;};spidev1: spidev@1{compatible = "spidev";reg = <1>;	/* CE1 */#address-cells = <1>;#size-cells = <0>;spi-max-frequency = <125000000>;};
};

测试

使用insmod加载ili9488.ko
在这里插入图片描述

加载完成后,在/dev目录下可以看到fb0,此为驱动里面注册的帧缓冲区
在这里插入图片描述
/dev/tty0是默认映射到/dev/fb0上的,所以,我们通过操作/dev/tty0即可操作屏幕

在这里插入图片描述
解决办法
sudo chmod 777 /dev/tty0
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

ili9488代码分析

  对于调色板myfb_setcolreg()函数,这里并未使用,是直接使用的rgb。
调色板的概念:假如LCD的数据位为16位,那么framebuffer应该每个像素占据16bit,但是为了节省空间,使用8bit表示一个像素,这时候需要引入调色板才能正确传输16位的数据给LCD(正确传输每个像素的数据)。调色板其实就是一片内存,这里面每一格存放16bit的数据。当LCD控制器从framebuffer中取出8bit的数据后,不是直接传给LCD,而是用这个8bit作为索引,从调色板中取出16bit的数据,然后发给LCD。所以,在使用8BPP(每个像素点的位数)格式时,framebuffer中存放的是伪彩色,16BPP或者24BPP格式时,framebuffer中存放的才是真彩色。所以在使用8BPP格式时,首先要设置调色板。
在这里插入图片描述
此部分来源于链接: link

LCD资料下载

链接: [link](链接: link)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/106691.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL视图、用户管理和C语言链接

文章目录 1. 视图1.1 基本使用 2. 用户管理2.1 用户信息2.2 创建用户2.3 修改用户密码2.4 删除用户 3. 数据库的权限3.1 给用户授权3.2 回收权限 4. mysql connect4.1 Connector/C 使用4.2 mysql接口介绍 1. 视图 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一…

百度SEO优化的特点(方式及排名诀窍详解)

百度SEO优化的特点介绍&#xff1a; 百度SEO优化是指对网站进行优化&#xff0c;使其在百度搜索引擎中获得更好的排名&#xff0c;进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新&#xff0c;所以长期稳定的…

开源任务调度框架

本文主要介绍一下任务调度框架Flowjob的整体结构&#xff0c;以及整体的心路历程。 功能介绍 flowjob主要用于搭建统一的任务调度平台&#xff0c;方便各个业务方进行接入使用。 项目在设计的时候&#xff0c;考虑了扩展性、稳定性、伸缩性等相关问题&#xff0c;可以作为公司…

YOLOv5网络结构图

网络结构图&#xff08;简易版和详细版&#xff09; 网络框架介绍 前言&#xff1a; YOLOv5是一种基于轻量级卷积神经网络&#xff08;CNN&#xff09;的目标检测算法&#xff0c;整体可以分为三个部分&#xff0c; backbone&#xff0c;neck&#xff0c;head。 如上图所示…

【排序算法】详解直接插入排序和希尔排序原理及其性能分析

文章目录 插入排序算法原理细节分析代码实现复杂度分析:稳定性分析:与冒泡排序的对比 希尔排序算法原理细节分析代码实现复杂度分析稳定性分析 总结对比 插入排序 算法原理 插入排序又或者说直接插入排序,是一种和冒泡排序类似的并且比较简单的排序方法&#xff0c; 基本思想…

3、Linux下安装

以下操作仅限于rh系列:支持rpm/yum安装方式&#xff0c;不支持deb/apt安装方式。 以下操作仅限于rh系列&#xff1a;支持rpm/yum安装方式&#xff0c;不支持 deb/apt安装方式。 1、在线下载安装包&#xff1a; wget https://downloads.mysql.com/archives/get/p/23/file/ m…

打造个人专属形象!工业级人物写真生成工具FaceChain开源

简介 FaceChain 是一个可以用来打造个人数字形象的深度学习模型工具。用户仅需要提供最低一张照片即可获得独属于自己的个人形象数字替身。FaceChain 支持在 gradio 的界面中使用模型训练和推理能力&#xff0c;也支持资深开发者使用 python 脚本进行训练推理。 Github链接&…

长短期记忆网络(LSTM)

一. 什么是LSTM Long Short Term Memory&#xff08;LSTM&#xff0c;长短期记忆&#xff09;是一种特殊的递归神经网络。这种网络与一般的前馈神经网络不同&#xff0c;LSTM可以利用时间序列对输入进行分析。 简而言之&#xff0c;当使用前馈神经网络时&#xff0c;神经网络会…

Linux 中如何安全地抹去磁盘数据?

哈喽大家好&#xff0c;我是咸鱼 离过职的小伙伴都知道&#xff0c;离职的时候需要上交公司电脑&#xff0c;但是电脑里面有许多我们的个人信息&#xff08;聊天记录、浏览记录等等&#xff09; 所以我们就需要先把这些信息都删除&#xff0c;确保无法恢复之后才上交 即有些…

MongoDB 索引和常用命令

一、基本常用命令 1.1 案例需求 存放文章评论的数据存放到 MongoDB 中&#xff0c;数据结构参考如下&#xff0c;其中数据库为 articledb&#xff0c; 专栏文章评论 comment 字段名称 字段含义 字段类型 备注 _id ID ObjectId或String Mongo的主键的字段 articlei…

怎么团队合作,协作开发

一、代码托管平台 我是在大一下的一个竞赛中接触到的代码托管平台 那个时候我也算是什么都不会的&#xff0c;不过不得不说这个确实比较重要&#xff0c;对我造成了一些冲击 在我看来&#xff0c;代码托管平台的作用就是在一个中转站&#xff08;仓库&#xff09;上存储我们写…

自己在家给电脑重装系统Win10教程

自己在家怎么给电脑重装系统Win10&#xff1f;Win10电脑系统如果操作时间特别长了&#xff0c;就可能出现卡顿、蓝屏等系统问题&#xff0c;这时候用户就想给电脑重装系统&#xff0c;却不知道重装具体的操作步骤&#xff0c;下面小编给大家详细介绍自己在家给电脑重装Win10系统…

k8s-13 存储之secret

Secret 对象类型用来保存敏感信息&#xff0c;例如密码、OAuth 令牌和 ssh key。 敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活 。 Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里 当 kubelet 为 pod 拉…

github 中关于Pyqt 的module view 操作练习

代码摘自&#xff0c;Pyside6 中的示例代码部分 # -*- coding: utf-8 -*- import sys from PySide6.QtWidgets import * from PySide6.QtGui import * from PySide6.QtCore import * from PySide6.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery import os os.chdir(os…

专业144,总分440+,上岸西北工业大学827西工大信号与系统考研经验分享

我的初试备考从4月末&#xff0c;持续到初试前&#xff0c;这中间没有中断。 总的时间分配上&#xff0c;是数学>专业课>英语>政治&#xff0c;虽然大家可支配时间和基础千差万别&#xff0c;但是这么分配是没错的。 数学 时间安排&#xff1a;3月-7月&#xff1a;…

人声分离软件:iZotope RX 10 (WinMac) 中文汉化版

iZotope RX 10是一款在音频修复和增强领域中非常出色的软件。它提供了一套全面的音频问题解决方案&#xff0c;为后期制作专业人员、音频工程师和视频编辑者解决各种棘手问题。 iZotope RX 10的主要特点包括&#xff1a; 声音修复功能&#xff1a;可以去除不良噪音、杂音、吱吱…

使用Python,Xpath获取所有的漫画章节路径,并下载漫画图片生成单个/多个pdf,并进行pdf合并

使用Python&#xff0c;Xpath获取所有的漫画章节路径&#xff0c;并下载漫画图片生成单个/多个pdf&#xff0c;并进行pdf合并 1 效果图2 原理2.1 pa_mh.py获取喜欢的漫画及所有章节2.2 pyImg2pdf.py根据图片生成单个/多个pdf并增加章节提示 3 源码3.1 pa_mh.py获取喜欢的漫画及…

python的pyecharts第三方模块绘制高端统计图表

pyecharts库 python的pyecharts库是一个用于生成 Echarts 图表的python第三方类库&#xff0c;可以绘制很高端的统计图表以便展示数据。 安装方法 pip安装 pip install pyecharts或者github拉取下载安装 git clone https://github.com/pyecharts/pyecharts.git cd pyechar…

业务安全五重价值:防攻击、保稳定、助增收、促合规、提升满意度

目录 防范各类威胁攻击 保障业务的连续性和稳定性 保障业务的合规性 提升企业营收和发展 提升企业满意度和品牌知名度 2023年暑假被“票贩子”和“黄牛”攻陷。他们利用各种手段抢先预约名额&#xff0c;然后加价出售给游客&#xff0c;导致了门票供不应求的局面&#xff…

win11的右键菜单改成win10的样子

在终端复制一下命令 reg add “HKCU\Software\Classes\CLSID{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32” /f /ve 回车&#xff0c;会显示成功 再重启资源管理器。这步必须执行&#xff0c;否则是成功的&#xff0c;或者可能重启电脑会成功&#xff0c;但是我没有…