利用/proc/scsi/usb-storage来判断 U盘的移入/移出

USB总线专题(五)——Mass storage 设备相关知识 前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。 1. 定义 小型计算机系统接口(SCSI,Small Computer System Interface):是一种用于计算机及其周边设备之间(硬盘、软驱、光驱、打印机、扫描仪等)系统级接口的独立处理器标准。SCSI 标准定义命令、通信协议以及实体的电气特性(换成 OSI... 阅读详情

/proc/scsi/下的文件夹usb-storage 在没有插入 U盘的时候,它是不存在的,故我们判断U盘的插入还是移出 就是通过判断opendir这个目录成功还是失败来判断。

  1 #include<stdio.h>

  2 #include<sys/types.h>

  3 #include<dirent.h>

  4 #include<stdlib.h>

  5 

  6 int main(int argc , char* argv[])

  7 {

  8         DIR *dir;

  9         int usb_bool = 0;

 10 

 11         while(1)

 12         {

 13                 /*这个循环体里是守护进程要做的工作*/

 14 

 15                 if((dir = opendir("/proc/scsi/usb-storage" )) != NULL)  //存储设备是插上了

 16                 {

 17                         usb_bool = 1;

 18                         printf("up  %p /n" ,dir);

 19                         closedir(dir);

 20                 }

 21                 else

 22                 {

 23                         printf("down %p/n" ,dir);

 24                         usb_bool = 0;  //拔下来的时候一定要清0  

 25                 }

 26                 sleep(3);

 27         }

 28 

 29 }

 

 输出结果:

magic@ubuntu:~/work/Linux_System_Program/digital--005$ ./test_usb 

up  0x8ecd008 

up  0x8ecd008 

down (nil)

down (nil)

down (nil)

down (nil)

down (nil)

down (nil)

down (nil)

up  0x8ecd008 

up  0x8ecd008 

up  0x8ecd008 

up  0x8ecd008 

up  0x8ecd008 

down (nil)

down (nil)

down (nil)

down (nil)

down (nil)

up  0x8ecd008 

up  0x8ecd008 

up  0x8ecd008 

 

有的时候,如果由于你opendir后都忘记了closedir,则有时候会造成 你把U盘移出了,仍然可以读取成功,可以尝试重启计算机。。。

USB_SCSI之旅 现在总结一下scsi,scsi协议有很多,所以只总结这次在usb mass storage里面用到的协议,主要包括inquiry,format , read write等等命令。   下面会一个一个总结。   U盘需要处理的命令如下:   1:inquiry:设备的一个描述,告诉host你的设备是什么,名字叫什么,用的什么协议,这里用的SCSI协议—SPC2 2:READ FORMA 阅读详情

相关推荐

Linux下检测USB设备的插拔

在Linux系统中,我们可以使用udev和Linux文件系统来监测和处理USB设备的插拔事件。udev是Linux系统中的一个设备管理框架,它可以在设备插入或移除时触发相应的动作。在脚本中,您可以根据需要添加处理设备插入和移除事件的代码。例如,您可以在设备插入时自动挂载USB磁盘,或在设备移除时执行清理操作。这是一个简单的示例,演示了如何在Linux下使用udev来检测USB设备的插拔事件。您可以根据自己的需求进行进一步的扩展和定制。的udev规则文件,该文件定义了在USB设备插入和移除时执行的脚本。

InjeProgram的博客 1390

usb设备的检测及区分(sata硬盘、优盘及移动硬盘)

原理: 1.如果有外置usb设备插入,会产生/proc/scsi/usb-storage目录(ide硬盘上默认 没有),并且会在/proc/scsi/usb-storage目录中产生数字文件,此文件存储了设 备的相关信息。 2./sys/class/scsi_device/目录中会有几个scsi设备的目录,以数字开头。(ide 中默认无子目录,sata硬盘默认有子目录),类似1:0:0或

Android/Linux的专栏 6846

USB协议学习(三)大容量存储设备SCSI协议分析

笔者来简单介绍一下SCSI得协议命令。

张一西的博客 4111

【Linux】linux中USB设备查看检测技术总结(21种方法)

目录 1、lsusb命令 2、fdisk命令(root用户下) 3、lsblk命令 4、demsg命令 5、ls /dev/sd* 6、ls /dev/input 7、cat /proc/scsi/scsi 8、ls /proc/scsi/usb-storage/ 9、cat /proc/bus/input/devices 10、ls /run/media/root(这个...

rong11417的博客 2万+

视频动作识别、行为识别、时空动作检测数据集整理(持续更新)

动作、行为、事件 在计算机视觉的相关研究中,人体的动作、行为识别是一个基础研究问题。但目前识别、检测人类的动作/行为仍然是一个巨大的挑战。这里整理下当前相关的细分任务、数据集和开源代码(持续更新中)。

人工智能算法与工程实践 3万+

3D识别建模 — 基于ReconstructMe和EAGLE EYES SCANNER的实现

3D实体识别建模,作为3D打印反向工程的一个重要环节,今天就让我们利用ReconstructMe和EAGLE EYES SCANNER来了解一下。 第一步、软件和硬件准备就绪 ReconstructMe下载并安装 http://reconstructme.net/?wpdmdl=160 EAGLE EYES SCANNER直接将相应USB插入电脑接口即OK,之后在    中点击搜索“设备管理...

qq_40013290的博客 881

如何linux查看U盘是否存在

使用命令:ls /proc/scsi/usb-storage 如果存在代表有一个或多个u盘挂载,如果没有则没有u盘 如: #ls /proc/scsi/usb-storage/ 0

weixin_41349207的博客 1570

Open5GS实战:从零搭建树莓派5G核心网并与商用终端联调

本文详细介绍了如何在树莓派5上从零开始搭建基于Open5GS的5G核心网,涵盖系统准备、依赖安装、源码编译、关键配置修改及服务启动全流程。通过整合SDR基站与商用终端进行端到端联调,为开发者和研究者提供了一个低成本、可实践的5G网络实验平台,助力物联网与边缘计算应用的本地化测试与验证。

weixin_29194255的博客 159

linux下区分各种SCSI磁盘类型

ATA硬盘、ISCSI磁盘及USB盘等都挂到scsi总线上,磁盘名称都是sd?开头的,对于一个sd?的磁盘如何知道它是属于哪类的磁盘?找到一个方法,通过/sys/class/scsi_disk建立一张sd? host_no的对应表,又通过/syc/class/scsi_host建立一张host_no 每个scsi host的proc_name对应表,然后就可以通过两张表重新一张sd? proc_name的对应表,通过proc_name我们就可能知道sd?这个磁盘是属于哪个类型的,比如:usb scsi

duwenyong的专栏 9579

基于BERTopic模型的英文20新闻数据集主题聚类及可视化

BERTopic是基于深度学习的一种主题建模方法。BERT是一种用于NLP的预训练策略,它成功地利用了句子的深层语义信息。

Cachel Wood的博客 1460

Unity之Hololens2开发MRTK Profile详解

配置 MRTK 的主要方式之一是使用基础包中的配置文件。场景中的主要对象具有活动配置文件 - 一个 ScriptableObject。顶级 MRTK 配置配置文件包含主核心系统的每个核心的子配置文件数据,每个主核心系统都旨在配置其相应子系统的行为。此外,这些子配置文件也是 ScriptableObjects,因此可以包含对低它们一级的其他配置文件对象的引用。实质上,有一个包含已连接配置文件的完整树,这些配置文件构成了如何初始化 MRTK 子系统和功能的配置信息。

TxNet 1034

关于linux下检测usb设备

需求: 嵌入式设备需要对U盘进行识别,如果U盘变动则需要清理数据库中某些表,若U盘不变,则保留数据库中某些特定的表。 分析: 若要对U盘进行识别,最精准的办法是识别出U盘的唯一序列号。 解答: 1.经过查找,发现有命令可以直接获取U盘序列号: root@lsy-ubuntu:/home/work/cPro/check_udisk# ap...

刘一儿(嵌入式) 2295

区块链技术概述:从比特币到Web3.0

区块链技术正重塑数字世界的信任机制。本文系统梳理了区块链的发展路径:从比特币的PoW共识和UTXO模型,到以太坊的智能合约和账户体系,直至Web3.0的去中心化互联网愿景。文章详细解析了区块链的核心特性(去中心化、不可篡改等)和数据结构,通过流程图展示了比特币交易生命周期和智能合约执行流程,并对比了Web2.0与Web3.0的关键差异。最后,用Python代码实现了包含区块类、交易处理和挖矿机制的简易区块链系统,为理解区块链底层原理提供了实践参考。

闲人编程的博客 455

USB检测

1.背景ubuntu16.04 server插入U盘后,需要手动挂载,然后才能读取到U盘,本文目标在于实现自动挂载到固定目录,该方法可用于大多数不自动挂载U盘的系统。2.研究2.1.尝试1cat /proc/scsi/usb-storage/2,其中2应该是个热生成值,信息如下,没有想要的设备(如/dev/sdb4) Host scsi2: usb-storage Vendor:

俗科技的博客 661

2019年高教社杯全国大学生数学建模竞赛 C 题:《机场的出租车问题》真题解析与 MATLAB 解决方案

🏆 本文已收录于专栏:《滚雪球学数学建模(含历年真题)》,持续更新最新及历年数学建模竞赛资料,每篇内容力求做到“问题讲透、模型讲清、代码可用、论文可参考”,帮助你从零开始逐步建立完整的数学建模知识体系。

**My Coding Family** 3453

C++性能优化:深入理解缓存一致性与伪共享

在现代多核处理器的世界里,理解缓存一致性和伪共享就像理解一个复杂社会系统的运作规则。正如心理学家阿德勒所说:"人的行为总是有目的的",CPU缓存的每一次同步也都有其深层的硬件逻辑。本文将带你深入探索这些看不见的性能杀手,以及如何在实际项目中与它们优雅共处。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 935

Android usb设备的检测及区分(sata硬盘、优盘及移动硬盘)

原理: 1.如果有外置usb设备插入,会产生/proc/scsi/usb-storage目录(ide硬盘上默认 没有),并且会在/proc/scsi/usb-storage目录中产生数字文件,此文件存储了设 备的相关信息。 2./sys/class/scsi_device/目录中会有几个scsi设备的目录,以数字开头。(ide 中默认无子目录,sata硬盘默认有子目录),类似1:0:0或2:0:0,开头的数字,这个数 字与/proc/scsi/usb-storage目录中的相对应,另外的子目录表示sata硬

weixin_39966398的博客 2470

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Arm平台 Qt检测U盘插拔(三)-----蛋疼的recv()阻塞

因为最终要在tiny210上实现此功能,最终选择了hotplug。 http://hi.baidu.com/hdy5200075/item/7751f48647f3d12a100ef3f6这里是hotplug检测U盘的源码,我在qt里将其写到一个hostplug.h文件里。 #ifndef HOSTPLUG_H #define HOSTPLUG_H #include &lt;iost...

分享技术干货和灵感 926

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

嵌入式linux检测U盘拔插

文章参考:https://blog.youkuaiyun.com/newnewman80/article/details/8766657 说明 做嵌入式开发,尤其在网关、路由器或者其他支持USB设备的终端上,为了提高用户体验,我们常常需要支持自动识别并挂载USB设备功能,USB的热插拔应用广泛,比如U盘、手机、USB网卡等。 某些应用程序,在使用USB设备的过程中,也希望能够侦测到USB断开事件,不至于某些工作因为USB已经不存在而白做,或者就是需要显示U盘是否插入的图标。在Linux下,主要有两种办法检测USB热插拔

weixin_42887343的博客 4746

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

linux 获取优盘信息

这段时间做liveCD优盘管控,需要对优盘信息进行注册管理,所以就要拿到优盘的指纹信息 cat /proc/scsi/usb-storage/* 例子: root@deepin:~# cat /proc/scsi/usb-storage/* Host scsi3: usb-storage Vendor: General Product: USB Flash Disk Serial Number: 04YRD8F50M4ONAPE Protocol: Tr...

1252661442的博客 599

[Linux] USB-Storage驱动 源码阅读笔记(一)

USB-Storage驱动 源码阅读笔记 最近在研究U盘的驱动,遇到很多难以理解的问题,虽然之前也参考过一些很不错的书籍如:《USB那些事》,但最终还是觉得下载一份最新的源码,慢慢啃源码会有更具象的了解,在这里做一些笔记。本文基于linux-5.16.9描述。 我就USB-Storage的调用栈花了个思维导图,放在这了USB-Storage驱动调用思维导图(免费下载) 一、USB子系统 要想了解USB-Storage驱动,我们就要从USB子系统开始说起。 1.USB Core USB core 是USB

qq_42291035的博客 6861

linux如何判断是否插了U盘

很简单 判断/proc/scsi/usb-storage 文件夹是否存在,如果存在代表有一个或多个u盘挂载,如果没有则没有u盘 u盘的目录在/media/ledmedia//u盘名

u011304615的博客 9589

usb storage驱动分析

本文以usb storage设备驱动来分析

鹤冲云霄的专栏 1万+

linux USB大容量设备驱动入门之读取U盘容量

linux USB大容量设备驱动入门之读取U盘容量

我的博客 1195

USB设备检测的一般过程

USB设备检测也是通过/proc目录下的USB文件系统进行的。为了使一个USB设备能够正常工作,必须要现在系统中插入USB桥接器模块。在检测开始时,一般要先检测是否存在/proc/bus/usb目录,若不存在则尝试插入USB桥接模块。现在一般的USB桥接器模块有两种类型,UHCI和OHCI。在决定插入那一个桥接器模块时,可以察看/proc/pci文件来决定。打开此文件,您若发现USB节为 I/O

ZCatLinux --资讯与技术社区--Open Source World----Linux/Shell/DevOPS-- 2088

USB大容量存储设备浅析

当插入U盘,USB主机控制器会识别到该设备是一个海量存储设备,然就就会根据SCSI协议,先发送CBW命令块包,U盘收到后根据SCSI协议解析该报,并回复命令执行状态包(CSW),就是应答,作为对前一个CBW命令块包处理结果的回应。同IDE(ATA)完全不同的接口, IDE接口是普通PC的标准接口,而SCSI并不是专门为硬盘设计的接口,是一种广泛应用于小型机上的高速数据传输技术。IDE、SCSI、USB,并行口,串口,其中并行口与串口的速度非常慢,不提也罢,最主要的就是IDE,usb, SCSI。

奶牛养殖场小马 4482
上一篇: *** glibc detected *** ./test: free(): invalid pointer: 0x0854d1b4 ***
下一篇: 挺实用的---测试sendto 的速率--精确microseconds
伊娃码力
博客等级 码龄16年 52粉丝 36原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值