OSSchedLock()函数透析

UCOSII移植STM32笔记 立即下载
uC/OS-II的OSSchedLock()和OSSchedUnlock()函数允许应用程序锁定当前任务不被其它任务抢占。
使用时应当注意的是:当你调用了OSSchedLock()之后,而在调用OSSchedUnlock()之前,
千万不要再调用诸如OSFlagPend()、OSMboxPend()、OSMutexPend()、OSQPend()、OSSemPend()之类的事件等待函数!
而且应当确保OSSchedLock()和OSSchedUnlock()函数成对出现,特别是在有些分支条件语句中,要考虑各种分支情况,不要有遗漏!
 
需要一并提醒用户的是:当您调用开关中断函数OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()时也要确保成对出现,否则系统将可能崩溃!
不过,在OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()函数之间调用OSFlagPend()、OSMboxPend()、OSMutexPend()、OSQPend()、OSSemPend()之类的事件等待函数是允许的。

 

摘

OSSchedLock()

调用OSSchedLock()以后,用户的应用程序不得使用任何能将现行任务挂起的系统调用。

也就是说,用户程序不得调用OSMboxPend()、OSQPend()、OSSemPend()、

OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零为止。

因为调度器上了锁,用户就锁住了系统,任何其它任务都不能运行

下面贴出这个函数的代码 :
#if OS_SCHED_LOCK_EN > 0   //这是个全局变量,在Os_cfg.h中定义
void  OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr;
#endif    
    
    
    if (OSRunning == TRUE) {                     /* 确认是否是多个任务在运行              */
        OS_ENTER_CRITICAL();
        if (OSLockNesting < 255) {               /* OSLockNesting最大值为255     */
            OSLockNesting++;                     /* Increment lock nesting level                       */
        }
        OS_EXIT_CRITICAL();
    }
}
#endif 
从上锁函数我们可以看出,这个函数就是一个确定任务上锁级数的函数,也就是为OSLockNesting这个变量更新取值的函数。
如果我们在任务里面执行一次该函数,则上锁级数就是1。我们也可以知道,上锁函数的深度最大值为255,我们可以通过上锁到255,到逐级解锁来实现不同的应用。
但这个过程,本人从来没有实现过。
并且补充一点,在上锁函数执行后,若任务遇到中断,则中断函数的执行会为OSIntNesting变量加1,所以上锁函数执行后,CPU一直处于当前任务与中断服务函数之间的运行,

直到解锁函数将OSLockNesting和OSIntNesting的值减到0时。方可解除系统锁定。。。。

转:ucos中的三种临界区管理机制(OS_CRITICAL_METHOD的解释)

熟悉ucos,或者读过Jean.J.Labrosse写过的ucos书籍的人,一定会知道ucos中著名的临界去管理宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。

同样是通过关中断来保护临界区,OS_ENTER_CRITICAL/OS_EXIT_CRITICAL一共实现了三种实现方式,如下所示:

 

  1. #if OS_CRITICAL_METHOD == 1  
  2. #define OS_ENTER_CRITICAL() __asm__("cli")  
  3. #define OS_EXIT_CRITICAL() __asm__("sti")  
  4. #endif  
  5.   
  6. #if OS_CRITICAL_METHOD == 2  
  7. #define OS_ENTER_CRITICAL() __asm__("pushf \n\t cli")  
  8. #define OS_EXIT_CRITICAL() __asm__("popf")  
  9. #endif  
  10.   
  11. #if OS_CRITICAL_METHOD == 3  
  12. #define OS_ENTER_CRITICAL() (cpu_sr = OSCPUSaveSR())  
  13. #define OS_EXIT_CRITICAL() (OSCPURestoreSR(cpu_sr))  
  14. #endif  

 

   第一种方式,OS_ENTER_CRITICAL()简单地关中断,OS_EXIT_CRITICAL()简单地开中断。这种方式虽然简单高效,但无法满足嵌套的情况。如果有两层临界区保护,在退出内层临界区时就会开中断,使外层的临界区也失去保护。虽然ucos的内核写的足够好,没有明显嵌套临界区的情况,但谁也无法保证一定没有,无法保证今后没有,无法保证在附加的驱动或什么位置没有,所以基本上第一种方法是没有人用的。

   第二种方式,OS_ENTER_CRITICAL()会在关中断前保存之前的标志寄存器内容到堆栈中,OS_EXIT_CRITICAL()从堆栈中恢复之前保存的状态。这样就允许了临界区嵌套的情况。但现在看来,这种方法还存在很大的问题,甚至会出现致命的漏洞。

      在OS_CRITICAL_METHOD=2的情况下,假设有如下代码:

  1. function_a()  
  2. {  
  3.      int a=(1<<31);  
  4.      OS_ENTER_CRITICAL();  
  5.      function_b(a);  
  6.      OS_EXIT_CRITICAL();  
  7.        
  8. }  

   会出现什么情况?在我的实验中,OS_EXIT_CRITICAL()之后,会出现处理器异常。为什么会出现处理起异常,让我来模拟一下它的汇编代码。之所以是模拟,并非是我虚构数据,而是因为我实际碰到问题的函数复杂一些,理解起来就需要更多的代码。而这个问题是有普遍意义的,所以请允许我来浅显地揭示这个隐藏的bug。

  

  1. function_a:  
  2.      push ebp  
  3.      mov ebp, esp  
  4.      sub esp, 8  
  5.      mov 4(esp), 0x80000000  
  6.      pushfd  
  7.      cli  
  8.      mov edi, 4(esp)  
  9.      mov (esp), edi  
  10.      call function_b  
  11.     popfd  
  12.     mov esp, ebp  
  13.     ret  

    这是参照了gcc编译结果的汇编模拟,无论是否加优化选项这一问题都存在。这个问题的起因很简单,gcc想聪明一点,一次把堆栈降个够,然后它就可以在栈上随意放参数去调用其他函数。尤其是在调用函数较多的时候,这种做法就更有意义。而且,gcc这种聪明与优化选项O好像没有太大关系,好像没有什么能禁止它这么做。但问题是,gcc不知道我们的OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是操作了堆栈的,我尝试过使用__asm__ __volatile__("pushfd \n\tcli":::"memory")来通知gcc内存数据改变了,但显然gcc不认为堆栈也改变了。于是,OS_ENTER_CRITICAL()保存在栈上的状态就被冲掉了,比如被这里调用参数a的值。在恢复时,是否会引发异常,会引发什么异常,这个就要靠运气了。但我相信一个人的运气不会总是那么好的,所以最后别使用OS_CRITICAL_METHOD=2。

 

 

    第三种,在关中断前,使用局部变量保存中断状态。这也是几乎所有实时操作系统共有的选择。但ucos是一朵奇葩,为了兼容前两种方式,OS_ENTER_CRITICAL()/ OS_EXIT_CRITICAL()宏定义并没有提供传递状态参数的功能。所以它的临界去必须这么用:

  1. function_a()  
  2. {  
  3. #if OS_CRITICAL_METHOD == 3  
  4.     int cpu_sr;  
  5. #endif  
  6.       int a = 1<<31;  
  7.       OS_ENTER_CRITICAL();  
  8.       function_b(a);  
  9.       OS_EXIT_CRITICAL();  
  10. }  

这种代码怎么看怎么别扭,可能是因为在函数体内加了宏定义吧。然后,第三种方法对同一个函数体内的嵌套临界区无法支持,这在一些很长大的函数中使用时或许会造成一定困扰。

 

    好吧,如果有了问题,就要有解决方案,毕竟我不是为了让大家对ucos失去信心的。我们可以参考下一般的实时操作系统是如何实现关中断临界区的,就是以显式的方式用局部变量保存中断状态。

  1. int int_lock()  
  2. {  
  3.    int cpu_sr;  
  4.     __asm__ __volatile__("pushfd \n\t pop %0\n\t cli":"=r"(cpu_sr));  
  5.     return cpu_sr;  
  6. }  
  7.   
  8. void int_unlock(int cpu_sr)  
  9. {  
  10.      __asm__ __volatile__("push %0\n\t popfd"::"r"(cpu_sr));  
  11. }  
  12.   
  13. function_a()  
  14. {  
  15.    int a, cpu_sr;  
  16.    a=1<<31;  
  17.    cpu_sr = int_lock();  
  18.    function_b(a);  
  19.    int_unlock(cpu_sr);  
  20. }  


   int_lock()和int_unlock()的可以用汇编更高效地实现,也可以选择只恢复中断标志的状态。这种方法让我们显示地管理状态保存的情况,我觉得至少要比宏定义清楚多了

三极管吸潮失效分析案例 案例背景三极管也称为晶体三极管,它被视为电子电路中最重要的器件之一。三极管顾名思义具有三个电极,它最主要的功能是电流放大和开关作用。本次失效案例中的三极管在仓库存放一段时间后,在PCBA测试过程中集中发生不良。分析过程1.外观检测对失效样品进行外观检测,未发现明显破损、裂纹等不良。2.X-ray检测对失效样品进行X-ray检测,金线、绑定点未发现异常。3.开封检测对失效样品进行开封检测,发现存在键合点脱落的现象,键合点附近的晶圆破损。4.SEM检测对失效样品进行SEM检测,发现晶圆键合点位置有裂纹和破损,金 阅读详情

相关推荐

Dify如何实现自主学习

摘要:Dify通过构建感知-决策-执行-反馈的闭环实现"自主学习",本质是打造能自动获取信息、更新知识库并调整策略的Agent工作流。核心包括:1)建立知识库作为记忆体;2)搭建感知与执行工具获取实时信息;3)通过工作流编排决策"大脑",包含LLM决策节点、行动执行节点和反馈反思节点。典型应用如根据用户反馈优化回答风格,通过存储反思日志到知识库实现持续优化。这种机制使智能体能基于新数据和经验不断自我改进。

专注于技术研发行业技术主要有AI人工智能视觉识别、物联网技术、电商平台、app原生技术、微信小程序、鸿蒙语言开发、办公企业oa、ERP等,致力于做东半球最优秀的程序员 726

UCOSII源码分析七——调度器上锁解锁

调度器上锁解锁 调度器上锁解锁函数OSSchedLock (void),OSSchedUnlock (void)用于禁止任务调度,让cpu执行当前任务保持cpu 的控制权,解锁后可以进行调度。 实现原理很简单,对全局变量锁定嵌套计数器OSLockNesting进行操作,OSLockNesting记录了上锁函数OSSchedLock (void)的调用次数,OSSchedLock (void)中对变量进行加一操作,OSSchedUnlock (void)对变量进行减一操作,在引起任务调度的函数中进行判断,若变

qq_15555275的博客 1195

ABtest描述统计功效

我们在面试数据分析时,常常会问到如何确定样本量的问题,会有一个指标:统计功效(power),或者是1-β 统计功效会影响实验的可信度,甚至会影响实验所需的样本量,要了解统计功效,首先要理解两类统计错误 假如我们做了一个AB实验,且两组用户的数据均值为μ1和μ2,我们会有两个初始假设: H0:两个实验组的数据没有差别(μ1=μ2),这个假设也叫“零假设”,也叫原假设 H1:两个实验组之间的数据存在差别(μ1≠μ2),这个假设也叫“非零假设”,也叫备择假设 定义两类错误: 实验本身没有效应,但我们觉

qq_38134556的博客 903

OSSchedLock()--上锁函数

作用:调度上锁函数 描述:阻止再次调度发生,它让你准备执行任务切换的时候才进行任务切换 参数:无 因为任务调度时一般都是通过OSTIMEDLY()来实现。在这个函数中会对当前的任务执行挂起。同时查看任务调度表中是否有优先级合适的就绪任务。如果当前任务运行时调用OSSchedLock()给调度器上锁,这样再调用OSTIMEDLY()时就会把当前任务挂起。但由于调度器上锁而不能使其他任务得到CP

rayylee 7098

3dsMax高效导入OSGB倾斜模型的3个关键步骤与插件应用

本文详细解析了在3dsMax中高效导入OSGB倾斜模型的三个核心步骤:建立索引、处理贴图路径以及选择合适的插件。针对导入过程中常见的模型崩溃、贴图丢失和操作卡顿问题,提供了从数据结构理解到插件选型的实战解决方案,帮助用户实现大规模实景模型在3dsMax中的流畅导入与编辑。

weixin_29238147的博客 471

AM驱动架构—优质Mini-LED显示技术解决方案

(VR)和增强现实(AR)设备:MiniLED背光驱动方案适用于虚拟现实和增强现实设备中的显示技术,通过高亮度和高对比度的显示效果,创造更逼真的虚拟体验此外,MiniLED背光还能够实现更快的响应速度,减少图像残影,使得用户的动作在虚拟环境中更加流畅自然。以其出色的性能和广泛的应用前景备受关注是实现MiniLED显示效果的重要环节。1)更高的亮度和对比度:尺寸更小,可以在同样面积的显示屏上配置更多的LED,并且通过独立控制每一个MiniLED,可以实现更高的亮度和更细致的对比度,使得显示画面更加鲜明清晰。

isweekDN的博客 2763

UCOS-III 任务调度锁定/解锁接口OSSchedLock/Unlock详解

在实时操作系统中,关闭和打开任务调度是确保系统执行关键代码时保持原子性和数据一致性的重要手段。通过正确使用 OSSchedLock 和 OSSchedUnlock 接口,我们可以有效地控制任务调度,实现高效、稳定的实时系统

TechIoT - 探索物联网与嵌入式系统 1069

保姆级教程:用BIGEMAP和Global Mapper搞定5米精度DEM高程数据下载与处理

本文提供了一份详细的5米精度DEM高程数据处理教程,涵盖从BIGEMAP下载到Global Mapper处理的完整流程。通过实战案例和避坑指南,帮助用户掌握高效下载DEM数据、优化等高线生成及坐标系转换的关键技巧,适用于GIS新手和专业人士。

weixin_34169322的博客 390

uCOS-II函数解析

时间管理服务函数是以系统节拍为处理单位的,实际的时间与希望的时间是有误差的,最坏的情况下误差接近一个系统节拍。因此时间管理服务函数只能用在对时间精度要求不高的场合,或者时间间隔较长的场合。 1. void  OSSchedLock(void); void  OSSchedLock (void) { #if OS_CRITICAL_METHOD == 3

michaelyue526的专栏 4593

利用恒源云云端GPU高效训练YOLOv11模型全流程:从环境搭建到模型部署,让你摆脱硬件束缚

记住,云端GPU的核心优势是“弹性算力+一键环境”,只要把握好这一工具特性,再结合YOLOv11的高性能模型架构,你也能在计算机视觉领域快速落地项目。接下来,我们从工具准备到模型部署,一步步带你实现高效训练,真正帮你解决资源与效率的核心痛点。凭借其在目标检测、实例分割任务上的卓越性能,成为众多开发者的首选。据统计,使用云端GPU训练YOLOv11,在处理百万级数据集时,训练效率较本地普通GPU提升。在安防监控中,YOLOv11可实时检测人员、车辆异常行为,某园区采用该方案后,异常事件识别准确率达。

LXY_LOVE36的博客 213

RK3568平台YOLOv11模型部署全流程实战:环境搭建、模型转换与性能优化解析

在AI边缘计算领域,瑞芯微RK3568芯片凭借其强大的NPU算力和丰富的接口资源,成为了众多开发者的首选平台。然而,瑞芯微官方文档虽然提供了YOLO11预训练模型的部署方案,但对于需要自定义数据集训练的开发者来说,从模型训练到板端部署的完整流程却缺乏详细指导。本文将带你走完从环境搭建、数据准备、模型训练到最终板端部署的完整技术路线,并分享实际开发中遇到的各种坑点和解决方案。让我们一起探索如何在RK3568平台上实现30FPS稳定推理的YOLO11目标检测应用!

LXY_LOVE36的博客 122

ucos_ii 上锁函数OSSchedLock()函数透析

因为任务调度时一般都是通过OSTIMEDLY()来实现。在这个函数中会对当前的任务执行挂起。同时查看任务调度表中是否有优先级合适的就绪任务。如果当前任务运行时调用OSSchedLock()给调度器上锁,这样再调用OSTIMEDLY()时就会把当前任务挂起。但由于调度器上锁而不能使其他任务得到CPU的使用权。这样除了中断意外就没有任务可以运行了。除非中断中对这种情况有处理。我想调用其余两个...

bangju6321的博客 517

【机器视觉】基于深度学习的托盘PCB识别与计数(有无、正反)

工业机器视觉是指在制造业和工业环境中使用计算机视觉技术来执行检测、测量、识别和控制任务。它结合了硬件(如相机、镜头、光源)与软件(图像处理算法)来自动完成传统上需要人工视觉的任务,从而提高生产效率、产品质量以及工作安全性。工业机器视觉系统通常具有高精度、高速度和高可靠性,能够适应恶劣的工作环境。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

OSSchedLock()函数透析 转自:跳跳盆盆——博客园http://www.cnblogs.com/pengwangguoyh/p/4446024.html

uC/OS-II的OSSchedLock()和OSSchedUnlock()函数允许应用程序锁定当前任务不被其它任务抢占。 使用时应当注意的是:当你调用了OSSchedLock()之后,而在调用OSSchedUnlock()之前, 千万不要再调用诸如OSFlagPend()、OSMboxPend()、OSMutexPend()、OSQPend()、OSSemPend()之类的事件等待函

vilsen的专栏 711

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

uc/os-ii任务调度的锁定与解锁

调度器上锁函数OSSchedlock()的功能是用于禁止任务调度,使任务保持对CPU的控制权。调度器开锁函数OSSchedUnlock()的功能是解除对任务调度的禁止。 调度器上锁和开锁的实现原理是:对全局变量锁定嵌套计数器OSLockNesting进行操作,OSLockNesting跟踪OS SchedLock() 函数被调用的次数,允许嵌套深度达255层。

fillthesky的博客 8080

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

给调度器上锁和开锁(Locking and UnLocking the Scheduler)

给调度器上锁函数OSSchedlock()(程序清单L3.9)用于禁止任务调度,直到任务完成后调用给调度器开锁函数OSSchedUnlock()为止,(程序清单L3.10)。调用OSSchedlock()的任务保持对CPU的控制权,尽管有个优先级更高的任务进入了就绪态。然而,此时中断是可以被识别的,中断服务也能得到(假设中断是开着的)。OSSchedlock()和OSSchedUnlock()必须

FunkyFrog821951259的博客 2741

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

OSSchedLock() 是 μC/OS-II(一个嵌入式实时操作系统)中的一个函数

当调用该函数后,μC/OS-II 的任务调度器将被禁止进行任务切换,直到调用 OSSchedUnlock() 函数解锁调度器。这意味着在调度器被锁定期间,即使有更高优先级的任务就绪,也不会发生任务切换,当前正在运行的任务会继续执行。在上述示例中,Task1 任务在执行关键代码时调用 OSSchedLock() 锁定调度器,确保关键代码的执行不会被其他任务打断,执行完关键代码后,调用 OSSchedUnlock() 解锁调度器,恢复任务调度。// 初始化 μC/OS-II。// 任务 2 的操作。

weixin_44799641的博客 730

STM32-时钟系统详解

本节主要对STM32时钟系统进行讲解,我们从原理框图入手,对每一个时钟线路进行来源和去向的分析,介绍了时钟配置的相关寄存器以及STM32时钟的软件配置,最后通过SysTick定时器来编写延时函数。

qq_44016222的博客 4万+

UCOS-III 任务调度接口(OSSched)详解

OSSched函数用于检查并确定是否有更高优先级的任务需要运行。该函数通常在任务级别代码中调用,而不是在中断服务程序(ISR)中调用。中断服务程序的调度由OSIntExit()函数处理。OSSched函数主要完成以下任务: 检查操作系统运行状态。 检查中断嵌套计数器。 检查调度器是否被锁定。 获取最高优先级任务。 执行任务级别的上下文切换。

TechIoT - 探索物联网与嵌入式系统 968

OSSchedLock()

uC/OS-II中的OSSchedLock()和OSSchedUnlock()用来锁定当前任务不被其他任务锁定. 在使用时如果用户调用了OSSchedLock()之后不能在调用不得使用任何能将现行任务挂起的系统调用。 如OSMboxPend(),OSQPend(),OSSemPend(),OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMS

Joetu的博客 1034

uCOSIII实时操作系统 四 任务管理

如果分别建立了优先级3,5,8,11这个四个任务,任务创建成功之后,调用CPU_CntLeadZeros()我们可以计算出 OSPrioTbl[0] 第一个置 1 的位前面有 3 个 0,那么这个 3 就是我们要查找的最高优先级,至于后面还有多少个位置 1 我们都不用管,只需要找到第一个 1 即可。就绪任务列表OSRdyList[]通过上一步我们已经知道了哪一个优先级的任务已经就绪,但是UCOSIII支持时间片轮转调度,同一个优先级下可以有多个任务。而。

ttdffmm的博客 1241

ucosII中禁止任务调度方式

ucOSII禁止调度实验

m0_56507251的博客 1538

uC/OS-II之系统函数20160526

任务管理 1 OSTaskCreate() 建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能 建立任务。一个任务可以为无限循环的结构。 函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio); 参数说明:task 是指向...

weixin_30378623的博客 242

uC/OS-II源码分析(六)

μC/OS-Ⅱ总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高, 下面该哪个任务运行了的工作是由调度器(Scheduler)完成的。任务级的调度是由函数 OSSched()完成的。中断级的调度是由另一个函数OSIntExt() 完成的,这个函数将在以后描 述。OSSched() 的代码如下: void OS_Sched (void) { #if OS_CR...

weixin_33935777的博客 210

OSSched()函数详细介绍

当调用 OSSchedLock() 函数时,这个变量的值会增加,表示任务调度被锁住,即调度被临时禁止。如果 OSIntNesting 等于0,意味着当前系统中所有的中断服务程序(ISR)都已经执行完毕,系统不再处于处理中断的状态,允许任务调度。如果就绪表中存在一个优先级高于当前正在运行任务的任务,并且满足前两个条件,那么就应该触发任务调度,将CPU控制权切换给该高优先级任务。它的主要作用是检查当前系统中是否有更高优先级的任务就绪运行,如果有,则执行任务切换,将CPU控制权转交给该任务。

2301_79791448的博客 652
上一篇: 三点定位算法--用于平面2D定位
下一篇: 十大经典排序算法(动态演示+代码),亲测有用
菜鸟高工
博客等级 码龄16年 27粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值