自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(54)
  • 资源 (80)
  • 收藏
  • 关注

转载 Linux驱动调试

驱动程序开发的一个重大难点就是不易调试。本文目的就是介绍驱动开发中常用的几种直接和间接的调试手段,它们是:利用printk查看OOP消息利用strace利用内核内置的hacking选项利用ioctl方法利用/proc 文件系统使用kgdb一、利用printk这是驱动开发中最朴实无华,同时也是最常用和有效的手段。scull驱动的main.c第338行如下,就是使用printk

2016-09-28 17:13:03 2535

转载 C语言中冒泡法、选择法、插入法三种常见排序算法

一、冒泡法 算法要求:用起泡法对10个整数按升序排序。    算法分析:如果有n个数,则要进行n-1趟比较。在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较。比较的顺序从前往后,经过一趟比较后,将最值沉底(换到最后一个元素位置),最大值沉底为升序,最小值沉底为降序。    算法源代码:# include main()

2016-09-23 21:26:08 9591 3

原创 (十一)1 简单的看门狗驱动

来个简单的看门狗驱动——静态平台类的杂设备看门狗驱动,有定时和重启两个基本功能。一、S3C2440中的看门狗——具体请看s3c2440文档看门狗应该可以算是S3C2440中最简单的一个设备的,仅仅只有三个寄存器需要配置。S3C2440中的看门狗有两种功能(只能二选一):1、复位功能,在指定时间内,如果没有执行喂狗操作。指定时间到达后会执行系统重启操作

2016-09-21 11:32:21 972

原创 (十)1 udev&misc

一、动态创建设备节点——udev之前加载字符型设备后是通过命令mknod来创建设备节点的。在2.6内核中,有一个名叫udev的后台程序,它通过读取/sys/class的信息,一旦添加的新的设备,该后台程序就会自动创建设备节点。一、要使用动态创建设备节点,首先要运行udev后台程序。在嵌入式下有两种方法:1、移植udev到嵌入式系统

2016-09-21 11:28:26 263

原创 (九)1 platform设备驱动

一、什么是paltform总线一个现实的linux设备和驱动通常都需要挂接在一种总线上,比较常见的总线有USB、PCI总线等。但是,在嵌入式系统里面,SoC系统中集成的独立的外设控制器、挂接在SoC内存空间的外设却不依附与此类总线。基于这样的背景下,2.6内核加入了platform虚拟总线。platform机制将设备本身的资源注册进内核,有内核统一管理,在驱动程序使用这些资源时

2016-09-21 11:26:37 262

原创 (八)4.总线热插拔

一、热插拔的实现我不知道在这里用热插拔这样的名字是否合适,在之前的代码,需要我自己手动去加载驱动和设备的模块,但在现实的情况下,一般是当设备一被插入,系统自己会注册设备,并调用合适的驱动。所以,接下来我要实现的是,在加载了usb总线和usb鼠标驱动的前提下,当有usb鼠标插入,系统自己进行设备的操作。当然,上面的usb鼠标是我自己想象出来的,当我一按下按键(对应中断E_

2016-09-21 11:24:25 9238

原创 (八) 3 设备模型的分层与面向对象

一、设备管理的分层回想一下之前的设备和驱动函数注册时,它们是自己指定所属的总线。但是,内核开发人员觉得,这样的方法不好,应该由总线来提供设备和驱动的注册函数。当设备和驱动需要注册到指定总线时,那就必须使用该总线为设备和驱动提供的注册函数。所以,将上一节的bus.c修改如下:/*8th_devModule_3/1st/bus.c*/21 /*总

2016-09-21 11:22:46 249

原创 (八)2 match.probe.remove

一、总线、设备和驱动函数在/sys/中的框架首先要写三个函数,bus.c、device.c和driver.c。这几个函数其实就是上一节函数的精简版,去掉属性文件的创建,仅仅保留创建和注销操作。第一个函数是bus.c,加载模块会创建了一条名叫usb的总线,总线目录放在/sys/bus/目录下:/*8th_devModule_2/1st/bus.c*/6 s

2016-09-21 11:20:56 291

原创 (八)1 总线、设备和驱动

一、sysfs文件系统设备模型是2.6内核新引入的特征。设备模型提供了一个独立的机制专门来表示设备,并描述其在系统中的拓扑结构。在2.4内核中,设备的信息放在/proc中。而在2.6内核,内核把设备相关的信息归类在新增加sysfs文件系统,并将它挂载到/sys目录中,把设备信息归类的同时,让用户可以通过用户空间访问。接下来简单介绍一些sys中

2016-09-21 11:18:44 267

原创 (七)2 内核定时器

一、定时器之前说过两类跟时间相关的内核结构。1、延时:通过忙等待或者睡眠机制实现延时。2、tasklet和工作队列,通过某种机制使工作推后执行,但不知道执行的具体时间。接下来要介绍的定时器,能够使工作在指定的时间点上执行,而且不需要使用忙等待这类的延时方法。通过定义一个定时器,告之内核在哪个时间需要执行什么函数就可以了,等时间一到,内核会就执行指定的函数

2016-09-21 11:16:01 154

原创 (七)1 时间管理与内核延时

一、内核时间的相关概念墙上时钟:也就是实际时间。系统时间:自系统启动开始所经过的时间。时钟中断:内核会周期性的产生时钟中断,在中断处理函数中执行一些与时间相关的操作,如更新时间,进程调度,检查时间片等。节拍率:在linux内核中,通过编程定义节拍率,也就是HZ。每1/HZ秒发生一次时钟中断。在ARM中,节拍率被定义为1

2016-09-21 11:12:59 267

原创 (六)3中断下半部之工作队列

1、工作队列的使用按惯例,在介绍工作队列如何实现之前,先说说如何使用工作队列实现下半部。步骤一、定义并初始化工作队列:创建工作队列函数:struct workqueue_struct *create_workqueue(const char *name)函数传参是内核中工作队列的名称,返回值是workqueue_struc

2016-09-21 11:10:49 245

原创 (六)3中断下半部之tasklet

一、什么是下半部中断是一个很霸道的东西,处理器一旦接收到中断,就会打断正在执行的代码,调用中断处理函数。如果在中断处理函数中没有禁止中断,该中断处理函数执行过程中仍有可能被其他中断打断。出于这样的原因,大家都希望中断处理函数执行得越快越好。另外,中断上下文中不能阻塞,这也限制了中断上下文中能干的事。基于上面的原因,内核将整个的中断处理流程分为了上半部和下半部。上

2016-09-21 11:08:23 241

原创 (六)2 分享中断号

上一节介绍的内容是,调用接口request_irq(),使中断号与中断处理函数对应。但是,有时候会有这样的情况,如果开发板上按键的中断已经被另外的驱动程序注册中断了,而我现在又想再注册一次这个中断,这就出现了一个中断号不止对应一个中断函数的情况。注意,这里与硬件上的共享中断不一样,这里是指,当一个中断信号来了,基于操作系统,一个中断的到来可以调用多个中断处理程序,与硬件无关。接下来从错误的

2016-09-20 19:50:16 287

原创 (六)1 中断的实现

一、什么是中断中断分两种:1)中断,又叫外部中断或异步中断,它的产生是由于外设向处理器发出中断请求。其中外部中断也有两种,这是由配置寄存器设定的:普通中断请求(IRQ)和快速中断请求(FIQ)。一般地,linux下很少使用快速中断请求。2)异常,又叫内部中断或同步中断,它的产生是由于处理器执行指令出错。在以下的内容我是要介绍由于外部设备产生的中断。

2016-09-20 19:46:17 717

原创 (五)4 写个简单的LED驱动

一、实现硬件操作函数一般的,我写驱动的时候,我会先确定一些基本的硬件操作函数能够使用。如LED驱动我要实现三个操作:配置、开灯和关灯,所以我先要实现这几个硬件操作函数。其实这些在我介绍IO内存时已经实现了(5th_mm_2/3rd/test.c),我只是稍作了一点修改,改了一下内存的数据类型,其实没什么大出入。/*5th_mm_4/1st/test.c*/

2016-09-20 19:43:59 1150

原创 (五)3 IO静态映射

一、静态IO是怎么建立的Io静态映射发生在内核启动的时候,接下来通过内核源代码来分析,如果你的开发板是mini2440或者时候mini2440的内核配置文件,可以跟着我同样修改。注意:我的开发板只是使用mini2440的配置文件,外围电路跟mini2440不一样。注:以下代码在内核目录linux-2.6.29/arch/arm/mach-s3c2440/ma

2016-09-20 19:41:40 410

原创 (五)2 操作硬件——IO内存

一、IO端口与IO内存介绍之前可以看看以下的博客:http://blogold.chinaunix.net/u2/66435/showart_2137870.htmlx86体系和ARM体系的寻址方式是有差别的:在x86下,为了能够满足CPU高速地运行,内存与CPU之间通过北桥相连并通过地址方式访问,而外设通过南桥与CPU相连并通过端口访问。在

2016-09-20 19:39:40 285

原创 (五)1在内核空间分配内存

一、内核空间和用户空间有什么不同学c语言的时候应该学过,从用户空间看,每个进程都傻乎乎的以为自己有4G的内存空间,其中位于高地址(3G-4G)的1G空间给内核用,另外的3G(0-3G)都是它一个人独占的。所以用户空间很慷慨的把3G的空间分了好几个区域,如堆、栈、代码段等。其中,malloc()分配的空间位于堆,而程序中的自动变量,如你在函数内定义的“int i”,它是放在栈

2016-09-20 19:37:26 485

原创 (四)5多处理器下的竞态和并发

一、多处理器抢占式内核的内核同步需要防什么1)防内核抢占。2)防中断打断。3)防其他处理器也来插一脚。所以,在上一节讲的防抢占和防中断,接下来的内容实在这两个的基础上说一下如何防其他处理器。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2016-09-20 19:34:01 383

原创 (四)4单CPU下竞态和并发

一、什么是并发所谓并发,就是多个进程同时、并行执行。在单处理器的情况下,并发只是宏观上的,用户会感觉多个程序共同执行,其实只不过是多个进程轮流占用处理器运行,只有在多处理器的情况下才会实现真正的同时执行。但是,不管单处理器还是多处理器,内核中的并发都会引起共享资源的并发访问。举个简单的例子,有两个相同代码的进程并发执行,它们都是要修改存在与内核中个一个数据data。

2016-09-20 19:30:46 655

原创 (四)3抢占和上下文切换

一、什么是上下文切换上下文切换,是指从一个可执行的进程切换到另外一个可执行的进程。在linux内核中,上下文的切换有两种方式:第一种是进程主动让出CPU,这样的操作成为“让步”。第二种是由内核调度程序决定进程运行时间,在在运行时间结束(如时间片耗尽)或者需要切换高优先级进程时强制挂起进程,这样的操作叫“抢占”。抢占是我一直误解的概念,我一直以为抢占是一个进程强制切换到另

2016-09-20 19:28:51 563

原创 (四)2进程调度的相关概念

一、I/O消耗型进程和处理器消耗型的进程进程分为I/O消耗型和处理器消耗型两种。I/O消耗型,是指进程大部分时间用来提交I/O请求或者等待I/O请求的进程。这类进程的特征是,经常需要运行,但执行一次需要的时间不长。如文字编辑。处理器消耗型,是指进程大部分时间用来执行代码的进程。这类进程对系统的响应时间要求比较少,像看个视频,慢个半秒人是察觉不出来的。

2016-09-20 19:27:14 257

原创 (四)1进程管理的相关概念

一、什么是进程简单的说,进程就是正在运行的程序,一个程序可以同时有多个进程。学过C语言都知道,程序运行时并不是只有代码,还包含其他的资源,如打开的文件,信号,全局变量等等。我在《操作系统原理》中看过一个很生动很深刻的例子:一个人对照着菜谱做菜。在这例子中,人就是内核,菜谱就是程序,做菜的过程就是进程,而菜、锅就是这个进程的资源。内核为线程提供了两种技术:虚拟处理器和虚拟

2016-09-20 19:25:53 229

原创 (三)7异步通知fasync

一、什么是异步通知个人认为,异步通知类似于中断的机制,如下面的将要举例的程序,当设备可写时,设备驱动函数发送一个信号给内核,告知内核有数据可读,在条件不满足之前,并不会造成阻塞。而不像之前学的阻塞型IO和poll,它们是调用函数进去检查,条件不满足时还会造成阻塞。xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2016-09-20 19:23:51 257

原创 (三)6 poll和sellct

一、系统调用select的简介简单来说,select这个系统调用的作用就是在应用层调用驱动函数中的poll来检测指定的文件的状态(读、写和异常)。如果某个状态满足,select函数调用成功后返回,应用程序就可以通过指定的函数来判断现在的文件状态。注意的是:select可以指定判断的时间,指定时间内,应用程序会阻塞在select函数,直到状态满足或者超时。xx

2016-09-20 19:22:03 368

原创 (三)5阻塞型IO实现

一、休眠简介进程休眠,简单的说就是正在运行的进程让出CPU。休眠的进程会被内核搁置在在一边,只有当内核再次把休眠的进程唤醒,进程才会会重新在CPU运行。这是内核中的进程调度,以后的章节会介绍。现在应该先知道这样的一个概念,一个CPU在同一时间只能有一个进程在运行,在宏观上,我们觉得是所有进程同时进行的。实际上并不是这样,内核给每个进程分配了4G的虚拟内存,并且让每个进程

2016-09-20 19:19:39 431

原创 (三)4.ioctl的实现

一、ioctl的简介:   虽然在文件操作结构体"struct file_operations"中有很多对应的设备操作函数,但是有些命令是实在找不到对应的操作函数。如CD-ROM的驱动,想要一个弹出光驱的操作,这种操作并不是所有的字符设备都需要的,所以文件操作结构体也不会有对应的函数操作。出于这样的原因,ioctl就有它的用处了————一些没办法归类的函数就统一放在io

2016-09-20 19:17:47 348

原创 (三)3面向对象思想和lseek

一、结构体struct file和struct inode在之前写的函数,全部是定义了一些零散的全局变量。有没有办法整合成到一个结构体当中?这样的话,看起来和用起来都比较方便。接下来就要说这方面的问题。不过先要介绍一下除了fops以外的两个比较重要的结构体:1)struct file在内核中,file结构体是用来维护打开的文件的。

2016-09-20 19:14:51 322

原创 (三)2.字符型设备的操作open、close、read、write

一、文件操作结构体file_operations继续上次没讲完的问题,文件操作结构体到底是什么东西,为什么我注册了设备之后什么现象都没有?可以验证文件操作结构体的内容。file_operations是一个函数指针的集合,用于存放我们定义的用于操作设备的函数的指针,如果我们不定义,它默认保留为NULL。来个文件操作结构体的定义:/*includ

2016-09-20 19:10:30 670

原创 (三)1字符型设备之设备申请

一、驱动的分类:内核驱动大致分为三类:1)字符设备:在今后的接触的大多数都是字符设备,我也只学过这个。2)块设备 :与硬盘相关的设备。3)网络设备:与网络相关的设备。上面的三种设备,我也只是学习过字符设备,所以对后面的两种也没有太多的归纳。稍稍说一下字符设备与块设备之间的区别:1)传输数据大小:字符设备以字节方式进行存

2016-09-20 19:08:34 808

原创 (二):模块相关的基础概念

一、初探linux内核模块内核模块:内核本身是很庞大的一个结构,需要的组件很多。编译内核时,用户 可以把所有的代码编译进内核,但是这样会引起两个问题:一是内核过大;二是 当需要添加或者删除内核时,需要重新再编译内核。所以有了内核模块的概念。 模块并不编译到内核中,编译后存放在指定的目录,当需要使用时动态加载。1.1下面是一个非常经典的hello world代码:

2016-09-20 19:05:14 342

原创 (一)内核相关的基础概念

一.linux设备驱动的作用内核:用于管理软硬件资源,并提供运行环境。如分配4G虚拟空间等。linux设备驱动:是连接硬件和内核之间的桥梁。linux系统按个人理解可按下划分:应用层:包括POSIX接口,LIBC,图形库等,用于给用户提供访问 内核的接口。属于用户态,ARM运行在用户模式(usr)或 者系统模式(sys)下。内核层:应用程序调

2016-09-20 18:57:01 643

转载 linux驱动中platform设备驱动模型

platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver。Linux 2.6的设备驱动模型中,把I2C、RTC、LCD等都归纳为platform_device。总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。Linux2.6

2016-09-14 11:16:59 352 1

转载 MISC混杂设备 struct miscdevice /misc_register()/misc_deregister()

在Linux系统中,存在一类字符设备,他们共享一个主设备号(10),但此设备号不同,我们称这类设备为混杂设备(miscdeivce),查看/proc/device中可以看到一个名为misc的主设备号为10.所有的混杂设备形成一个链表,对设备访问时内核根据次设备号找到对应的miscdevice设备。相对于普通字符设备驱动,它不需要自己去生成设备文件。Linux内核使用struct miscd

2016-09-13 16:28:47 170

原创 PV原语

在计算机操作系统中,PV操作是进程管理中的难点。首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:    P(S):①将信号量S的值减1,即S=S-1;           ②如果S³0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。    V(S):①将信号量S的值加1,即S=S+1;      

2016-09-12 19:52:16 1106

转载 Makefile使用总结

makefile使用总结

2016-09-11 21:35:57 154

原创 linux中直接内存访问(DMA)

1. 什么是DMA直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。 2. DMA数据传输有两种方式引发数据传输:第一种情况:软件对数据的请求1. 当进程调用read,驱动程序函数分配一个DMA缓冲区,并让硬件将数据传输到这个缓冲区中。进程处于睡眠状态。2. 硬件将数据写

2016-09-11 20:54:30 2196

原创 linux中的物理地址,虚拟地址,总线地址的区别

1 逻辑地址《understanding the linux kernel》上的解释是与虚拟地址相关,基于硬件MMU与软件内存管理的一个概念,具体可以看UTLK的第二章内存寻址,有很详细的解释。但是工作中之前用到的MIPS架构的处理器的解释却有出入,在《MIPS体系架构透视》一书中,逻辑地址是跟MMU无关的,MIPS地址空间划分中,Kseg0 Kseg1地址空间与真实的

2016-09-11 09:59:31 3654 1

转载 Linux设备模型firmware(固件)

硬件越来越复杂,硬件的许多功能使用了程序实现,与直接硬件实现相比,固件拥有处理复杂事物的灵活性和便于升级、维护等优点。固件(firmware)就是这样的一段在设备硬件自身中执行的程序,通过固件标准驱动程序才能实现特定机器的操作,如:光驱、刻录机等都有内部的固件。固件一般存放在设备上的flash存储器中,但出于成本和灵活性考虑,许多设备都将固件的映像(image)以文件的形式存放在硬盘中,设备驱

2016-09-10 19:46:35 4971

Detection and Identification of Cyclostationary Signals

这是一份bpsk循环谱的文件,这里介绍了FAM和SSCA两种算法 文章后面有代码 自己拷贝

2016-03-30

25_继承的由来 和 继承的访问控制权限_2 video

25_继承的由来 和 继承的访问控制权限_2 javase视频文件

2016-03-28

23_static(2) video

23_static(2) javase 视频文件

2016-03-28

22_static video

22_static javase 视频文件

2016-03-28

27_Java为什么没有多继承

27_Java为什么没有多继承 javase video file

2016-03-28

26_面向对象的继承反映

26_面向对象的继承反映 javase video file

2016-03-28

24_继承的由来 和 继承的访问控制权限 video

24_继承的由来 和 继承的访问控制权限 javase video file

2016-03-28

C++ Sort summary

c++中所有的排序算法,包含选择,插入,冒泡,希尔,归并,快速等排序算法,可以用txt文件打开,没装C++编辑器也可以打开

2016-03-27

BPSk循环谱

matlab 文件 bpsk产生循环谱

2016-03-26

18_构造函数 视频

18_构造函数 视频文件(javase)

2016-03-24

17_函数的重载

17_函数的重载 视频文件(javase)

2016-03-24

14_构造函数 视频

14_构造函数 视频文件(javase)

2016-03-24

C++初级到精髓3本书

C++初级到精髓3本书 下载下来保留着 等忘记了的时候看看

2016-03-24

20_static 视频

20_static. 视频文件(javase)

2016-03-24

19_this 视频

19_this 视频文件(javase)

2016-03-24

16_复习 视频

16_复习 视频文件(javase)

2016-03-24

15_UltraEdit的使用 视频

15_UltraEdit的使用 视频文件(javase)

2016-03-24

13_访问控制符_2 视频

13_访问控制符_2 视频文件(javase)

2016-03-24

12_访问控制符_1 视频

12_访问控制符_1 视频文件(javase)

2016-03-24

11_内存分配 视频

11_内存分配 视频文件(javase)

2016-03-24

MTD原始设备与FLASH硬件驱动的对话

描述了nand flash在linux内核被调用一页的过程

2016-08-25

linux驱动程序设计从入门到精通

适合嵌入式初学者

2016-08-25

BootLoader技术内幕

分析了bootloader的启动过程,真的很不错

2016-08-19

keil上开发S3C2440

在MDK上开发S3C2440,以前开发是在ADS上开发,但是ADS好像不支持win7/win8等系统

2016-08-12

mini2440原理图

mini2440开发板原理图

2016-08-12

SD3.0(英文版)

SD3.0协议标准

2016-08-10

SD2.0协议(中文版)

SD卡协议标准

2016-08-10

S3C2440 裸机开发 SPI

S3C2440 裸机开发 SPI 只有一个main函数,要参考更详细可以下载资源页的另一文件

2016-08-03

S3C2440 SPI 裸机开发

S3C2440 SPI 裸机开发,ADS项目文件,可供参考

2016-08-03

CuteFTP.Pro.v9.0.5.0007

本人测试过可用 不用注册码 先不要生成快捷方式 替换之后在生成 非常完美

2016-07-16

S3C2440与S3C6410中文数据手册

想学嵌入式的可以参考下,两个常用芯片的中文数据手册,许多开发板都是采用这两款芯片做主芯片

2016-07-07

S3C2440裸机学习心得

很多同学想学嵌入式,一开始就往Linux方向走是不明智的,可以先搞裸机程序,对底层比较了解才去搞内核驱动层

2016-07-06

计算机操作系统.

讲操作系统挺不错的书,买一本要好几十呢 ,建议收藏

2016-06-06

糗百桌面版

代码所用的程序开发工具VS2013,开发环境.net2.0,开发语言c#。流程:首先利用HttpGet请求去获取糗百的网页内容,再利用正则表达式从网页源码中获取所需要的内容,最后进行数据绑定。

2016-05-11

java面试试题

java面试题汇总,看一遍会让收获不少

2016-04-23

c语言代码的120个小建议

改善自己编写代码的风格,适应企业用人标准

2016-04-18

Android2016开发规范

Android开发要求及规范,很全面

2016-04-08

java思维导图

java知识点概括图,所有知识点尽收眼底 不到2M大小

2016-04-05

apktool工具

apktool工具,经验证可用

2016-03-31

Qt模仿酷狗音乐UI界面

使用Qt编写纯代码,模仿酷狗音乐界面,实现了基本的界面。给其他做QT开发的做个参考

2016-03-31

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除