Microwindows 及其 触摸屏驱动 在eCos MINI2440 上的实现

开源GUI-Microwindows简介 作者:EasyWave 时间:2014.06.07 类别:开源GUI系统-Microwindows简介 声明:转载,请保留链接 一:Microwindows简介 Microwindows 是一个著名的开放式源码嵌入式GUI 软件,目的是把图形视窗环境引入到运行Linux 的小型设备和平台上。作为X Window 的替代品,Microwindows可以使用更少的RAM 和文件存储空间(100K-600K)提供与X Window 相似 阅读详情

1. 修复MINI2440 QEMU的BUG

开始的我用ecos里面仅有的两个ARM下面的touch 驱动来做一个中断测试,

都快疯了,没有任何反应。

后来看到RT-Thread的例子可以正常运行,于是才想看看他们呢对MINI2440 QEMU的修改。

 

真的要感谢所有自由组织的无私奉献。

 

果然,MINI2440的QEMU采用的是S3C2410的TOUCH接口,里面关于PenDown和PenUP的寄存器位都木有。

 

代码已经上传到了emboslab git 库中qemu-mini2440的ecos-emboslab 分支,这里还是简要介绍一下。

 

--------------------------------- hw/s3c2410.c ---------------------------------

index d1e4c92..bdf8a73 100644

@@ -1630,6 +1630,14 @@ static void s3c_adc_tick(void *opaque)

         qemu_mod_timer(s->tst, qemu_get_clock(vm_clock) +

                         (ticks_per_sec >> 5));

     }

/*

这个是QEMU实现ARM中断方式的机制

可以这样理解:如果对QEMU的窗口做Penup的时候,触发一个专断给CPU。

*/

+    else

+    {

+        if (((s->ts & 3) == 3) && (s->ts & (1<<8)) && (s->enable))

+            qemu_irq_raise(s->tcirq);

+

+ qemu_mod_timer(s->tst, qemu_get_clock(vm_clock) +

+                        (ticks_per_sec >> 5));

+    }

 }

 

 static void s3c_adc_event(void *opaque,

@@ -1689,7 +1697,7 @@ static void s3c_adc_write(void *opaque, target_phys_addr_t addr,

         break ;

 

     case S3C_ADCTSC:

-        s->ts = value & 0xff;

+        s->ts = value & 0x1ff; /*增加了Pendown和Penup的控制位*/

         break ;

 

     case S3C_ADCDLY:

 

2. 实现触摸屏驱动(尚有BUG)

目前官方的触屏驱动有两个,我们看下

 

ricky@ricky-laptop:ecos-emboslab$ cd packages/devs/touch/arm/
ricky@ricky-laptop:arm$ ls
aaed2000  ipaq

 

如果让Microwindows支持Touch只要实现这样的一个标准的Touch驱动就可以了。

在Microwindows的部分调用这个标准的ecos字符形设备就可以了。

不过从代码看来,ecos并没有对Touch驱动有严格的API定义,所以在网上你能看到很多种实现方法。

 

既然Microwindows用了字符形的设备,那么我们也就按照这个架构实现一下吧。

我们先看一下ecos的字符形设备是什么样子的,具体的请看ecos的参考手册(如何生成最新的参考手册,我会在另一篇博客中讲述)

 

CHAR_DEVIO_TABLE(mini2440_ts_handlers,
                 NULL,                                   // Unsupported write() function
                 ts_read,
                 ts_select,
                 ts_get_config,
                 ts_set_config);

CHAR_DEVTAB_ENTRY(mini2440_ts_device,
                  CYGDAT_DEVS_TOUCH_MINI2440_NAME, /*这个是字符形设备的描述符 , 在CDL文件中定义 "/dev/ts" ,和Linux的驱动文件很相似 */
                  NULL,                                   // Base device name
                  &mini2440_ts_handlers,
                  ts_init,
                  ts_lookup,  /*重点看这个函数:当设备被open的时候这个callback函数会被调用*/
                  NULL);                                  // Private data pointer

关于如何实现更好的touch架构,本人还在研究。

现在的方案是

在设备初始化的时候配置硬件资源和终端设置,

在设备被打开,也就是ts_lookup里面创建中断响应函数,把转化好的touch 数据放到队列中等待上层(Microwindows)

来读取。

 

看下初始化部分

 

static bool      
ts_init(struct cyg_devtab_entry *tab)
{
    cyg_uint32 _dummy;
    HAL_WRITE_UINT32(ADCCON,S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(9));
    HAL_WRITE_UINT32(ADCDLY,50000);
    HAL_WRITE_UINT32(ADCTSC,WAIT4INT(0));  /*这里就是使能,PenDownUP终端*/

    //HAL_WRITE_UINT32(INTMSK, BIT_ALLMSK);
    HAL_READ_UINT32(SUBSRCPND, _dummy);
    _dummy |= BIT_SUB_TC;
    _dummy |= BIT_SUB_ADC;
    HAL_WRITE_UINT32(SUBSRCPND, _dummy);

   
    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_ADC);
    cyg_selinit(&ts_select_info);
    /* install interrupt handler */
    HAL_READ_UINT32(INTSUBMSK, _dummy);
    _dummy &= ~BIT_SUB_ADC;
    _dummy &= ~BIT_SUB_TC;
    HAL_WRITE_UINT32(INTSUBMSK, _dummy);
    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ADC);
    return true ;
}

 

/*设备打开函数,创建了AD C中断的挂钩函数cyg_mini2440_ts_isr和cyg_mini2440_ts_dsr*/

    if (!_is_open) {
        _is_open = true;
       
       cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_ADC,
                             0,
                             (CYG_ADDRWORD)0,
                             cyg_mini2440_ts_isr,
                             cyg_mini2440_ts_dsr,
                             &ts_thread_handle,
                             &ts_thread_data);
       cyg_drv_interrupt_attach(ts_thread_handle);
       cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_ADC);
    }
    return ENOERR;
}

 

罗嗦两句,ecos在创建的时候就参考了很多linux的风格,比如我们看到上面的isr和dsr很像Linux对中断处理的上半和下半。

具体的实现机理本人也在研究呢,目前位置我只是知道如何应用。

 

isr中希望用户能快速的响应终端,在isr结束的时候往往有下面的代码

   cyg_drv_interrupt_acknowledge (CYGNUM_HAL_INTERRUPT_ADC);

上面的这行主要是在函数返回前开启这个中断

   return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR ;

后面这个有两个含义,第一个是告诉系统这个中断我已经知道了,做了我应该做的事情。第二个含义就是红色的部分会在函数返回之后

出发这个终端的DSR处理程序。

 

那么这个touch驱动到底需要还是不需要DSR呢,本人下不了结论。

本人是做Linux的,知道Linux一般的input driver一般用到后半的多是处理report机制,

为了不把问题复杂化,我们现让硬件能动起来,欢迎其他人给我建议

 

2440的Touch中断处理暂时比较简单

if (res& (1 << 10)) /*ADC的采用的后要继续出发PenDownUP中断*/
   {
       //diag_printf("ADC Interrupt/n");
       HAL_READ_UINT32(SUBSRCPND, reg);
       reg |= BIT_SUB_ADC;
       HAL_WRITE_UINT32(SUBSRCPND, reg);
     
       x = read_ts_x();
       y = read_ts_y();
      
       lastX = x;  lastY = y;
      
       //diag_printf("X = %x, Y = %x/n", x, y);
       HAL_WRITE_UINT32(ADCTSC,WAIT4INT(1));

   }
   if (res& (1 << 9)){ /*PenDownUp中断记录Touch的按下和抬起,同时出发ADC的采样*/
       //diag_printf("TS Interrupt/n");
      
       HAL_READ_UINT32(SUBSRCPND, reg);
       reg |= BIT_SUB_TC;
       HAL_WRITE_UINT32(SUBSRCPND, reg);

       HAL_READ_UINT32(ADCDAT0, data0);
       HAL_READ_UINT32(ADCDAT1, data1);
      
    
       updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
      
       if(updown)
       {           
           x = read_ts_x();
            y = read_ts_y();
            //diag_printf("X = %x, Y = %x/n", x, y);
        //diag_printf("pen_down#######################################################################/n");
            if ((x < X_THRESHOLD) || (y < Y_THRESHOLD)) {
                // Ignore 'bad' samples
                 }
            lastX = x;  lastY = y;
            HAL_WRITE_UINT32(ADCTSC, S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST);
        HAL_READ_UINT32(ADCCON, reg);
            reg |= S3C2410_ADCCON_ENABLE_START;
            HAL_WRITE_UINT32(ADCCON, reg);
            pen_down = true;
       }
       else
       {
               x = lastX;
            y = lastY;
            HAL_WRITE_UINT32(ADCTSC,WAIT4INT(0));
            pen_down = false;
        //diag_printf("pen_up#######################################################################/n");
       }
   }


   /*把合理的数据处理后放入一个events数组中,等待上层来读取*/         
   if (num_events < MAX_EVENTS) {
            num_events++;
            ev = &_events[_event_put++];
            if (_event_put == MAX_EVENTS) {
                _event_put = 0;
            }
            ev->button_state = pen_down ? 0x04 : 0x00;
            ev->xPos = x;
            ev->yPos = y;
            if (ts_select_active) {
                ts_select_active = false;
                cyg_selwakeup(&ts_select_info);
            }
        }

3. 修正eCos自带Microwindows的ecos_app错误

目前发现的一个问题是,ecos之前曾经采纳了一个牛的patch,他应用HAL_TABLE实现了基于Microwindows的APP定义方式。

很巧妙,那么什么是HAL_TABLE呢,我们可以理解为为了实现更好的表的管理的一种机制,可以把我们要存放的表通过宏

放到内存中的某个位置,大家可以在google上找一下,ecos在这个部分应用还是比较有特点的。

尤其是在二维表的处理上有很多特别的应用,redboot的一些命令就是例子

 

ecos_mw_app.h

typedef void fun(CYG_ADDRWORD);
typedef struct _mw_app_entry {
    char         *name;
    fun          *entry;
    int          prio;
    fun          *init;
    cyg_handle_t t;
    cyg_thread   t_obj;
    char         stack[STACKSIZE];
} CYG_HAL_TABLE_TYPE _mw_app_entry_t;

#define _mw_app(_name_,_id_,_pri_,_init_)               /
externC void _id_##_thread(CYG_ADDRWORD data);          /
_mw_app_entry_t _mw_app_##_pri_##_##_id_           /
   CYG_HAL_TABLE_QUALIFIED_ENTRY(_mw_apps,_pri_) =      /
     { _name_, _id_##_thread, _pri_, _init_};

#define ECOS_MW_STARTUP_PRIORITY 11
#define ECOS_MW_NANOX_PRIORITY   (ECOS_MW_STARTUP_PRIORITY+1)
#define ECOS_MW_KND_PRIORITY     (ECOS_MW_STARTUP_PRIORITY+2)
#define ECOS_MW_NANOWM_PRIORITY  (ECOS_MW_STARTUP_PRIORITY+4)
#define ECOS_MW_APP_PRIORITY     (ECOS_MW_STARTUP_PRIORITY+5)

 

ecos_app.c

 

CYG_HAL_TABLE_BEGIN( __MW_APP_TAB__, _mw_apps );
CYG_HAL_TABLE_END( __MW_APP_TAB_END__, _mw_apps );
extern struct _mw_app_entry __MW_APP_TAB__[], __MW_APP_TAB_END__;

 

为什么提到这个呢,到目前位置我不能十分的确定是这个机制有问题还是QEMU本身对于内存管理的问题。

如果我在Microwindows访问我的设备文件,就是open我们之前创建的/dev/ts这个时候貌似用HAL_TABLE存放的UI线程信息就读不到了。

如果可以打message,可以看到不能创建我们要的Microwindows的一些线程,当然也就不能看到画面了。

 

比较简单的做法就是参考ecos之前的代码,或者干脆去看官方Microwindows的代码,用一个数组去存放线程信息。

 

struct nx_thread _threads[] = {
    { "System startup", startup_thread,    11 },
    { "Nano-X server",  nanox_thread,      12 },
    { "Nano-WM",        nanowm_thread,     14 },
    /*{ "Nano-KBD",       nxkbd_thread,      13 },*/
#ifdef USE_NXSCRIBBLE
    { "Scribble",       nxscribble_thread, 20 },
#endif
#ifdef USE_LANDMINE
    { "Landmine",       landmine_thread,   19 },
#endif
#ifdef USE_NTETRIS
    { "Nano-Tetris",    ntetris_thread,    18 },

# endif
#ifdef USE_WORLD
    { "World Map",      world_thread,      21 },
#endif
    { "demo",            demo_thread,      22 },
};

 

接下来你就看到Microwindows了,进入下一个环节。

4. Show 图咯

Microwindows 0.91版本:嵌入式GUI系统详解 Microwindows是一个开源的、微内核的图形用户界面(GUI)系统,它提供了一种轻量级的方式,为嵌入式系统和小型设备提供窗口化操作界面。0.91版本是该系列中的一个里程碑,它在功能和性能上都有显著提升,为开发者提供了更为丰富的工具集和优化选项。 阅读详情

相关推荐

Micro_Window_Toolkit(MWT)

这个资源里面不仅有所有的Demo例子还有14个简单的易学的例子,希望能给大家带来好的学习资源。MWT是一个用于开发J2ME用户界面(UI)的工具包。它具有友好,强大,快速,开源等特性。因为它的"灵感"来自 AWT,Swing和SWT。可以使用bitmap fonts等来自定义组件。它专门为嵌入式开发而设计和优化。基于LGPL发布。

microwindows位图解析

 第1章 microwinodows图形显示框架1.1 microwindows体系结构Microwindows 采用了分层结构设计方法,其层次结构如下图所示。同时, 这里也列出 Microwindows 源代码目录树下的主要目录结构,以便于对照参考。 microwindows --bin --Configsnano-X /win32 API --demos

bisword的专栏 2301

MicroWindows_system.rar_microwindows

MICROWINDOWS事件,接口等的一些实际应用,对开发者有一定的借鉴作用

Microwindows安装与配置指南

Microwindows,也称为Nano-X Window System,是一个轻量级的图形窗口系统。它为Linux、Mac OS X、Android、EMSCRIPTEN等多种平台提供了Win32和Nano-X(类似X11)API,用于在窗口中执行剪裁图形绘制。它是一个开源项目,遵循Mozilla Public License协议。该项目主要使用C语言编写。 ## 2. 关键技术和框架 - ...

gitblog_00481的博客 1005

Vitis HLS 学习指南与实践教程

Vitis HLS 学习指南与实践教程摘要:本文系统介绍了AMD Vitis HLS工具及其应用。HLS技术将C/C++代码自动转换为硬件描述语言,显著提升FPGA开发效率(5-10倍)。文章对比了HLS与传统RTL设计的优势,包括抽象级别高、开发周期短、代码重用性强等特点。详细讲解了Vitis HLS工具链的核心功能,包括支持的C/C++特性(如任意精度数据类型)、开发流程(项目创建-代码编写-仿真-综合)以及关键优化技术(流水线、循环展开、数组分割等编译指示)。通过具体代码示例展示了HLS设计方法,为F

weixin_44707118的博客 1401

使用Bigemap下载地图流程

Bigemap地图下载简单流程,临时安排任务简单学习没有深入了解。

TKY666的博客 4846

MicroWindows介绍

   MicroWindows Open Source Project成立的宗旨是针对体积小的装置建立一套先进的视窗环境。在Linux桌面上通过交叉编译可以很容易地制作出MicroWindows的程序。MicroWindows能够在没有任何操作系统或其他图形系统的支持下运行,它能对裸显示设备进行直接操作。因此,MicroWindows就显得十分小巧,便于移植到各种硬件和软件系统上。  然而Mi

冷雨 专栏 1394

WRF实战:自定义Vtable解析ECMWF海温数据的关键步骤与技巧

本文详细介绍了在WRF模型中自定义Vtable以解析ECMWF海温数据的关键步骤与技巧。通过解剖GRIB文件、编写自定义Vtable条目以及配置METGRID.TBL,解决了ECMWF数据与WRF模型对接的难题,为海洋气象和台风模拟研究提供了高精度数据输入方案。

weixin_29279101的博客 335

嵌入式系统下的Microwindows实现

前 言 目前,伴随着各种手持、无线及嵌入式设备的迅猛发展,相应的软硬件设计也发生了很大的变化。许多设备都使用了 Intel,MIPS,摩托罗拉的32位微处理器及大屏幕的液晶图形显示器。由于在过去10年中,桌面操作模式取得...

ciyi7513的博客 1283

手把手教你完成YOLOv10 PySide6目标检测界面搭建,使用Qt6设计YOLOv10检测系统,前台系统+后台管理系统开发实战,可用于大论文凑工作量或毕设必备,全网最详细教程

手把手教你完成YOLOv10 PySide6目标检测界面搭建,使用Qt6设计YOLOv10检测系统,前台系统+后台管理系统开发实战,可用于大论文凑工作量或毕设必备,全网最详细教程

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1732

深度强化学习在机器人控制中的应用

非常感谢您提供如此详细的任务要求和约束条件。作为一位世界级的人工智能专家和计算机领域大师,我将全身心投入到这篇技术博客的撰写中。 深度强化学习在机器人控制中的应用 1. 背景介绍 近年来,随着人工智能技术的飞速发展,深度学习和强化学习在各个领域都得到了广泛应用,尤其是在机器人

AI天才研究院 1323

linux轻量级的图形库,基于Microwindows的嵌入式Linux轻量级图形应用库的设计

本文引用地址:http://www.eepw.com.cn/article/201809/388534.htm这里基于Linux2.4.19和Microwindows0.89进行讨论,主要难点:一是将Microwindows层次打乱后如何进行代码的重构,用最少的代码实现最有效的功能,二是提供中文显示和中文输入的支持。2.1 结构重构(1)底层驱动层整个系统的核心是键盘和屏幕数据结构,它们在Linu...

weixin_42522817的博客 443

SKUA-GOCAD入门教程-第六节

DisplayElements窗口是用于浏览和处理项目数据的工具,包含多个数据浏览器,如模型列表、对象、未分类对象、属性数据及资源数据。

江洋大葱的博客 983

用Microwindows(Nano-X)编写“hello world”

用Microwindows(Nano-X)编写“hello world” By: 吴垠 Date: 2008-05-09 Homepage:

吴垠的专栏 1万+

深入浅出AXI协议(2)——通道及信号

本文我们继续AXI协议的学习,我们将讨论5个通道的具体内容和相对应的信号。这一部分的内容现在对于大家来说可能很难理解,但是没有关系,随着学习的深入,我们会逐步讲解这里面的所有现在,现在只需要把它们当作一个可以查阅的手册,快速阅读有一个基本的印象即可。

apple_53311083的博客 1798

5 分钟上手 Kimi Work:安装、配置、跑通第一个任务

这篇文章提供了Kimi Work的快速入门指南,帮助用户在5分钟内完成从安装到运行第一个任务的全过程。主要内容包括: 安装步骤: macOS用户下载.dmg文件并拖入Applications Windows用户下载.exe安装包,需注意中文路径问题 初始设置: 使用现有Kimi账号登录 检查任务配额和文件访问权限 首个任务推荐: 建议从简单的本地文件整理开始(如按类型分类桌面文件) 详细说明了任务执行流程和审批机制 常见问题: 计划生成卡顿的解决方法 文件无变化的排查步骤 进阶建议: 提供难度递增的后续任务

sg_knight的专栏 2775

Microwindows 介绍

Microwindows 介绍(The Nano-X Window System is an Open Source project aimed at bringing the features of modern graphical windowing environments to smaller devices and platforms. Nano-X allows applicati

ShorminHsu的专栏 1214

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Microwindows(Nano-X)移植

Microwindows(Nano-X) Gui移植笔记 (2011-11-07 20:38) 分类: Gui 首先需要下载Microwindows的源文件以及依赖的库. 下载zlib包 http://www.zlib.net/zlib-1.2.3.tar.bz2 下载jpeg包 http://www.fmsoft.cn/uploads/minigui_org_

AMOVLAB(阿木实验室) 2376

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

编译microwindow(nano-X) 及flnx-0.18

来自: http://blog.chinaunix.net/uid-20595394-id-1619435.html http://blog.chinaunix.net/uid-20595394-id-1619427.html 先编译microwindows,然后flnx。 说明:编译freetype库时,在freetype-x.x.xx/builds/unix/libto

jianwushuang的专栏 2198

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

ecos 自带的Microwindows中加入mwin的支持

如何让ecos的Microwindows支持WINAPI和自己内置的一些MWidget呢。 本文粗略的讲述了一下,源码会上传到emboslab

嵌入式虚拟系统实验室 8725

microwindows:轻量级图形窗口系统,实现跨平台GUI设计

microwindows,又称Nano-X Window System,是一款轻量级的图形窗口系统。它实现了Win32和Nano-X(类似X11)API,支持在Linux、Mac OS X、ELKS、EMSCRIPTEN、Android等多种平台上进行剪裁图形绘制。该系统开源,并遵循Mozilla Public License授权。 microwindows为创建GUI提供了多种工具和库,包括N...

gitblog_00674的博客 477

主流嵌入式开源GUI比较

本文主要说明了MicroWindows、MiniG、QT、GTK+、OpenGUI和FLTK,第七小节是对比的详细表格,内容是根据网上的一些资料还有各大开源GUI的官网的资料整理而来,目的是为自己以后学习把握方向。

逐梦的博客 5万+

Linux 下的图形库介绍

在进行Linux下的图形系统编程时,我们常常会遇到以下这些概念: Framebuffer,X11,SDL,DFB,miniGUI,OpenGL,QT,GTK,KDE,GNOME等等。 一、Linux图形领域的基础设施1.1XWindow XWindow从逻辑上分为三层:XServer、XClient和X协议。 最底层的XServer(X服务器)主要处理输...

weixin_34176694的博客 755

Microwindows及其中文化方法

 [转帖]Microwindows及其中文化方法 嵌入式GUI系统是嵌入式系统中实现友好人机界面的关键技术,应用于嵌入式的GUI系统必须具备体积小、反应快、高可靠性、可移植性好以及可裁减等特点,对于实时系统还需要有时实方面的要求。目前,流行的嵌入式GUI系统有Microwindows、MiniGUI、Qt/Embedded等。基中Microwindows以其开放的源

bisword的专栏 1991

Microwindow系列(2)--结构

Microwindow系列(二)--结构          要想做好基于Microwindow的GUI开发,需要对其架构有比较清晰的认识。 Bin—存放make后生成的可执行程序,这些程序是microwindow提供的例程,包含众多用nano-X API和microwindow API的例子,这些例子的源码存放在目录demos下。基于Microwindow API的可执行程序可直接

FreeWind(风的自由)的专栏 959

Microwindow系列(3)--开发

Microwindow系列(三)--开发 好好从例程看起吧,能给你很多提示, microwindow API的没nano-X的多,但已经差不多了,网上也会有搜到一些例子。例程源码在demos/mwin目录下,make后的可执行文件在bin下,中间文件在obj中,编写自己的UI程序时,要注意编译时的诸多选项,可以通过make时的日志记录来了解。其实大多都是config里的配置。同时要包含一些头文

FreeWind(风的自由)的专栏 961
上一篇: ubuntu 10.04 应用eclipse 搭建 RTEMS 应用程序集成开发环境
下一篇: PW graphic library 测试
知秋一叶
博客等级 码龄19年 196粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值