17_ZYNQ7020开发板_定时器操作

**1.内核中的定时器依赖硬件定时器。**硬件定时器产生固定的频率并产生中断。
命令

petalinux-config -c kernel

在这里插入图片描述
选中Kernel Features按回车进入
在这里插入图片描述
回车进去,选择100Hz ,每秒100个节拍
**2.系统频率越高,时钟精度越高,**100hz 的精度可以达到10ms,1000hz可以达到1ms。频率增加,CPU的负担增加。实验使用100hz就可以了。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们选的是毫秒级别的转换。
3.定时器相关函数:
1.void init_timer(struct timer_list *timer)
初始化定时器,输入参数timer即需要初始化定时器。
2.void add_timer(struct timer_list *timer)
向内核注册定时器,注册后定时器就开始运行,输入参数timer即需要注册的定时器。
3. int del_timer(struct timer_list * timer)
删除定时器,不管定时器是否正在运行,删除正在运行的定时器
4. int del_timer_sync(struct timer_list *timer)
删除定时器,正在运行的定时器timer会等到使用完成后才删除。
5.int mod_timer(struct timer_list *timer, unsigned long expires)
修改定时器的expires超时的时间
原理图
4.原理图
在这里插入图片描述
5.设备树

/include/ "system-conf.dtsi"
/ {
    model = "Zynq ALINX Development Board";
    compatible = "alinx,zynq", "xlnx,zynq-7000";

    aliases {
        ethernet0 = "&gem0";
        serial0 = "&uart1";
    };

    usb_phy0: usb_phy@0 {
        compatible = "ulpi-phy";
        #phy-cells = <0>;
        reg = <0xe0002000 0x1000>;
        view-port = <0x0170>;
        drv-vbus;
    };
    
    amba {
        slcr@f8000000 {
             pinctrl_led_default: led-default {  
                mux {  
                    groups = "gpio0_0_grp";  
                    function = "gpio0";  
                };  

                conf {  
                    pins = "MIO0"; 
                    io-standard = <1>; 
                    bias-disable;  
                    slew-rate = <0>;  
                };      
            }; 
            pinctrl_key_default: key-default {
                mux {
                    groups = "gpio0_50_grp";
                    function = "gpio0";
                };

                conf {
                    pins = "MIO50";
                    io-standard = <1>;
                    bias-high-impedance;
                    slew-rate = <0>;
                };
            };
        };
    };

    alinxled {
        compatible = "alinx-led";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_led_default>;
        alinxled-gpios = <&gpio0 0 0>;
    };

    alinxkey {
        compatible = "alinx-key";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_key_default>;
        alinxkey-gpios = <&gpio0 50 0>;
    };
};

&i2c0 {
    clock-frequency = <100000>;
};

&usb0 {
    dr_mode = "host";
    usb-phy = <&usb_phy0>;
};

&sdhci0 {
    u-boot,dm-pre-reloc;
};

&uart1 {
    u-boot,dm-pre-reloc;
};

&flash0 {
    compatible = "micron,m25p80", "w25q256", "spi-flash";
};

&gem0 {
    phy-handle = <&ethernet_phy>;
    ethernet_phy: ethernet-phy@1 {
        reg = <1>;
        device_type = "ethernet-phy";
    };
};

&amba_pl {
    hdmi_encoder_0:hdmi_encoder {
        compatible = "digilent,drm-encoder";
        digilent,edid-i2c = <&i2c0>;
    };

    xilinx_drm {
        compatible = "xlnx,drm";
        xlnx,vtc = <&v_tc_0>;
        xlnx,connector-type = "HDMIA";
        xlnx,encoder-slave = <&hdmi_encoder_0>;
        clocks = <&axi_dynclk_0>;
        dglnt,edid-i2c = <&i2c0>;
        planes {
            xlnx,pixel-format = "rgb888";
            plane0 {
                dmas = <&axi_vdma_0 0>;
                dma-names = "dma";
            };
        };
    };
};

&axi_dynclk_0 {
    compatible = "digilent,axi-dynclk";
    #clock-cells = <0>;
    clocks = <&clkc 15>;
};

&v_tc_0 {
    compatible = "xlnx,v-tc-5.01.a";
};

6.驱动程序

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/fs.h>  
#include <linux/init.h>  
#include <linux/ide.h>  
#include <linux/types.h>  
#include <linux/errno.h>
#include <linux/cdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <asm/uaccess.h>
#include <asm/mach/map.h>
#include <asm/io.h>
  
/* 设备节点名称 */  
#define DEVICE_NAME       "timer_led"
/* 设备号个数 */  
#define DEVID_COUNT       1
/* 驱动个数 */  
#define DRIVE_COUNT       1
/* 主设备号 */
#define MAJOR_U
/* 次设备号 */
#define MINOR_U           0

  
/* 把驱动代码中会用到的数据打包进设备结构体 */
struct alinx_char_dev{
    dev_t              devid;             //设备号
    struct cdev        cdev;              //字符设备
    struct class       *class;            //类
    struct device      *device;           //设备
    struct device_node *nd;               //设备树的设备节点
    int                alinx_led_gpio;    //gpio号
    char               led_status;        //gpio状态
    unsigned int       time_count;        //定时器时间
    struct timer_list  timer;             //定时器
};
/* 声明设备结构体 */
static struct alinx_char_dev alinx_char = {
    .cdev = {
        .owner = THIS_MODULE,
    },
};

void timer_function(unsigned long data)
{    
    /* 反转led状态 */
    alinx_char.led_status = !alinx_char.led_status;
    /* 设置led */
    gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status);
    /* 重新开始计时 */
    mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count));
}

/* open函数实现, 对应到Linux系统调用函数的open函数 */  
static int timer_led_open(struct inode *inode_p, struct file *file_p)  
{  
    printk("gpio_test module open\n");  
    return 0;  
}  
  
  
/* write函数实现, 对应到Linux系统调用函数的write函数 */  
static ssize_t timer_led_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p)  
{  
    int retvalue;
    /* 获取用户数据 */
    retvalue = copy_from_user(&alinx_char.time_count, buf, len); 
    /* 设置好timer后先点亮led */
    alinx_char.led_status = 1;
    gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status);
    /* 开启timer */
    mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count));
    
    return 0;  
}  
  
/* release函数实现, 对应到Linux系统调用函数的close函数 */  
static int timer_led_release(struct inode *inode_p, struct file *file_p)  
{  
    printk("gpio_test module release\n");  
    /* 删除定时器 */
    del_timer_sync(&alinx_char.timer);
    return 0;  
}  
      
/* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */  
static struct file_operations ax_char_fops = {  
    .owner   = THIS_MODULE,  
    .open    = timer_led_open,  
    .write   = timer_led_write,     
    .release = timer_led_release,   
};  
  
/* 模块加载时会调用的函数 */  
static int __init timer_led_init(void)  
{
    /* 用于接受返回值 */
    u32 ret = 0;
    
    /* 获取led设备节点 */
    alinx_char.nd = of_find_node_by_path("/alinxled");
    if(alinx_char.nd == NULL)
    {
        printk("alinx_char node not find\r\n");
        return -EINVAL;
    }
    else
    {
        printk("alinx_char node find\r\n");
    }
    
    /* 获取节点中gpio标号 */
    alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0);
    if(alinx_char.alinx_led_gpio < 0)
    {
        printk("can not get alinxled-gpios");
        return -EINVAL;
    }
    printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio);
    
    /* 申请gpio标号对应的引脚 */
    ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled");
    if(ret != 0)
    {
        printk("can not request gpio\r\n");
    }
    
    /* 把这个io设置为输出 */
    ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1);
    if(ret < 0)
    {
        printk("can not set gpio\r\n");
    }
    
    /* 注册设备号 */
    alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME);
    
    /* 初始化字符设备结构体 */
    cdev_init(&alinx_char.cdev, &ax_char_fops);
    
    /* 注册字符设备 */
    cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT);
    
    /* 创建类 */
    alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME);
    if(IS_ERR(alinx_char.class)) 
    {
        return PTR_ERR(alinx_char.class);
    }
    
    /* 创建设备节点 */
    alinx_char.device = device_create(alinx_char.class, NULL, 
                                      alinx_char.devid, NULL, 
                                      DEVICE_NAME);
    if (IS_ERR(alinx_char.device)) 
    {
        return PTR_ERR(alinx_char.device);
    }

    /* 设置定时器回掉函数  */
    alinx_char.timer.function = timer_function;    
    /* 初始化定时器 */
    init_timer(&alinx_char.timer);
    return 0;  
}

/* 卸载模块 */  
static void __exit timer_led_exit(void)  
{  
    /* 释放gpio */
    gpio_free(alinx_char.alinx_led_gpio);

    /* 注销字符设备 */
    cdev_del(&alinx_char.cdev);
    
    /* 注销设备号 */
    unregister_chrdev_region(alinx_char.devid, DEVID_COUNT);
    
    /* 删除设备节点 */
    device_destroy(alinx_char.class, alinx_char.devid);
    
    /* 删除类 */
    class_destroy(alinx_char.class);
       
    printk("timer_led_dev_exit_ok\n");  
}  
  
/* 标记加载、卸载函数 */  
module_init(timer_led_init);  
module_exit(timer_led_exit);  
  
/* 驱动描述信息 */  
MODULE_AUTHOR("Alinx");  
MODULE_ALIAS("gpio_led");  
MODULE_DESCRIPTION("TIMER LED driver");  
MODULE_VERSION("v1.0");  
MODULE_LICENSE("GPL");  

7.应用程序

/** ===================================================== **
 *Author : ALINX Electronic Technology (Shanghai) Co., Ltd.
 *Website: http://www.alinx.com
 *Address: Room 202, building 18, 
           No.518 xinbrick Road, 
           Songjiang District, Shanghai
 *Created: 2020-3-2 
 *Version: 1.0
 ** ===================================================== **/

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include "linux/ioctl.h"

int main(int argc, char *argv[])
{
    int fd, ret;
    char *filename;
    unsigned int interval_new, interval_old = 0;

    /* 验证输入参数个数 */
    if(argc != 2)
    {
        printf("Error Usage!\r\n");
        return -1;
    }

    /* 打开输入的设备文件, 获取文件句柄 */
    filename = argv[1];
    fd = open(filename, O_RDWR);
    if(fd < 0)
    {
        /* 打开文件失败 */
        printf("can not open file %s\r\n", filename);
        return -1;
    }

    while(1)
    {
        /* 等待输入led闪烁的时间间隔 */
        printf("Input interval:");
        scanf("%d", &interval_new);

        /* 时间间隔更新了 */
        if(interval_new != interval_old)
        {
            interval_old = interval_new;
            /* 写入新的时间间隔 */
            ret = write(fd, &interval_new, sizeof(interval_new));
            if(ret < 0)
            {
                printf("write failed\r\n");
            }
            else
            {
                printf("interval refreshed!\r\n");
            }
        }
        else
        {
            printf("same interval!");
        }
    }
    close(fd);
}

8.实验

insmod ax-timer-dev.ko
./ax-timer-test /dev/timer_led

公式T=1/f=20ms+time2
当输入40ms
t=20ms +40ms
2=100ms
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当输入为80时
在这里插入图片描述
T=802+20=180ms
在这里插入图片描述
当输入为10时
T=20ms+10
2=40ms
在这里插入图片描述
在这里插入图片描述
9.修改设备树,修改内核中的定时器
在petalinux工程中打开终端输入命令:

2.修改设备树
修改这四个地方
在这里插入图片描述

/include/ "system-conf.dtsi"
/ {
    model = "Zynq ALINX Development Board";
    compatible = "alinx,zynq", "xlnx,zynq-7000";

    aliases {
        ethernet0 = "&gem0";
        serial0 = "&uart1";
    };

    usb_phy0: usb_phy@0 {
        compatible = "ulpi-phy";
        #phy-cells = <0>;
        reg = <0xe0002000 0x1000>;
        view-port = <0x0170>;
        drv-vbus;
    };
    
    amba {
        slcr@f8000000 {
             pinctrl_led_default: led-default {  
                mux {  
                    groups = "gpio0_13_grp";  
                    function = "gpio0";  
                };  

                conf {  
                    pins = "MIO13"; 
                    io-standard = <3>; 
                    bias-disable;  
                    slew-rate = <0>;  
                };      
            }; 
            pinctrl_key_default: key-default {
                mux {
                    groups = "gpio0_50_grp";
                    function = "gpio0";
                };

                conf {
                    pins = "MIO50";
                    io-standard = <1>;
                    bias-high-impedance;
                    slew-rate = <0>;
                };
            };
        };
    };

    alinxled {
        compatible = "alinx-led";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_led_default>;
        alinxled-gpios = <&gpio0 13 0>;
    };

    alinxkey {
        compatible = "alinx-key";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_key_default>;
        alinxkey-gpios = <&gpio0 50 0>;
    };
};

&i2c0 {
    clock-frequency = <100000>;
};

&usb0 {
    dr_mode = "host";
    usb-phy = <&usb_phy0>;
};

&sdhci0 {
    u-boot,dm-pre-reloc;
};

&uart1 {
    u-boot,dm-pre-reloc;
};

&flash0 {
    compatible = "micron,m25p80", "w25q256", "spi-flash";
};

&gem0 {
    phy-handle = <&ethernet_phy>;
    ethernet_phy: ethernet-phy@1 {
        reg = <1>;
        device_type = "ethernet-phy";
    };
};

&amba_pl {
    hdmi_encoder_0:hdmi_encoder {
        compatible = "digilent,drm-encoder";
        digilent,edid-i2c = <&i2c0>;
    };

    xilinx_drm {
        compatible = "xlnx,drm";
        xlnx,vtc = <&v_tc_0>;
        xlnx,connector-type = "HDMIA";
        xlnx,encoder-slave = <&hdmi_encoder_0>;
        clocks = <&axi_dynclk_0>;
        dglnt,edid-i2c = <&i2c0>;
        planes {
            xlnx,pixel-format = "rgb888";
            plane0 {
                dmas = <&axi_vdma_0 0>;
                dma-names = "dma";
            };
        };
    };
};

&axi_dynclk_0 {
    compatible = "digilent,axi-dynclk";
    #clock-cells = <0>;
    clocks = <&clkc 15>;
};

&v_tc_0 {
    compatible = "xlnx,v-tc-5.01.a";
};

3.驱动程序

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/fs.h>  
#include <linux/init.h>  
#include <linux/ide.h>  
#include <linux/types.h>  
#include <linux/errno.h>
#include <linux/cdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <asm/uaccess.h>
#include <asm/mach/map.h>
#include <asm/io.h>
  
/* 设备节点名称 */  
#define DEVICE_NAME       "timer_led"
/* 设备号个数 */  
#define DEVID_COUNT       1
/* 驱动个数 */  
#define DRIVE_COUNT       1
/* 主设备号 */
#define MAJOR_U
/* 次设备号 */
#define MINOR_U           0

  
/* 把驱动代码中会用到的数据打包进设备结构体 */
struct alinx_char_dev{
    dev_t              devid;             //设备号
    struct cdev        cdev;              //字符设备
    struct class       *class;            //类
    struct device      *device;           //设备
    struct device_node *nd;               //设备树的设备节点
    int                alinx_led_gpio;    //gpio号
    char               led_status;        //gpio状态
    unsigned int       time_count;        //定时器时间
    struct timer_list  timer;             //定时器
};
/* 声明设备结构体 */
static struct alinx_char_dev alinx_char = {
    .cdev = {
        .owner = THIS_MODULE,
    },
};

void timer_function(unsigned long data)
{    
    /* 反转led状态 */
    alinx_char.led_status = !alinx_char.led_status;
    /* 设置led */
    gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status);
    /* 重新开始计时 */
    mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count));
}

/* open函数实现, 对应到Linux系统调用函数的open函数 */  
static int timer_led_open(struct inode *inode_p, struct file *file_p)  
{  
    printk("gpio_test module open\n");  
    return 0;  
}  
  
  
/* write函数实现, 对应到Linux系统调用函数的write函数 */  
static ssize_t timer_led_write(struct file *file_p, const char __user *buf, size_t len, loff_t *loff_t_p)  
{  
    int retvalue;
    /* 获取用户数据 */
    retvalue = copy_from_user(&alinx_char.time_count, buf, len); 
    /* 设置好timer后先点亮led */
    alinx_char.led_status = 1;
    gpio_set_value(alinx_char.alinx_led_gpio, alinx_char.led_status);
    /* 开启timer */
    mod_timer(&alinx_char.timer, jiffies + msecs_to_jiffies(alinx_char.time_count));
    
    return 0;  
}  
  
/* release函数实现, 对应到Linux系统调用函数的close函数 */  
static int timer_led_release(struct inode *inode_p, struct file *file_p)  
{  
    printk("gpio_test module release\n");  
    /* 删除定时器 */
    del_timer_sync(&alinx_char.timer);
    return 0;  
}  
      
/* file_operations结构体声明, 是上面open、write实现函数与系统调用函数对应的关键 */  
static struct file_operations ax_char_fops = {  
    .owner   = THIS_MODULE,  
    .open    = timer_led_open,  
    .write   = timer_led_write,     
    .release = timer_led_release,   
};  
  
/* 模块加载时会调用的函数 */  
static int __init timer_led_init(void)  
{
    /* 用于接受返回值 */
    u32 ret = 0;
    
    /* 获取led设备节点 */
    alinx_char.nd = of_find_node_by_path("/alinxled");
    if(alinx_char.nd == NULL)
    {
        printk("alinx_char node not find\r\n");
        return -EINVAL;
    }
    else
    {
        printk("alinx_char node find\r\n");
    }
    
    /* 获取节点中gpio标号 */
    alinx_char.alinx_led_gpio = of_get_named_gpio(alinx_char.nd, "alinxled-gpios", 0);
    if(alinx_char.alinx_led_gpio < 0)
    {
        printk("can not get alinxled-gpios");
        return -EINVAL;
    }
    printk("alinxled-gpio num = %d\r\n", alinx_char.alinx_led_gpio);
    
    /* 申请gpio标号对应的引脚 */
    ret = gpio_request(alinx_char.alinx_led_gpio, "alinxled");
    if(ret != 0)
    {
        printk("can not request gpio\r\n");
    }
    
    /* 把这个io设置为输出 */
    ret = gpio_direction_output(alinx_char.alinx_led_gpio, 1);
    if(ret < 0)
    {
        printk("can not set gpio\r\n");
    }
    
    /* 注册设备号 */
    alloc_chrdev_region(&alinx_char.devid, MINOR_U, DEVID_COUNT, DEVICE_NAME);
    
    /* 初始化字符设备结构体 */
    cdev_init(&alinx_char.cdev, &ax_char_fops);
    
    /* 注册字符设备 */
    cdev_add(&alinx_char.cdev, alinx_char.devid, DRIVE_COUNT);
    
    /* 创建类 */
    alinx_char.class = class_create(THIS_MODULE, DEVICE_NAME);
    if(IS_ERR(alinx_char.class)) 
    {
        return PTR_ERR(alinx_char.class);
    }
    
    /* 创建设备节点 */
    alinx_char.device = device_create(alinx_char.class, NULL, 
                                      alinx_char.devid, NULL, 
                                      DEVICE_NAME);
    if (IS_ERR(alinx_char.device)) 
    {
        return PTR_ERR(alinx_char.device);
    }

    /* 设置定时器回掉函数  */
    alinx_char.timer.function = timer_function;    
    /* 初始化定时器 */
    init_timer(&alinx_char.timer);
    return 0;  
}

/* 卸载模块 */  
static void __exit timer_led_exit(void)  
{  
    /* 释放gpio */
    gpio_free(alinx_char.alinx_led_gpio);

    /* 注销字符设备 */
    cdev_del(&alinx_char.cdev);
    
    /* 注销设备号 */
    unregister_chrdev_region(alinx_char.devid, DEVID_COUNT);
    
    /* 删除设备节点 */
    device_destroy(alinx_char.class, alinx_char.devid);
    
    /* 删除类 */
    class_destroy(alinx_char.class);
       
    printk("timer_led_dev_exit_ok\n");  
}  
  
/* 标记加载、卸载函数 */  
module_init(timer_led_init);  
module_exit(timer_led_exit);  
  
/* 驱动描述信息 */  
MODULE_AUTHOR("Alinx");  
MODULE_ALIAS("gpio_led");  
MODULE_DESCRIPTION("TIMER LED driver");  
MODULE_VERSION("v1.0");  
MODULE_LICENSE("GPL");  

4.应用程序

/** ===================================================== **
 *Author : ALINX Electronic Technology (Shanghai) Co., Ltd.
 *Website: http://www.alinx.com
 *Address: Room 202, building 18, 
           No.518 xinbrick Road, 
           Songjiang District, Shanghai
 *Created: 2020-3-2 
 *Version: 1.0
 ** ===================================================== **/

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include "linux/ioctl.h"

int main(int argc, char *argv[])
{
    int fd, ret;
    char *filename;
    unsigned int interval_new, interval_old = 0;

    /* 验证输入参数个数 */
    if(argc != 2)
    {
        printf("Error Usage!\r\n");
        return -1;
    }

    /* 打开输入的设备文件, 获取文件句柄 */
    filename = argv[1];
    fd = open(filename, O_RDWR);
    if(fd < 0)
    {
        /* 打开文件失败 */
        printf("can not open file %s\r\n", filename);
        return -1;
    }

    while(1)
    {
        /* 等待输入led闪烁的时间间隔 */
        printf("Input interval:");
        scanf("%d", &interval_new);

        /* 时间间隔更新了 */
        if(interval_new != interval_old)
        {
            interval_old = interval_new;
            /* 写入新的时间间隔 */
            ret = write(fd, &interval_new, sizeof(interval_new));
            if(ret < 0)
            {
                printf("write failed\r\n");
            }
            else
            {
                printf("interval refreshed!\r\n");
            }
        }
        else
        {
            printf("same interval!");
        }
    }
    close(fd);
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值