ucos源码分析(一)

2023-05-16

时间:2018.01.27 本人目前是大三学生 电子信息工程专业,在大学前俩年的时间,一直在使用和学习单片机,不过也仅仅是从51到32,马上要面临就业,最近开始学习linux ,驱动方面知识,看了几天视频,感觉看不下去了,昨晚突发奇想,下载了ucos的源码,想要分析一下这个小的嵌入式系统。本人将从头开始,通过调试追踪,对源代码进行细致分析。 

希望自己可以坚持下去。开发环境是linux+eclipse  仿真来运行程序。

下面进入正题,大家接触过C语言,单片机的同学都知道,程序的入口是main函数,当然在单片机中会有一些堆栈初始化以及中断向量设置我们现在不关注,

下面是这个程序的main函数;

int  main (void)
{
    OS_ERR  err;

    OSInit(&err);                                               /* Initialize "uC/OS-III, The Real-Time Kernel"         */

    OSTaskCreate((OS_TCB     *)&App_TaskStartTCB,               /* Create the start task                                */
                 (CPU_CHAR   *)"App Task Start",
                 (OS_TASK_PTR ) App_TaskStart,
                 (void       *) 0,
                 (OS_PRIO     ) APP_CFG_TASK_START_PRIO,
                 (CPU_STK    *)&App_TaskStartStk[0],
                 (CPU_STK     )(APP_CFG_TASK_START_STK_SIZE / 10u),
                 (CPU_STK_SIZE) APP_CFG_TASK_START_STK_SIZE,
                 (OS_MSG_QTY  ) 0,
                 (OS_TICK     ) 0,
                 (void       *) 0,
                 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
                 (OS_ERR     *)&err);

    OSStart(&err);                                              /* Start multitasking (i.e. give control to uC/OS-III). */

    while(DEF_ON){												/* Should Never Get Here							    */
    };
}
    OSInit(&err);                                               /* Initialize "uC/OS-III, The Real-Time Kernel"         */
 osInit(&err); 这是main函数中运行的第一个函数,下面是这个函数的实现 在os_core.c文件中
/*
************************************************************************************************************************
*                                                    INITIALIZATION
*
* Description: This function is used to initialize the internals of uC/OS-III and MUST be called prior to
*              creating any uC/OS-III object and, prior to calling OSStart().
*
* Arguments  : p_err         is a pointer to a variable that will contain an error code returned by this function.
*
*                                OS_ERR_NONE    Initialization was successful
*                                Other          Other OS_ERR_xxx depending on the sub-functions called by OSInit().
* Returns    : none
************************************************************************************************************************
*/

void  OSInit (OS_ERR  *p_err)
{
#if (OS_CFG_ISR_STK_SIZE > 0u)
    CPU_STK      *p_stk;
    CPU_STK_SIZE  size;
#endif



#ifdef OS_SAFETY_CRITICAL
    if (p_err == DEF_NULL) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

    OSInitHook();                                               /* Call port specific initialization code               */

    OSIntNestingCtr       = 0u;                                 /* Clear the interrupt nesting counter                  */

    OSRunning             = OS_STATE_OS_STOPPED;                /* Indicate that multitasking not started               */

    OSSchedLockNestingCtr = 0u;                                 /* Clear the scheduling lock counter                    */

    OSTCBCurPtr           = DEF_NULL;                           /* Initialize OS_TCB pointers to a known state          */
    OSTCBHighRdyPtr       = DEF_NULL;

    OSPrioCur             = 0u;                                 /* Initialize priority variables to a known state       */
    OSPrioHighRdy         = 0u;
#if (OS_CFG_ISR_POST_DEFERRED_EN == DEF_ENABLED)
    OSPrioSaved           = 0u;
#endif

#if (OS_CFG_SCHED_LOCK_TIME_MEAS_EN == DEF_ENABLED)
    OSSchedLockTimeBegin  = 0u;
    OSSchedLockTimeMax    = 0u;
    OSSchedLockTimeMaxCur = 0u;
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508
    OSSafetyCriticalStartFlag       =  DEF_FALSE;
#endif

#if (OS_CFG_SCHED_ROUND_ROBIN_EN == DEF_ENABLED)
    OSSchedRoundRobinEn             = DEF_FALSE;
    OSSchedRoundRobinDfltTimeQuanta = OSCfg_TickRate_Hz / 10u;
#endif

#if (OS_CFG_ISR_STK_SIZE > 0u)
    p_stk = OSCfg_ISRStkBasePtr;                                /* Clear exception stack for stack checking.            */
    if (p_stk != DEF_NULL) {
        size  = OSCfg_ISRStkSize;
        while (size > 0u) {
            size--;
           *p_stk = 0u;
            p_stk++;
        }
    }
#if (OS_CFG_TASK_STK_REDZONE_EN == DEF_ENABLED)                 /* Initialize Redzoned ISR stack                        */
    OS_TaskStkRedzoneInit(OSCfg_ISRStkBasePtr, OSCfg_ISRStkSize);
#endif
#endif

#if (OS_CFG_APP_HOOKS_EN == DEF_ENABLED)                        /* Clear application hook pointers                      */
#if (OS_CFG_TASK_STK_REDZONE_EN == DEF_ENABLED)
    OS_AppRedzoneHitHookPtr = DEF_NULL;
#endif
    OS_AppTaskCreateHookPtr = DEF_NULL;
    OS_AppTaskDelHookPtr    = DEF_NULL;
    OS_AppTaskReturnHookPtr = DEF_NULL;

    OS_AppIdleTaskHookPtr   = DEF_NULL;
    OS_AppStatTaskHookPtr   = DEF_NULL;
    OS_AppTaskSwHookPtr     = DEF_NULL;
    OS_AppTimeTickHookPtr   = DEF_NULL;
#endif

#if (OS_CFG_TASK_REG_TBL_SIZE > 0u)
    OSTaskRegNextAvailID    = 0u;
#endif

    OS_PrioInit();                                              /* Initialize the priority bitmap table                 */

    OS_RdyListInit();                                           /* Initialize the Ready List                            */


#if (OS_CFG_FLAG_EN == DEF_ENABLED)                             /* Initialize the Event Flag module                     */
#if (OS_CFG_DBG_EN == DEF_ENABLED)
    OSFlagDbgListPtr = DEF_NULL;
    OSFlagQty        = 0u;
#endif
#endif

#if (OS_CFG_MEM_EN == DEF_ENABLED)                              /* Initialize the Memory Manager module                 */
    OS_MemInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_MSG_EN == DEF_ENABLED)                                  /* Initialize the free list of OS_MSGs                  */
    OS_MsgPoolInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_MUTEX_EN == DEF_ENABLED)                            /* Initialize the Mutex Manager module                  */
#if (OS_CFG_DBG_EN == DEF_ENABLED)
    OSMutexDbgListPtr = DEF_NULL;
    OSMutexQty        = 0u;
#endif
#endif


#if (OS_CFG_Q_EN == DEF_ENABLED)                                /* Initialize the Message Queue Manager module          */
#if (OS_CFG_DBG_EN == DEF_ENABLED)
    OSQDbgListPtr = DEF_NULL;
    OSQQty        = 0u;
#endif
#endif


#if (OS_CFG_SEM_EN == DEF_ENABLED)                              /* Initialize the Semaphore Manager module              */
#if (OS_CFG_DBG_EN == DEF_ENABLED)
    OSSemDbgListPtr = DEF_NULL;
    OSSemQty        = 0u;
#endif
#endif


#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)
    OS_TLS_Init(p_err);                                         /* Initialize Task Local Storage, before creating tasks */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


    OS_TaskInit(p_err);                                         /* Initialize the task manager                          */
    if (*p_err != OS_ERR_NONE) {
        return;
    }


#if (OS_CFG_ISR_POST_DEFERRED_EN == DEF_ENABLED)
    OS_IntQTaskInit(p_err);                                     /* Initialize the Interrupt Queue Handler Task          */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_TASK_IDLE_EN == DEF_ENABLED)
    OS_IdleTaskInit(p_err);                                     /* Initialize the Idle Task                             */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_TASK_TICK_EN == DEF_ENABLED)
    OS_TickTaskInit(p_err);                                     /* Initialize the Tick Task                             */
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_STAT_TASK_EN == DEF_ENABLED)                        /* Initialize the Statistic Task                        */
    OS_StatTaskInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_TMR_EN == DEF_ENABLED)                              /* Initialize the Timer Manager module                  */
    OS_TmrInit(p_err);
    if (*p_err != OS_ERR_NONE) {
        return;
    }
#endif


#if (OS_CFG_DBG_EN == DEF_ENABLED)
    OS_Dbg_Init();
#endif


    OSCfg_Init();

    OSInitialized = DEF_TRUE;                                   /* Kernel is initialized                                */
}
代码一长了就没人想看,我也没有看下去的欲望,但是仔细分析,其实都是一些条件编译的东西;
突然想起了一个词,叫做可裁剪,其实,这里的内容就是实现了ucos内核的裁剪功能,根据编译之前对一些功能宏的定义,实现编译我们需要的功能,去掉那些不需要的功能。这个在嵌入式开发中还是比较的重要,在一些嵌入式芯片,无论是ram还是flash都是寸土寸金,有时可能就是因为多定义了一些变量就会导致程序编译失败。  
我接下来只会讲参加编译的代码
继续分析我们的这个初始化代码
#if (OS_CFG_ISR_STK_SIZE > 0u)  /* 在我的项目 OS_CFG_ISR_STK_SIZE=256 猜测这个宏是一个与堆栈有关*/
    CPU_STK      *p_stk;   /* 而且这个宏确实是大于0 这段代码会被编译 这里是定义可俩个变量*/
    CPU_STK_SIZE  size;   /* 从名字上去看 应该是一个堆栈指针和大小 但是这里并没有赋值 后面应该会继续赋值*/
#endif   
 OSInitHook();                                               /* Call port specific initialization code               */
/根据官方给出的注释  这里是一个初始化化 下面是这函数的实现*/
  *********************************************************************************************************
*                                       OS INITIALIZATION HOOK
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments  : None.
*
* Note(s)    : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/

void  OSInitHook (void)
{


    struct  rlimit  rtprio_limits;
    ERR_CHK(getrlimit(RLIMIT_RTPRIO, &rtprio_limits));
    if (rtprio_limits.rlim_cur != RLIM_INFINITY) {
        printf("Error: RTPRIO limit is too low. Set to 'unlimited' via 'ulimit -r' or /etc/security/limits.conf\r\n");
        exit(-1);
    }


    CPU_IntInit();                                              /* Initialize critical section objects.                 */
}
 上面这个函数的主要内容是 cpu_intinit(); 暂时不去看,后面如果需要在回来看
 接着往下分析
这里是对一些变量初始化赋值,根据后面注释可以看出大概的意思 
    OSIntNestingCtr       = 0u;                                 /* Clear the interrupt nesting counter                  */

    OSRunning             = OS_STATE_OS_STOPPED;                /* Indicate that multitasking not started               */

    OSSchedLockNestingCtr = 0u;                                 /* Clear the scheduling lock counter                    */

    OSTCBCurPtr           = DEF_NULL;                           /* Initialize OS_TCB pointers to a known state          */
    OSTCBHighRdyPtr       = DEF_NULL;

    OSPrioCur             = 0u;                                 /* Initialize priority variables to a known state       */
    OSPrioHighRdy         = 0u;
 下面也是一个开关  具体意思还不太了解
#if (OS_CFG_SCHED_ROUND_ROBIN_EN == DEF_ENABLED)
    OSSchedRoundRobinEn             = DEF_FALSE;
    OSSchedRoundRobinDfltTimeQuanta = OSCfg_TickRate_Hz / 10u;
#endif
 下面这段有熟悉的地方 有几个变量都在上面出现过了,在上面定义过但是没有赋值,这里开始赋值
#if (OS_CFG_ISR_STK_SIZE > 0u)
    p_stk = OSCfg_ISRStkBasePtr;            /* 这里给堆栈指针赋值 跟踪过去发现 OSCfg_ISRStkBasePtr是一个数组的首指针*/
    if (p_stk != DEF_NULL) {
        size  = OSCfg_ISRStkSize;
        while (size > 0u) {   /* 这里是对堆栈初始化,清零 同时 堆栈指针p_stk会指向堆栈数组的尾部*/
            size--;     
           *p_stk = 0u;
            p_stk++;
        }
    }
 这里又是一个初始化的部分,是对任务优先级的一个初始化,这里我们先不研究,在之后的任务调度肯定会用到
/*
************************************************************************************************************************
*                                               INITIALIZE THE PRIORITY LIST
*
* Description: This function is called by uC/OS-III to initialize the list of ready priorities.
*
* Arguments  : none
*
* Returns    : none
*
* Note       : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

void  OS_PrioInit (void)
{
    CPU_DATA  i;


                                                                /* Clear the bitmap table ... no task is ready          */
    for (i = 0u; i < OS_PRIO_TBL_SIZE; i++) {
         OSPrioTbl[i] = 0u;
    }

#if (OS_CFG_TASK_IDLE_EN == DEF_DISABLED)
    OS_PrioInsert ((OS_CFG_PRIO_MAX - 1u));                     /* Insert what would be the idle task                   */
#endif
}

这个也是一个任务相关数组的初始化 后面会重点关注
************************************************************************************************************************
*                                                    INITIALIZATION
*                                               READY LIST INITIALIZATION
*
* Description: This function is called by OSInit() to initialize the ready list.  The ready list contains a list of all
*              the tasks that are ready to run.  The list is actually an array of OS_RDY_LIST.  An OS_RDY_LIST contains
*              three fields.  The number of OS_TCBs in the list (i.e. .NbrEntries), a pointer to the first OS_TCB in the
*              OS_RDY_LIST (i.e. .HeadPtr) and a pointer to the last OS_TCB in the OS_RDY_LIST (i.e. .TailPtr).
*
*              OS_TCBs are doubly linked in the OS_RDY_LIST and each OS_TCB points pack to the OS_RDY_LIST it belongs
*              to.
*
*              'OS_RDY_LIST  OSRdyTbl[OS_CFG_PRIO_MAX]'  looks like this once initialized:
*
*                               +---------------+--------------+
*                               |               | TailPtr      |-----> 0
*                          [0]  | NbrEntries=0  +--------------+
*                               |               | HeadPtr      |-----> 0
*                               +---------------+--------------+
*                               |               | TailPtr      |-----> 0
*                          [1]  | NbrEntries=0  +--------------+
*                               |               | HeadPtr      |-----> 0
*                               +---------------+--------------+
*                                       :              :
*                                       :              :
*                                       :              :
*                               +---------------+--------------+
*                               |               | TailPtr      |-----> 0
*          [OS_CFG_PRIO_MAX-1]  | NbrEntries=0  +--------------+
*                               |               | HeadPtr      |-----> 0
*                               +---------------+--------------+
*
*
* Arguments  : none
*
* Returns    : none
*
* Note(s)    : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

void  OS_RdyListInit (void)
{
    CPU_INT32U    i;
    OS_RDY_LIST  *p_rdy_list;



    for (i = 0u; i < OS_CFG_PRIO_MAX; i++) {                    /* Initialize the array of OS_RDY_LIST at each priority */
        p_rdy_list = &OSRdyList[i];
#if (OS_CFG_DBG_EN == DEF_ENABLED)
        p_rdy_list->NbrEntries = 0u;
#endif
        p_rdy_list->HeadPtr    = DEF_NULL;
        p_rdy_list->TailPtr    = DEF_NULL;
    }
}

 剩下的部分都是一些条件编译的初始化,就不分析了  
 这里是本文分析的第一个函数 OS_INIT();
总结一下呢就是对一些数据结构的初始化,我们重点会关注 任务调度时间 以及其他的功能实现 后面会继续分析
第一次写博客 内容有些乱 分析的也很肤浅 应为我本来也不会哈哈哈


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ucos源码分析(一) 的相关文章

  • freeRTOS与ucos II区别

    freeRTOS比uCOS II优胜的地方 1 内核ROM和耗费RAM都比uCOS 小 xff0c 特别是RAM 这在单片机里面是稀缺资源 xff0c UCOS至少要5K以上 xff0c 而freeOS用2 3K也可以跑的很好 xff1b
  • uCOS任务信号量相关函数代码理解

    强调任务信号量思想 xff1a 任务信号量只是一个标志 xff0c 获取成功就是指把信号量计数值减1 xff1b 释放就是指把信号量计数值加1 xff08 溢出则计数值不变 xff09 获取信号量需要判断信号量是否可用 xff08 大于0
  • UCOS-II任务设计

    UCOS II任务设计 任务函数的结构 xff1a 在用户任务函数中 xff0c 必须包含至少一次对操作系统服务函数的调用 xff0c 否则比其优先级低的任务将无法得到运行的机会 xff0c 这是用户任务与普通函数的明显区别 任务函数按照执
  • docker源码分析(1)(持续更新)

    docker源码分析 xff08 1 xff09 xff08 持续更新 xff09 daemondocker DaemonClient的启动内部函数分析newAPIServerConfigloadListenersinitContainer
  • UCOS II 中信号量的使用

    UCOS II 中信号量的使用 UCOS II 中信号量的使用1 声明信号量2 创建信号量3 请求信号量4 发送信号量5 删除信号量 UCOS II 中信号量的使用 1 声明信号量 例如 xff1a OS EVENT Fun semp 声明
  • Autoware源码分析——astar_avoid

    概要 本文是对autoware中waypoint planner功能包的相关文件组成和具体节点的分析 由于程序比较复杂 xff0c 我认为还存在一些不完整的地方 xff0c 之后也会继续分析 xff0c 继续更新 在看代码的过程中也学习了一
  • 从 C51+uCos-II 近距离了解操作系统任务切换原理

    前言 从 C51 43 uCos II 简单介绍下任务切换的原理 方便大家更形象的理解多任务怎么切换 为后续写 x86 43 Linux 任务切换做铺垫练手吧 参考资料如下 xff1a uCos II 源码 单片机原理与应用及 C51 编程
  • Freertos 源码分析 队列queue

    队列queue xff08 零 xff09 队列的基础概念和形态 xff08 一 xff09 Freertos 队列 queue c FreeRTOS Kernel 10 4 6 include queue h Freertos队列模块包含
  • ucos信号量集

    事件标志组 信号量集 的使用 xff1a span class token keyword static span OS STK task testled span class token punctuation span STARTUP
  • 【ROS】源码分析-消息订阅与发布

    说明 本文通过NodeHandle subscribe和Publication publish 源码作为入口 xff0c 来分析PubNode SubNode之间是网络连接是如何建立的 xff0c 消息是如何发布的 xff0c topic队
  • [JavaSE 源码分析] 关于HashMap的个人理解

    目录 HashMap是什么 HashMap的底层数据结构是什么 table容量为什么必须是二的倍数 table容量怎么做到二的倍数 Entry是怎样的结构 Node Entry在HashMap中的具体实现处理hash冲突的方法HashMap
  • mybatis 自动化处理 mysql 的json类型字段 终极方案

    文章目录 mybatis 自动化处理 mysql 的json类型字段 终极方案 why json 简介 mysql 建表 json 字段 添加1条json 数据 对应的java对象 JsonEntity mybatis 不使用 通用mapp
  • 阿里云OSS请求文件跨域问题Access-Control-Allow-Origin

    跨域问题网上很多解决方案提示到这里配置但是不生效 一定要勾选Vary Origin这个选项 请求的时候浏览器记得请求在控制台要清理缓存
  • Spring IOC容器初始化过程 源码分析

    本文主要记录Spring容器创建 源码分析过程 首先贴上一张时序图 好久没画 忘的差不多了 画的不好 可以凑合看一下 接下来 贴上一份测试代码 这里使用AnnotationConfigApplicationContext来初始化Spring
  • Glide3.7.0源码详解

    基于的Glide版本 3 7 0 本文分析的是Glide最基本的一行代码 Glide with this load url into imageView 我们认准这一个功能点 来看看Glide默默为我们做了什么 这篇文章会分析这行代码背后的
  • GTest源码剖析(六)——RUN_ALL_TESTS

    GTest源码剖析 RUN ALL TESTS GTest源码剖析RUN ALL TESTS RUN ALL TESTS源码分析 1 UnitTestRun 2 HandleExceptionsInMethodIfSupported 3 U
  • Mybatis整合Spring源码分析

    一 整合配置 POM
  • ucos2-cpu_c.c-位带操作

    在uC CPU ARM Cortex M3 cpu c c中有两个位带访问的函数 使用位带访问技术来对内存或外设地址addr中的第bit nbr位进行清零操作 void CPU BitBandClr CPU ADDR addr CPU IN
  • Wifi模块—源码分析Wifi热点扫描2(Android P)

    一 前言 这次接着讲Wifi工程流程中的Wifi热点扫描过程部分的获取扫描结果的过程 也是Wifi扫描过程的延续 可以先看前面Wifi扫描的分析过程 Wifi模块 源码分析Wifi热点扫描 Android P 二 图示调用流程 这次的调用流
  • IDEA国际化资源Key无法全局重命名的解决方案

    一 前言 最近在开发中使用到了HibernateValidator进行入参校验以及错误消息的国际化支持 大家应该都知道在使用HibernateValidator进行校验的时候 我们只需在需要在校验的变量上添加相应的注解 同时在message

随机推荐

  • 处理iOS开发中的各种警告

    iOS开发中我们会遇到各种警告 包括第三方不再支持更新导致的警告 苹果一些过时方法的警告 其中尤其是ASIHttpRequest的不支持更新导致有很多的警告 所以我在这里做了罗列 Semantic Warnings WarningMessa
  • c#利用虚拟串口工具进行串口通信数据的发送和接收

    原文 xff1a 我的个人博客 串口通信 串口通信 xff08 Serial Communications xff09 的概念非常简单 xff0c 串口按位 xff08 bit xff09 发送和接收字节 尽管比按字节 xff08 byte
  • stm32 移植 FreeRTOS

    1 建立裸机工程 在移植 freeRTOS 之前需要创建一个 stm32f103 的 keil5 裸机工程 所谓裸机工程就是包含 stm32f103 单片机的启动文件 xff0c 外设驱动固件库的文件集合 xff0c 也可以说是支持裸机开发
  • ESP32(Espressif-IDE)添加外部(.c .h)文件 (error:undefined reference to)

    0x00 xff1a 前言 笔记文件 用习惯了keil和iar之类的开发软件 xff0c 一下子转换到ESP32是特别的不习惯 xff0c 这里使用的开发环境是乐鑫官方推出的Espressif IDE xff0c 也是刚学折腾ESP32 x
  • 无人机地面站源码搭建环境(qt版)记录

    最近基于项目需要 xff0c 借鉴无名创新的QT版开源地面站 xff0c 搭建一款测试平台 原本以为比较简单的 但是在搭建过程中还是遇到了很多看不见的坑 xff0c 在这里分享给大家 xff0c 避免别人在开发类似项目时像我这样走弯路 基本
  • 如何才能有论文创新点?idear

    1 看别人是怎么解决问题的 xff0c 别人写的每一篇论文都是在解决问题 2 看自己领域综述性论文 xff0c 对某一问题都是一步步发展出来的 xff0c 某一方法也是一步一步更新完善的 xff0c 这些解决的都是问题 3 看一篇论文的引言
  • 前端图片裁剪cropper.js

    背景 xff1a 我们在项目中常常都会有更换登陆人头像的需求 xff0c 这个很简单直接上传一张图片展示就可以了 xff0c 但是如果上传的图片需要剪裁成正方形的话就需要我们来做一些特殊的处理 xff1b 这里我们会用到一个图片剪裁插件 x
  • 新产品开发之C流程 (C-flow)

    关于新产品开发的C流程 C flow xff0c 是世界上大公司采用的标准开发流程 xff0c 十分基本也十分重要 xff0c 但是网上关于C流程介绍相关的资料很少 xff0c 所以花点时间整理一下相关的资料 下面以软件BSP开发为例 xf
  • Arduino的Stepper库函数及其控制步进电机(ULN2003)调速

    问题来源 最近自学Arduino xff0c 在使用步进电机时开始没能使步进电机转起来 xff0c 转起来后感觉没法调速 xff0c 遂完成此篇笔记供自己后续查阅以及方便遇到相同问题的诸君寻找灵感 对于如何使步进电机转动就不详述 xff0c
  • 一、电脑端实现单片机与ESP8266的通信

    1 准备工具 xff08 硬件 软件 xff09 硬件 xff1a 51单片机开发板 ESP8266无线模块 xff08 ESP8266 01 xff09 TTL USB串口 杜邦线 数据线 xff1b 软件 xff1a keil uv4单
  • 错误 LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(main.obj 中)

    前言 vs2019报错如下图 xff1a 错误 LNK2038 检测到 ITERATOR DEBUG LEVEL 的不匹配项 值 2 不匹配值 0 main obj 中 错误原因 1 产生这个问题的原因是当前工程是Debug版本 xff0c
  • 三种获取字节码对象的方式及区别

    方式一 xff1a 对象 getClass 方法是 根对象Object的方法 是其他类继承Object的getClass方法 方式二 xff1a 类名 class xff0c 你可以理解为字节码本身就是静态的 xff0c 类加载的时字节码就
  • 关于接口与Object 类的关系

    看到这个标题 xff0c 你或许就会想好自己的那份答案 但事实上这个确实没有答案 xff0c 至少没官方证明它们之间的基友关系 看法一 xff1a 因为老师说 xff0c 你可以把接口看作是特殊的类 xff0c 所以不假思索的就认为接口也
  • 单词博弈Java实现(借鉴“miss若尘”博客中写的解题思路)

    单词博弈Java实现 xff0c 已经通过庞果网的用例测试 代码如下 import java util HashMap public class WordGameFinalTest public static int who String
  • 我的2013,梦在路上

    我的2013 xff0c 在路上 今年最后一次给姐姐打电话 xff0c 她在那里像我炫耀自己和爸爸妈妈一起跨年 xff0c 说1314的意义 xff0c 而我还在北京苦逼着 回想2013年对于我来说 xff0c 或许是不错的一年 这一年我进
  • mysql安装时的粗心错误:last error unable to update security settings. access denied for user 'root' @ 'localh

    来自 梦想家haima 39 s blog gt http blog dreamwe cn 这个报错出现在mysql最后 当你看到mysql的最后一步需要设置密码可能你开心得很 Mysql就快安装好了 赶快输入三行密码都是root 结果报下
  • @SuppressWarnings

    简介 xff1a java lang SuppressWarnings是J2SE 5 0中标准的Annotation之一 可以标注在类 字段 方法 参数 构造方法 xff0c 以及局部变量上 作用 xff1a 告诉编译器忽略指定的警告 xf
  • 欢迎使用CSDN-markdown编辑器

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • Linux之强大的awk

    来自 梦想家 Haima s blog gt http blog dreamwe cn awk简介 awk是Linux中的一个命令 xff0c 用来做文本处理与分析 xff0c 功能简单强悍 xff0c 同时它也是一门编程语言 awk处理文
  • ucos源码分析(一)

    时间 2018 01 27 本人目前是大三学生 电子信息工程专业 xff0c 在大学前俩年的时间 xff0c 一直在使用和学习单片机 xff0c 不过也仅仅是从 xff15 xff11 到 xff13 xff12 xff0c 马上要面临就业