armbain调用mipi摄像头

替换内核

【非本机替换内核】

在这里也可以像本机替换内核一样直接执行#make,但本文将编译内核和编译模块分开来执行,但原理和结果是一样的。

1)编译内核:

       #make bzImage

内核编译成功后,会在源码树根目录即linux-3.12.5/arch/x86_64/boot/目录中生成一个新内核的映像文件bzImage。

注:对于大内核(比如需要SCSI支持),make bzImage (推荐)

对于小内核,make zImage。

       2)编译模块:

       #make modules

                   编译可加载模块(即内核选项中选择为M的选项),以便将来使用insmod命令进行加载。编译时间跟M选项的数量有关。 

3)安装模块:

#make modules_install

       即将编译好的modules拷贝到/lib/modules下。

4)安装内核:

       由于不是本机替换内核,所以我们需要将新生成的内核文件拷贝到要替换内核的机器上。需要拷贝的内核文件为主要有4个,分别是:.config,bzImage,System.map 和系统/lib/modules/linux-3.12.5目录。

具体操作如下:

(1)将生成的linux-3.12.5/.config 拷贝到要替换内核系统的/boot下,并重命名为config-3.12.5

(2)将生成的linux-3.12.5/arch/x86-64/boot/bzImage 拷贝到要替换内核系统的/boot下,并重命名为vmlinuz-3.12.5(注:这里需特别注意拷贝后的文件名变为vmlinuz-x.x.x)。

(3)将生成的linux-3.12.5/System.map 拷贝到要替换内核系统的/boot下,并重命名为System.map-3.12.5

(4)将make modules_install生成的系统目录/lib/modules/linux-3.12.5 拷贝到要替换内核系统的/lib/modules下。

(5)在要替换新内核的系统的/lib/modules目录下执行以下命令:

        $ sudo update-initramfs -c -k4.4.179-rk3399,生成/boot/initrd.img-4.4.179-rk3399

$ sudo update-grub(或#update-grub2), 更新启动加载文件。

 

 

make ARCH=arm64  nanopi4-images -j20
sudo make install

 

 


FriendlyArm调用mipi脚本

cd /tmp/
git clone https://github.com/friendlyarm/gst-camera-sh.git
sudo cp gst-camera-sh/*.sh /usr/bin/

 

 

$ gst-camera.sh



Start MIPI CSI Camera Preview [/dev/video0] ...
XCAM INFO device_manager.cpp:90: open /usr/lib/libcam_ia.so successed
XCAM INFO device_manager.cpp:96: open /usr/lib/libcam_engine_cifisp.so successed
XCAM INFO device_manager.cpp:106: dlsym rkisp_start success
Setting pipeline to PAUSED ...
XCAM WARNING v4l2_device.cpp:171: set capture mode(0x00004000) failed but continue
XCAM INFO x3a_image_process_center.cpp:48: Add processor(IspImageProcessor) into image processor center
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
XCAM INFO v4l2_device.cpp:322: device(/dev/video0) set format(w:1280, h:720, pixelformat:NV12, bytesperline:1280)
XCAM WARNING rkisp_device.cpp:48: atomisp device(/dev/video0) get framerate failed 
XCAM ERROR rkisp_device.cpp:72: atomisp device(/dev/video0) try subdev format failed
XCAM WARNING v4l2_device.cpp:233: device(/dev/video0) pre_set_format failed
XCAM INFO v4l2_device.cpp:300: device(/dev/video0) set format(w:1280, h:720, pixelformat:NV12, bytesperline:1280,image_size:1382400)
XCAM INFO device_manager.cpp:208: device manager start, capture dev fd: 10

CAMHALInfo:   CAMHALVERSION is: 2.0.9.0

CAMHALInfo:   libcam_ia: 2.0.c.0

CAMHALInfo:   init:tuningFile /etc/cam_iq/ov13850.xml
CAMHALInfo:   load tunning file success.
AWB: AwbConfigure: AWB_VERSION_10

CAMHALInfo:   rkisp_start: interface isp dev started
XCAM INFO device_manager.cpp:211: device manager isp_init _rkisp_engine:0x7f8c0020b0

XCAM INFO device_manager.cpp:216: rkisp_init engine succeed

XCAM INFO v4l2_device.cpp:473: request buffers in device(/dev/video0)
XCAM INFO v4l2_device.cpp:563: init buffer poll in device(/dev/video0), cnt: 8
XCAM INFO v4l2_device.cpp:440: device(/dev/video0) started successfully
XCAM INFO xcam_analyzer.cpp:164: Analyzer(X3aAnalyzerSimple) initialized(w:1280, h:720).
XCAM INFO xcam_analyzer.cpp:213: Analyzer(X3aAnalyzerSimple) started in async mode.
XCAM INFO image_processor.cpp:182: ImageProcessor(IspImageProcessor) started
XCAM INFO x3a_image_process_center.cpp:84: 3a process center started
AWB: AwbConfigure: AWB_VERSION_10



===================================================================================


handling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:04:35.964235671
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
XCAM INFO xcam_analyzer.cpp:226: Analyzer(X3aAnalyzerSimple) stopped.
XCAM INFO xcam_analyzer.cpp:178: Analyzer(X3aAnalyzerSimple) deinited.
XCAM INFO device_manager.cpp:343: deinit rkisp engine

CAMHALInfo:   rkisp_stop: rkisp interface ready to deinit
XCAM INFO v4l2_device.cpp:457: device(/dev/video0) stopped
Setting pipeline to NULL ...
Freeing pipeline ...


完整命令:

gst-launch-1.0 rkisp device=/dev/video1 io-mode=4 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! rkximagesink

 

$ vim gst-camera.sh

 

if [ ${CameraTypes[$icam]} = "mipi" ]; then
                CMD="gst-launch-1.0 rkisp ${rkargs} io-mode=4 \
                        ! video/x-raw,format=NV12,${PreviewModes[$icam]} \
                        ! ${Sinks[$icam]}"

 


安装GStreamer

sudo apt install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio

出错:

no element "rkisp"

没有元素 “rkisp”,缺少插件,名称为libgsrkisp.so

https://github.com/01org/libxcam

 

 

 

https://github.com/rockchip-linux/camera_engine_rkisp

 

$ vim productConfigs.mk line 16
CROSS_COMPILE ?= /usr/bin/
$ sudo make ARCH=arm

 

./autogen.sh –prefix=/home/install –nocheck 
fatal: Not a git repository (or any of the parent directories): .git 
ln: failed to create symbolic link ‘.git/hooks/pre-commit’: No such file or directory 
+ passing argument –prefix=/home/install to configure 
+ autotools version check disabled 
+ options passed to configure: –prefix=/home/install 
+ check for build tools: skipped version checks 
patching file po/Makefile.in.in 
Hunk #1 succeeded at 15 with fuzz 2 (offset 4 lines). 
+ running autopoint –force… 
./autogen.sh: 349: ./autogen.sh: autopoint: not found

这个问题主要是因为auto相关的工具没有安装成功, 
使用apt install 安装就好了 
sudo apt install autoconf automake libtool autopoint

 

configure: No package 'glib-2.0' found 
No package 'gobject-2.0' found 
No package 'gthread-2.0' found 
No package 'gmodule-no-export-2.0' found 
configure: error: This package requires GLib >= 2.20 to compile.




sudo apt-get install libperl-dev libgtk2.0-dev  libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev

 

https://forum.armbian.com/topic/9528-nano-pi-m4-camera-module/

 

If you want to get your hands dirty i can give you briefly the steps if i recall correctly (it works on NanoPi M4, so should work on NanoPi-T4) but unfortunately, i did not take note:

 

a) encode/decode is done by gstreamer (decoding by mvp)

install gstreamer (if not already installed)

sudo apt install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio


 

b) clone https://github.com/rockchip-linux/mpp , build and install it (install dependencies fisrt)



cmake -DRKPLATFORM=ON -DHAVE_DRM=ON && make

sudo make install

 

c) clone gstreamer-rockchip (i can't remember if i did for the -extra also)

git clone https://github.com/rockchip-linux/gstreamer-rockchip.git
cd gstreamer-rockchip
./autogen.sh --disable-rkximage
make
sudo make install

sudo ldconfig


vim ./gst/rkximage/rkx_kmsutils.c:50:3

 

git clone https://github.com/rockchip-linux/gstreamer-rockchip-extra

sudo ./autogen.sh 
sudo make
sudo make install
sudo ldconfig


d) check if the plugins are then installed correctly

gst-inspect-1.0|grep 4l2
gst-inspect-1.0|grep rkcamsrc

 

gst-inspect-1.0 | grep rk
gst-inspect-1.0 rkximage
gst-inspect-1.0 rkv4l2
 

 

You will need libdrm-dev and some other dependencies i can't remember.

 

This steps should work on any RK3399.

 

Have fun.



vim ./gst/kms/gstkmsutils.c




https://github.com/rockchip-linux/camera_engine_rkisp

 


MIPI OV13850

 

 

 


GStreamer文档

https://gstreamer.freedesktop.org/documentation/installing/index.html?gi-language=c#

 


element总结

        前面几篇较详细的介绍了v4l2src、videodecoder编码、gst-omx以及videosink显示几个element,介绍它们与其他element交互的操作流程,这一次,我们对之前的文章做一个总结。


element创建
  由于一开始gstreamer在加载的时候,会扫描/usr/lib/gstreamer-1.0目录下的库并加载,识别其中的feature,并记录相关的信息。当使用到某一功能的时候,检查gstreamer core是否支持该功能,如果有,则加载相应的库,获取信息,创建相应的element实例,这样,element创建出来了。


element link
  创建之后,将会添加到bin并且link element,而在通过link的时候,将会通过gst_pad_query_caps (pad, NULL)调用到相应element的查询函数。这个查询函数将会调用到element的init()函数通过gst_pad_set_query_function()设置的pad查询函数,而该查询函数在element link阶段一般都是返回pad template caps。因为这个阶段还没有进行打开设备、设备初始化等操作,不知道element真正支持的caps,但element link阶段只要查询的caps有交集即可link成功,所以问题不大。


NULL->READY
  该状态下,将会进行相应的设备初始化,根据相应的class调用start()函数或者open()等函数初始化相应的硬件设备,初始化class的结构参数等。


READY->PAUSED
  这一步,将会进一步申请资源,确定相应的参数设置,重要的一步,将会激活pad,激活的过程,将会调用到element init中通过gst_pad_set_activate_function()设置的pad激活函数,而在激活的同时,也将会选择相应的push模式,所以又会调用到element init通过gst_pad_set_activatemode_function()设置的pad激活模式函数。
  在激活pad的时候,一般的将会设置了GST_PAD_FLAG_NEED_RECONFIGURE标志位,在element中将会有检查这个标志位,然后将会进行协商操作,在协商的过程中将会多次调用到element的pad查询函数,为什么说是多次调用呢,一开始link时调用,得到的是pad template caps,在进行设备初始化之后,将会可以查询实际的硬件,得到真正支持的caps,这样,上游将得知下游支持的caps。
  caps之后,就将是接收到stream-start事件,上游告知element,将会开始传输数据,谁将负责处理EVENT呢,一般的element init中通过gst_pad_set_event_function()设置了pad的EVENT处理函数,element接收到该事件,提取相应的信息初始化结构。
  虽然上面反馈了caps到上游,上游根据自身情况选择相应的caps之后,又将会发送accept-caps query,再次查询,element是否支持该caps。
  上游再次得到反馈之后,将会发送caps事件到element,element接收该事件并将会set_caps。同时,上游会发送GST_QUERY_ALLOCATION查询缓冲区的属性,确定buffer pool缓冲区属性,决定时候申请buffer pool,以及激活pool等操作。
  最后,就是GST_EVENT_SEGMENT和TAG EVENT。segment将描述接下来的数据时间戳范围,之后的数据都将需要在这个范围才可以正常使用。TAG则是描述数据的其他一些信息,这些,element的event处理函数将会有相应的操作。
  接下来就是数据的预滚(preroll)。数据到达的时候,将会调用element init中通过gst_pad_set_chain_function()设置的chain函数。检查数据的时间戳是否在segment内,数据同步,通过preroll函数进行预滚,最后就是commit状态,进入PAUSED。


PAUSED->PLAYING
  在这个过程,将会设置clock,时钟运行,chain函数接收到数据的时候,检查时间有效性,进行数据同步、处理,push到下游,发送QOS事件到上游,完成一个循环。


总结
  上述的操作流程,不可能每个element都会是一样的操作,但是大致流程是差不多的,在接触一个新的插件的时候,可以通过上述的流程阅读代码,了解插件是如何操作的。当然,最好的,是可以通过捕获运行log信息来分析具体的流程。
 


Gstreamer常用命令

#用于检查元素的所有属性,信号,动态参数和对象层次结构
$ gst-inspect-1.0 

#gst-launch-1.0是一个简单的类似脚本的命令行应用程序,可用于测试管道。
$ gst-launch-1.0 
 gst-launch-1.0 rkisp device=/dev/video1 io-mode=4 ! video/x-raw,format=NV12,width=1280,height=720,framerate=30/1 ! kmssink

 

 

 


rockchip-isp1

http://blog.iotwrt.com/media/2017/10/01/camera/

 

 

 


原来FriendlyElec发行版使用gstreamer-camera而不是gstreamer-plugins / extra - 我希望 - 这就是一招:) ( 来自github.com/rockchip-linux/repos )

git clone https://github.com/rockchip-linux/gstreamer-camera

sudo ./autogen
sudo make
sudo make install

查看插件扫描路径
$ echo $GST_PLUGIN_PATH
#查看插件信息
$ gst-inspect-1.0 rkisp

Factory Details:
  Rank                     none (0)
  Long-name                Gstreamer Plugin For Rockchip ISP Source
  Klass                    Source/Base
  Description              Capture camera video with rockchip ISP support
  Author                   Jacob Chen <cc@rock-chips.com>

Plugin Details:
  Name                     rkisp
  Description              rkisp
  Filename                 /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstrkisp.so
  Version                  1.0
  License                  unknown
  Source module            rkisp
  Binary package           librkisp
  Origin URL               https://github.com/01org/libxcam

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseSrc
                         +----GstPushSrc
                               +----GstXCamSrc

Implemented Interfaces:
  GsXCam3AInterface

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw
                 format: { (string)I420, (string)YV12, (string)YUY2, (string)UYVY, (string)AYUV, (string)RGBx, (string)BGRx, (string)xRGB, (string)xBGR, (string)RGBA, (string)BGRA, (string)ARGB, (string)ABGR, (string)RGB, (string)BGR, (string)Y41B, (string)Y42B, (string)YVYU, (string)Y444, (string)v210, (string)v216, (string)NV12, (string)NV21, (string)GRAY8, (string)GRAY16_BE, (string)GRAY16_LE, (string)v308, (string)RGB16, (string)BGR16, (string)RGB15, (string)BGR15, (string)UYVP, (string)A420, (string)RGB8P, (string)YUV9, (string)YVU9, (string)IYU1, (string)ARGB64, (string)AYUV64, (string)r210, (string)I420_10BE, (string)I420_10LE, (string)I422_10BE, (string)I422_10LE, (string)Y444_10BE, (string)Y444_10LE, (string)GBR, (string)GBR_10BE, (string)GBR_10LE, (string)NV16, (string)NV24, (string)NV12_64Z32, (string)A420_10BE, (string)A420_10LE, (string)A422_10BE, (string)A422_10LE, (string)A444_10BE, (string)A444_10LE, (string)NV61, (string)P010_10BE, (string)P010_10LE, (string)IYU2, (string)VYUY, (string)GBRA, (string)GBRA_10BE, (string)GBRA_10LE, (string)GBR_12BE, (string)GBR_12LE, (string)GBRA_12BE, (string)GBRA_12LE, (string)I420_12BE, (string)I420_12LE, (string)I422_12BE, (string)I422_12LE, (string)Y444_12BE, (string)Y444_12LE }
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
              framerate: [ 0/1, 2147483647/1 ]

Element has no clocking capabilities.
Element has no URI handling capabilities.

Pads:
  SRC: 'src'
    Pad Template: 'src'

Element Properties:
  name                : The name of the object
                        flags: readable, writable
                        String. Default: "xcamsrc0"
  parent              : The parent of the object
                        flags: readable, writable
                        Object of type "GstObject"
  blocksize           : Size in bytes to read per buffer (-1 = default)
                        flags: readable, writable
                        Unsigned Integer. Range: 0 - 4294967295 Default: 4096 
  num-buffers         : Number of buffers to output before sending EOS (-1 = unlimited)
                        flags: readable, writable
                        Integer. Range: -1 - 2147483647 Default: -1 
  typefind            : Run typefind before negotiating (deprecated, non-functional)
                        flags: readable, writable, deprecated
                        Boolean. Default: false
  do-timestamp        : Apply current stream time to buffers
                        flags: readable, writable
                        Boolean. Default: true
  device              : Device location
                        flags: readable, writable
                        String. Default: null
  io-mode             : Memory mode
                        flags: readable, writable
                        Enum "GstXCamMemoryModeType" Default: 1, "mmap"
                           (1): mmap             - memory map mode
                           (2): userptr          - user pointer mode
                           (3): overlay          - overlay mode
                           (4): dmabuf           - dmabuf mode
  buffercount         : buffer count
                        flags: readable, writable
                        Integer. Range: 0 - 2147483647 Default: 4 
  field               : field
                        flags: readable, writable
                        Enum "GstXCamSrcFieldType" Default: 1, "none"
                           (1): none             - no field
                           (2): top              - top field
                           (3): bottom           - bottom field
                           (4): interlaced       - interlaced fields
                           (5): seq-tb           - both fields sequential, top first
                           (6): seq-bt           - both fields sequential, bottom first
                           (7): alternate        - both fields alternating
                           (8): interlaced-tb    - interlaced fields, top first
                           (9): interlaced-bt    - interlaced fields, bottom first
  imageprocessor      : Image Processor
                        flags: readable, writable
                        Enum "GstXCamSrcImageProcessorType" Default: 0, "rkisp"
                           (0): rkisp            - ISP image processor
  analyzer            : 3A Analyzer
                        flags: readable, writable
                        Enum "GstXCamSrcAnalyzerType" Default: 0, "simple"
                           (0): simple           - simple 3A analyzer
                           (1): aiq              - aiq 3A analyzer
                           (2): rockchip         - dynamic 3A analyzer
                           (3): rockchip         - rkiq 3A analyzer
  path-iqf            : Path to IQ file
                        flags: readable, writable
                        String. Default: "/etc/cam_iq.xml"
  enable-3a           : Enable 3A
                        flags: readable, writable
                        Boolean. Default: true
  input-format        : Input pixel format
                        flags: readable, writable
                        String. Default: ""
  enable-usb          : Enable USB camera
                        flags: readable, writable
                        Boolean. Default: false
  fake-input          : Use the specified raw file as fake input instead of live camera
                        flags: readable, writable
                        String. Default: null

由上述信息得出插件安装路径:/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstaudiotestsrc.so

$ cd /usr/lib/aarch64-linux-gnu/gstreamer-1.0/
$ ldd libgstrkisp.so


linux-vdso.so.1 (0x0000007fa8c5a000)
	libgstbase-1.0.so.0 => /usr/lib/aarch64-linux-gnu/libgstbase-1.0.so.0 (0x0000007fa8b40000)
	libgstreamer-1.0.so.0 => /usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so.0 (0x0000007fa8a11000)
	libgobject-2.0.so.0 => /usr/lib/aarch64-linux-gnu/libgobject-2.0.so.0 (0x0000007fa89b3000)
	libglib-2.0.so.0 => /usr/lib/aarch64-linux-gnu/libglib-2.0.so.0 (0x0000007fa88a5000)
	libgstallocators-1.0.so.0 => /usr/lib/aarch64-linux-gnu/libgstallocators-1.0.so.0 (0x0000007fa8891000)
	libgstvideo-1.0.so.0 => /usr/lib/aarch64-linux-gnu/libgstvideo-1.0.so.0 (0x0000007fa87fe000)
	librkisp.so => /usr/lib/librkisp.so (0x0000007fa8570000)
	libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007fa83dd000)
	libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007fa83b1000)
	libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007fa838d000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fa8234000)
	/lib/ld-linux-aarch64.so.1 (0x0000007fa8c2f000)
	libgmodule-2.0.so.0 => /usr/lib/aarch64-linux-gnu/libgmodule-2.0.so.0 (0x0000007fa8220000)
	libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007fa8166000)
	libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007fa8151000)
	libffi.so.6 => /usr/lib/aarch64-linux-gnu/libffi.so.6 (0x0000007fa8139000)
	libpcre.so.3 => /lib/aarch64-linux-gnu/libpcre.so.3 (0x0000007fa80c7000)
	liborc-0.4.so.0 => /usr/lib/aarch64-linux-gnu/liborc-0.4.so.0 (0x0000007fa804e000)
	libdrm.so.2 => /usr/lib/aarch64-linux-gnu/libdrm.so.2 (0x0000007fa802f000)

 

 

#查看插件信息
$ gst-inspect-1.0

...
...
Total count: 249 plugins (3 blacklist entries not shown), 1398 features

有三个插件在黑名单



#查看黑名单插件
$ gst-inspect-1.0  -b

Blacklisted files:
  libgstkmssink.so
  librockchip_vpu.so
  librockchip_mpp.so

Total count: 3 blacklisted files



$ cd ~/.cache/gstreamer-1.0
$ sudo rm registry.aarch64.bin 
$ sudo GST_DEBUG=2,GST_PLUGIN_LOADING:5,GST_REGISTRY:5 gst-inspect-1.0 


#验证插件信息
gst-inspect-1.0 ./libgstkmssink.so

#如果能找到信息,将该插件移到/usr/lib/aarch64-linux-gnu/gstreamer-1.0/目录
#如果找不到,将插件文件移到/usr/lib/aarch64-linux-gnu/目录

#安装rkisp插件后,执行 sudo gst-camera.sh

报错:

(gst-launch-1.0:5411): GStreamer-WARNING **: 07:18:44.346: Failed to load plugin '/usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstkms.so': /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstkms.so: undefined symbol: gst_video_overlay_install_properties
WARNING: erroneous pipeline: no element "kmssink"

https://github.com/rockchip-linux/gstreamer-rockchip/issues/12

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值