在一个任务等待多个内核对象在之前,信号量和消息队列的发布过程中都有等待多个内核对象判断的函数,所谓任务等待多个内核对象顾名思义就是一任务同时等待多个内核对象而被挂起,在USOC—III中一个任务等待多个内核对象时只能是信号量和消息队列的组合。数据类型是OS_PEND_DATA的数组。
  在使任务等待多个内核对象时,先定义一个OS_PEND_DATA 类型的等待数据数组,数组的长度等于等待对象的个数,然后初始化数组元素内的Array[n].PendobjPtr=(OS_PEND_OBJ)某个内核对象,进行初始化后就可以调用对应的函数进行设置了。
任务等待多个内核对象函数:

OS_OBJ_QTY  OSPendMulti (OS_PEND_DATA  *p_pend_data_tbl,OS_OBJ_QTY     tbl_size,OS_TICK        timeout,OS_OPT         opt,OS_ERR        *p_err)
{CPU_BOOLEAN   valid;OS_OBJ_QTY    nbr_obj_rdy;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return ((OS_OBJ_QTY)0);}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Can't pend from an ISR                                 */*p_err = OS_ERR_PEND_ISR;return ((OS_OBJ_QTY)0);}
#endif#if OS_CFG_ARG_CHK_EN > 0uif (p_pend_data_tbl == (OS_PEND_DATA *)0) {             /* Validate 'p_pend_data_tbl'                             */*p_err = OS_ERR_PTR_INVALID;return ((OS_OBJ_QTY)0);}if (tbl_size == (OS_OBJ_QTY)0) {                        /* Array size must be > 0                                 */*p_err = OS_ERR_PTR_INVALID;return ((OS_OBJ_QTY)0);}//请求不到时阻塞? switch (opt) {case OS_OPT_PEND_BLOCKING:case OS_OPT_PEND_NON_BLOCKING:break;default:*p_err = OS_ERR_OPT_INVALID;return ((OS_OBJ_QTY)0);}
#endif//多个内核对象检查,只能是信号量或者是消息 valid = OS_PendMultiValidate(p_pend_data_tbl,           /* -------- Validate objects to be OS_SEM or OS_Q ------- */tbl_size);if (valid == DEF_FALSE) {*p_err = OS_ERR_OBJ_TYPE;                            /* Invalid, not OS_SEM or OS_Q                            */return ((OS_OBJ_QTY)0);}/*$PAGE*/CPU_CRITICAL_ENTER();//检查是否有内核对象已经提交 nbr_obj_rdy = OS_PendMultiGetRdy(p_pend_data_tbl,       /* --------- SEE IF OBJECT(s) HAVE BEEN POSTED ---------- */tbl_size);//有对象就绪,返回 if (nbr_obj_rdy > (OS_OBJ_QTY)0) {CPU_CRITICAL_EXIT();*p_err = OS_ERR_NONE;return ((OS_OBJ_QTY)nbr_obj_rdy);}if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {    /* Caller wants to block if not available?                */CPU_CRITICAL_EXIT();*p_err = OS_ERR_PEND_WOULD_BLOCK;                    /* No                                                     */return ((OS_OBJ_QTY)0);} else {if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /* Can't pend when the scheduler is locked                */CPU_CRITICAL_EXIT();*p_err = OS_ERR_SCHED_LOCKED;return ((OS_OBJ_QTY)0);}}/* Lock the scheduler/re-enable interrupts                */OS_CRITICAL_ENTER_CPU_EXIT();/* ------ NO OBJECT READY, PEND ON MULTIPLE OBJECTS ----- *///插入等待队列,和单独一个内核对象相似 OS_PendMultiWait(p_pend_data_tbl,                       /* Suspend task until object posted or timeout occurs     */tbl_size,timeout);OS_CRITICAL_EXIT_NO_SCHED();//挂起当前任务,之后任务能恢复就在于信号发布或消息队列的发布是将任务加入就绪列表 OSSched();                                              /* Find next highest priority task ready                  */CPU_CRITICAL_ENTER();switch (OSTCBCurPtr->PendStatus) {case OS_STATUS_PEND_OK:                             /* We got one of the objects posted to                    */*p_err = OS_ERR_NONE;break;case OS_STATUS_PEND_ABORT:                          /* Indicate that the multi-pend was aborted               */*p_err = OS_ERR_PEND_ABORT;break;case OS_STATUS_PEND_TIMEOUT:                        /* Indicate that we didn't get semaphore within timeout   */*p_err = OS_ERR_TIMEOUT;break;case OS_STATUS_PEND_DEL:                            /* Indicate that an object pended on has been deleted     */*p_err = OS_ERR_OBJ_DEL;break;default:*p_err = OS_ERR_STATUS_INVALID;break;}OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;CPU_CRITICAL_EXIT();return ((OS_OBJ_QTY)1);
}

OSPendMulti ()

其中调用的相关函数也是比较简单全部在OS_Pend_Multi.c文件里。等待多个内和对象实际就是前面的消息队列与多值信号量的组合,原理很简单具体的使用结合前面的相关操作就可以了。

任务内建信号量与消息队列
  任务内建的信号量与消息队列是UCOS作者为了方便使用而设计的数据结构放在每一个任务的任务控制块里这样操作更简单更省时,在实践的任务通信中,一个任务发送信号量或者消息给另一个任务是比较常见的,但是多个任务发送给一个任务的情况是比较少见的,而任务内建信号或消息队列不仅在数据结构的设计上更加简单,功能也是有区别的任务内建的对象不会有多个等待任务,等待任务有且仅有一个,他们是任务控制块里的所以不可以被单独删除,任务消息队列或信号量在任务创建时就要配置,在以往我们不使用内建对象时,这些选项都是被设置为0的,创建任务是函数传入参数OS_MSG_QTY就是消息队列的最大长度。任务控制块里的OS_SEM_CTR SemCtr;就是任务内建的多值信号量变量

内建消息队列和消息对列相同,在任务控制块内有一个MsgQ的变量如图结构:

OSTaskSemPost函数 同样是对opt进行检查,然后选择是否延迟发布,延迟发布最后也是进行相同的发布过程因此可以直接看OS_TaskSemPost函数,此函数的第一个入口参数就是任务控制块地址,如果为0 就默认为当前执行的任务,然后判断任务状态进行操作具体见源码注释。

************************************************************************************************************************
*                                                    SIGNAL A TASK
*
* Description: This function is called to signal a task waiting for a signal.
*
* Arguments  : p_tcb     is the pointer to the TCB of the task to signal.  A NULL pointer indicates that you are sending
*                        a signal to yourself.
*
*              opt       determines the type of POST performed:
*
*                             OS_OPT_POST_NONE         No option
*                             OS_OPT_POST_NO_SCHED     Do not call the scheduler
*
*              p_err     is a pointer to an error code returned by this function:
*
*                            OS_ERR_NONE              If the requested task is signaled
*                            OS_ERR_SEM_OVF           If the post would cause the semaphore count to overflow.
*
* Returns    : The current value of the task's signal counter or 0 if called from an ISR
************************************************************************************************************************
*/OS_SEM_CTR  OSTaskSemPost (OS_TCB  *p_tcb,OS_OPT   opt,OS_ERR  *p_err)
{OS_SEM_CTR  ctr;CPU_TS      ts;#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return ((OS_SEM_CTR)0);}
#endif#if OS_CFG_ARG_CHK_EN > 0uswitch (opt) {                                          /* Validate 'opt'                                         */case OS_OPT_POST_NONE:case OS_OPT_POST_NO_SCHED:break;default:*p_err =  OS_ERR_OPT_INVALID;return ((OS_SEM_CTR)0u);}
#endifts = OS_TS_GET();                                       /* Get timestamp                                          */#if OS_CFG_ISR_POST_DEFERRED_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* See if called from an ISR                              */OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_SIGNAL,   /* Post to ISR queue                                      */(void      *)p_tcb,(void      *)0,(OS_MSG_SIZE)0,(OS_FLAGS   )0,(OS_OPT     )0,(CPU_TS     )ts,(OS_ERR    *)p_err);return ((OS_SEM_CTR)0);}
#endifctr = OS_TaskSemPost(p_tcb,opt,ts,p_err);return (ctr);
}

OSTaskSemPost ()

OSTaskSemPend 函数 先检查选项,然后直接if (OSTCBCurPtr->SemCtr > (OS_SEM_CTR)0)判断任务控制块内的信号量是否可用,可用后进行相关的处理后返回可用值(数量),否则调用OS_Pend直接将当前任务阻塞,阻塞选项是任务内建信号量。

************************************************************************************************************************
*                                              WAIT FOR A TASK SEMAPHORE
*
* Description: This function is called to block the current task until a signal is sent by another task or ISR.
*
* Arguments  : timeout       is the amount of time you are will to wait for the signal
*
*              opt           determines whether the user wants to block if a semaphore post was not received:
*
*                                OS_OPT_PEND_BLOCKING
*                                OS_OPT_PEND_NON_BLOCKING
*
*              p_ts          is a pointer to a variable that will receive the timestamp of when the semaphore was posted
*                            or pend aborted.  If you pass a NULL pointer (i.e. (CPU_TS *)0) then you will not get the
*                            timestamp.  In other words, passing a NULL pointer is valid and indicates that you don't
*                            need the timestamp.
*
*              p_err         is a pointer to an error code that will be set by this function
*
*                                OS_ERR_NONE               The call was successful and your task received a message.
*                                OS_ERR_PEND_ABORT
*                                OS_ERR_PEND_ISR           If you called this function from an ISR and the result
*                                OS_ERR_PEND_WOULD_BLOCK   If you specified non-blocking but no signal was received
*                                OS_ERR_SCHED_LOCKED       If the scheduler is locked
*                                OS_ERR_STATUS_INVALID     If the pend status is invalid
*                                OS_ERR_TIMEOUT            A message was not received within the specified timeout
*                                                          would lead to a suspension.
*
* Returns    : The current count of signals the task received, 0 if none.
************************************************************************************************************************
*/OS_SEM_CTR  OSTaskSemPend (OS_TICK   timeout,OS_OPT    opt,CPU_TS   *p_ts,OS_ERR   *p_err)
{OS_SEM_CTR    ctr;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return ((OS_SEM_CTR)0);}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Not allowed to call from an ISR                        */*p_err = OS_ERR_PEND_ISR;return ((OS_SEM_CTR)0);}
#endif#if OS_CFG_ARG_CHK_EN > 0uswitch (opt) {                                          /* Validate 'opt'                                         */case OS_OPT_PEND_BLOCKING:case OS_OPT_PEND_NON_BLOCKING:break;default:*p_err = OS_ERR_OPT_INVALID;return ((OS_SEM_CTR)0);}
#endifif (p_ts != (CPU_TS *)0) {*p_ts  = (CPU_TS  )0;                                /* Initialize the returned timestamp                      */}CPU_CRITICAL_ENTER();if (OSTCBCurPtr->SemCtr > (OS_SEM_CTR)0) {              /* See if task already been signaled                      */OSTCBCurPtr->SemCtr--;ctr    = OSTCBCurPtr->SemCtr;if (p_ts != (CPU_TS *)0) {*p_ts  = OSTCBCurPtr->TS;}
#if OS_CFG_TASK_PROFILE_EN > 0uOSTCBCurPtr->SemPendTime = OS_TS_GET() - OSTCBCurPtr->TS;if (OSTCBCurPtr->SemPendTimeMax < OSTCBCurPtr->SemPendTime) {OSTCBCurPtr->SemPendTimeMax = OSTCBCurPtr->SemPendTime;}
#endifCPU_CRITICAL_EXIT();*p_err = OS_ERR_NONE;return (ctr);}if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {    /* Caller wants to block if not available?                */CPU_CRITICAL_EXIT();*p_err = OS_ERR_PEND_WOULD_BLOCK;                    /* No                                                     */return ((OS_SEM_CTR)0);} else {                                                /* Yes                                                    */if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /* Can't pend when the scheduler is locked                */CPU_CRITICAL_EXIT();*p_err = OS_ERR_SCHED_LOCKED;return ((OS_SEM_CTR)0);}}/* Lock the scheduler/re-enable interrupts                */OS_CRITICAL_ENTER_CPU_EXIT();                           OS_Pend((OS_PEND_DATA *)0,                              /* Block task pending on Signal                           */(OS_PEND_OBJ  *)0,(OS_STATE      )OS_TASK_PEND_ON_TASK_SEM,(OS_TICK       )timeout);OS_CRITICAL_EXIT_NO_SCHED();OSSched();                                              /* Find next highest priority task ready to run           */CPU_CRITICAL_ENTER();switch (OSTCBCurPtr->PendStatus) {                      /* See if we timed-out or aborted                         */case OS_STATUS_PEND_OK:if (p_ts != (CPU_TS *)0) {*p_ts                    =  OSTCBCurPtr->TS;
#if OS_CFG_TASK_PROFILE_EN > 0uOSTCBCurPtr->SemPendTime = OS_TS_GET() - OSTCBCurPtr->TS;if (OSTCBCurPtr->SemPendTimeMax < OSTCBCurPtr->SemPendTime) {OSTCBCurPtr->SemPendTimeMax = OSTCBCurPtr->SemPendTime;}
#endif}*p_err = OS_ERR_NONE;break;case OS_STATUS_PEND_ABORT:if (p_ts != (CPU_TS *)0) {*p_ts  =  OSTCBCurPtr->TS;}*p_err = OS_ERR_PEND_ABORT;                     /* Indicate that we aborted                               */break;case OS_STATUS_PEND_TIMEOUT:if (p_ts != (CPU_TS *)0) {*p_ts  = (CPU_TS  )0;}*p_err = OS_ERR_TIMEOUT;                        /* Indicate that we didn't get event within TO            */break;default:*p_err = OS_ERR_STATUS_INVALID;break;}ctr = OSTCBCurPtr->SemCtr;CPU_CRITICAL_EXIT();return (ctr);
}

OSTaskSemPend()

OSTaskQPost函数第一个参数就是要给发布的任务控制块,然后根据消息对列的模式FIFO或者LIFO,下来就是与消息对列相同的提交操作。

任务内建消息队列发布:

#if OS_CFG_TASK_Q_EN > 0u
void  OS_TaskQPost (OS_TCB       *p_tcb,void         *p_void,OS_MSG_SIZE   msg_size,OS_OPT        opt,CPU_TS        ts,OS_ERR       *p_err)
{CPU_SR_ALLOC();OS_CRITICAL_ENTER();if (p_tcb == (OS_TCB *)0) {                             /* Post msg to 'self'?                                    */p_tcb = OSTCBCurPtr;}*p_err  = OS_ERR_NONE;                                   /* Assume we won't have any errors                        */switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY:case OS_TASK_STATE_DLY:case OS_TASK_STATE_SUSPENDED:case OS_TASK_STATE_DLY_SUSPENDED:OS_MsgQPut(&p_tcb->MsgQ,                       /* Deposit the message in the queue                       */p_void,msg_size,opt,ts,p_err);OS_CRITICAL_EXIT();break;case OS_TASK_STATE_PEND:case OS_TASK_STATE_PEND_TIMEOUT:case OS_TASK_STATE_PEND_SUSPENDED:case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:if (p_tcb->PendOn == OS_TASK_PEND_ON_TASK_Q) { /* Is task waiting for a message to be sent to it?        */OS_Post((OS_PEND_OBJ *)0,p_tcb,p_void,msg_size,ts);OS_CRITICAL_EXIT_NO_SCHED();if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0u) {OSSched();                             /* Run the scheduler                                      */}} else {OS_MsgQPut(&p_tcb->MsgQ,                   /* No,  Task is pending on something else ...             */p_void,                         /*      ... Deposit the message in the task's queue       */msg_size,opt,ts,p_err);OS_CRITICAL_EXIT();}break;default:OS_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;break;}
}
#endif

OS_TaskQPost ()

总的来说任务内建的信号量或消息对列被创建出来就是有其特点使用简单方便,且管理方便。

任务内建消息队列等待:

#if OS_CFG_TASK_Q_EN > 0u
void  *OSTaskQPend (OS_TICK       timeout,OS_OPT        opt,OS_MSG_SIZE  *p_msg_size,CPU_TS       *p_ts,OS_ERR       *p_err)
{OS_MSG_Q     *p_msg_q;void         *p_void;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return ((void *)0);}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Can't Pend from an ISR                                 */*p_err = OS_ERR_PEND_ISR;return ((void *)0);}
#endif#if OS_CFG_ARG_CHK_EN > 0u                                  /* ---------------- VALIDATE ARGUMENTS ------------------ */if (p_msg_size == (OS_MSG_SIZE *)0) {                   /* User must supply a valid destination for msg size      */*p_err = OS_ERR_PTR_INVALID;return ((void *)0);}switch (opt) {                                          /* User must supply a valid option                        */case OS_OPT_PEND_BLOCKING:case OS_OPT_PEND_NON_BLOCKING:break;default:*p_err = OS_ERR_OPT_INVALID;return ((void *)0);}
#endifif (p_ts != (CPU_TS *)0) {*p_ts  = (CPU_TS  )0;                                /* Initialize the returned timestamp                      */}CPU_CRITICAL_ENTER();//取出任务内建消息队列 p_msg_q = &OSTCBCurPtr->MsgQ;                           /* Any message waiting in the message queue?              *///获取消息的地址 p_void  = OS_MsgQGet(p_msg_q,p_msg_size,p_ts,p_err);//如果获取到了消息 if (*p_err == OS_ERR_NONE) {
#if OS_CFG_TASK_PROFILE_EN > 0uif (p_ts != (CPU_TS *)0) {OSTCBCurPtr->MsgQPendTime = OS_TS_GET() - *p_ts;if (OSTCBCurPtr->MsgQPendTimeMax < OSTCBCurPtr->MsgQPendTime) {OSTCBCurPtr->MsgQPendTimeMax = OSTCBCurPtr->MsgQPendTime;}}
#endifCPU_CRITICAL_EXIT();//返回消息地址,同时指针形式的传入p_msg_size将消息长度传回 return (p_void);                                    /* Yes, Return oldest message received                    */}if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {    /* Caller wants to block if not available?                */*p_err = OS_ERR_PEND_WOULD_BLOCK;                    /* No                                                     */CPU_CRITICAL_EXIT();return ((void *)0);} else {                                                /* Yes                                                    */if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /*     Can't block when the scheduler is locked           */CPU_CRITICAL_EXIT();*p_err = OS_ERR_SCHED_LOCKED;return ((void *)0);}}/* Lock the scheduler/re-enable interrupts                */OS_CRITICAL_ENTER_CPU_EXIT();//没有请求到消息阻塞任务 OS_Pend((OS_PEND_DATA *)0,                              /* Block task pending on Message                          */(OS_PEND_OBJ  *)0,(OS_STATE      )OS_TASK_PEND_ON_TASK_Q,(OS_TICK       )timeout);OS_CRITICAL_EXIT_NO_SCHED();OSSched();                                              /* Find the next highest priority task ready to run       */CPU_CRITICAL_ENTER();switch (OSTCBCurPtr->PendStatus) {case OS_STATUS_PEND_OK:                             /* Extract message from TCB (Put there by Post)           */p_void      = OSTCBCurPtr->MsgPtr;*p_msg_size  = OSTCBCurPtr->MsgSize;if (p_ts != (CPU_TS *)0) {*p_ts  = OSTCBCurPtr->TS;
#if OS_CFG_TASK_PROFILE_EN > 0uOSTCBCurPtr->MsgQPendTime = OS_TS_GET() - OSTCBCurPtr->TS;if (OSTCBCurPtr->MsgQPendTimeMax < OSTCBCurPtr->MsgQPendTime) {OSTCBCurPtr->MsgQPendTimeMax = OSTCBCurPtr->MsgQPendTime;}
#endif}*p_err = OS_ERR_NONE;break;case OS_STATUS_PEND_ABORT:                          /* Indicate that we aborted                               */p_void     = (void      *)0;*p_msg_size = (OS_MSG_SIZE)0;if (p_ts  != (CPU_TS *)0) {*p_ts   = (CPU_TS  )0;}*p_err      =  OS_ERR_PEND_ABORT;break;case OS_STATUS_PEND_TIMEOUT:                        /* Indicate that we didn't get event within TO            */default:p_void     = (void      *)0;*p_msg_size = (OS_MSG_SIZE)0;if (p_ts  != (CPU_TS *)0) {*p_ts   =  OSTCBCurPtr->TS;}*p_err      =  OS_ERR_TIMEOUT;break;}CPU_CRITICAL_EXIT();return (p_void);                                        /* Return received message                                */
}
#endif

OSTaskQPend ()

转载于:https://www.cnblogs.com/w-smile/p/7978537.html

μC/OS-III---I笔记9---任务等待多个内核对象和任务内建信号量与消息队列相关推荐

  1. uCOS-III学习笔记(10)----等待多个内核对象

    理解:等待多个内核对象说的就是,比如一个任务需要等待信号量才能打开led1,等待一个消息队列才能打开led2,此时不用等待多个内核对象的话就算来了信号量也会被pend卡住而不能往下面运行,所以等待多个 ...

  2. 【UCOSIII】UCOSIII的同时等待多个内核对象

    UCOSIII同时等待多个内核对象 前面讲述了UCOSIII的信号量(一个任务与另一个任务同步).事件标志组(一个任务与多个任务同步),它们都可以完成任务的同步.同时,信号量(保证全局变量).消息队列 ...

  3. [原创]java WEB学习笔记71:Struts2 学习之路-- struts2常见的内建验证程序及注意点,短路验证,非字段验证,错误消息的重用...

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. 《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“信号量”

    "信号量内核对象"用于对资源进行计数. 在信号量内核对象内部,和其他内核对象一样,有一个使用计数,该使用计数表示信号量内核对象被打开的次数. 信号量内核对象中还有两个比较重要的数据 ...

  5. STM32工作笔记0088---时间标志组和同时等待多个内核对象

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 两个任务之间的同步,咱们一般用信号量,但是 一个任务和多个事件之间的同步可以用或同步,和 与同步.

  6. UC/OS III操作系统学习笔记

    UCOS操作系统学习笔记 1.UCOSIII任务 1.1任务管理 1.2 任务创建和删除.挂起和恢复 1.3 系统内部任务 2.UCOSIII中断和时间管理 2.1 中断管理 2.2 时间管理 3.U ...

  7. 基于μC/OS—III的CC1120驱动程序设计

    基于μC/OS-III的CC1120驱动程序设计 时间:2014-01-21 来源:电子设计工程 作者:张绍游,张贻雄,石江宏 关键字:CC1120   嵌入式操作系统   STM32F103ZE   ...

  8. OS和Linux笔记

    OS和Linux笔记 操作系统 基本概念 进程管理 进程和线程 协程 同步互斥 死锁 CAS技术 IPC 线程间通信 内存管理 Linux 基础知识 守护进程 系统监测 编译调试 文件管理 零拷贝技术 ...

  9. 【操作系统/OS笔记16】进程间通信(IPC),直接/间接通信与阻塞/非阻塞通信,信号,管道,消息队列,共享内存

    本次笔记内容: 11.8 IPC概述 11.9 信号.管道.消息队列和共享内存 文章目录 进程间通信(Inter-Process Communication, IPC)概述 为什么要进程间通信? 直接 ...

最新文章

  1. sqlserver 查找数据混排
  2. Kotlin中的接口回调
  3. ad怎么批量改元器件封装_Altium Designer 批量修改元件封装的方法(修正)
  4. Angular Redux
  5. Path Sum I, II
  6. java limit_Java 8 Stream:limit()和skip()之间的区别
  7. 遇到的bug及解决方法,持续更新
  8. 为Python安装Redis库
  9. MongoDB学习(黑马教程)-6-数据库MongoDB的验证时的错误信息的获取
  10. 句柄(handle)是什么?
  11. 解决svn文件图标不显示
  12. 哲学家进餐问题解决方法
  13. CentOS Steam 9 安装测试
  14. 使用VPS时的注意事项
  15. Charles工具使用教程,以及注意事项。
  16. 配置windows系统中 PHP的环境变量
  17. 手机App开发的有关问题
  18. linux服务器安装anaconda,然后远程使用jupyter
  19. Maven打包(瘦身打包部署),不包含第三方依赖jar包
  20. 天正服务器不显示,天正菜单无法显示怎么办?

热门文章

  1. 网安入门须知:注释的危害居然这么大?——注释漏洞导致的信息泄露
  2. 什么是GaussDB
  3. RDMA over TCP的协议栈工作过程浅析
  4. McAfee安全管理器允许任何用户绕过管理器的安全机制
  5. 用集合实现二分(折半)查找
  6. Spring+SpringMVC+maven使用@aspectJ添加切面
  7. asp.net中日志框架Log4Net的使用
  8. sea 配置资料收集
  9. Ajax(从json中提取数据)
  10. phpeclipse+xdebug配置