当前位置: 首页 > news >正文

服务网站建设公司网站开发框架技术

服务网站建设公司,网站开发框架技术,如何注册域名和网站,浙江建设网证书查询写在前面#xff1a; 由于时间的不足与学习的碎片化#xff0c;写博客变得有些奢侈。 但是对于记录学习#xff08;忘了以后能快速复习#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位#xff0c;以时间为顺序#xff0c;仅仅将博客当做一个知识学习的目录 由于时间的不足与学习的碎片化写博客变得有些奢侈。 但是对于记录学习忘了以后能快速复习的渴望一天天变得强烈。 既然如此 不如以天为单位以时间为顺序仅仅将博客当做一个知识学习的目录记录笔者认为最通俗、最有帮助的资料并尽量总结几句话指明本质以便于日后搜索起来更加容易。 标题的结构如下“类型”“知识点”——“简短的解释” 部分内容由于保密协议无法上传。 点击此处进入学习日记的总目录 2024.04.15UCOSIII第四十三节任务消息队列 五十七、UCOSIII任务消息队列1、任务消息队列的基本概念2、任务消息队列的函数接口讲解1. 任务消息队列发送函数OSTaskQPost()2. 任务消息队列获取函数OSTaskQPend() 3、任务消息队列实验4、任务消息队列实验现象 五十七、UCOSIII任务消息队列 1、任务消息队列的基本概念 任务消息队列跟任务信号量一样均隶属于某一个特定任务不需单独创建任务在则任务消息队列在只有该任务才可以获取接收这个任务消息队列的消息 其他任务只能给这个任务消息队列发送消息却不能获取。 任务消息队列与前面讲解的普通消息队列极其相似只是任务消息队列已隶属于一个特定任务 所以它不具有等待列表在操作的过程中省去了等待任务插入和移除列表的动作所以工作原理相对更简单一点效率也比较高一些。 注意 本专栏所提的“消息队列”若无特别说明均指前面的普通消息队列属于内核对象而非任务消息队列。 通过对任务消息队列的合理使用可以在一定场合下替代μC/OS的消息队列用户只需向任务内部的消息队列发送一个消息而不用通过外部的消息队列进行发送 这样子处理就会很方便并且更加高效当然凡事都有利弊任务消息队列虽然处理更快RAM开销更小但也有限制只能指定消息发送的对象 有且只有一个任务接收消息而内核对象的消息队列则没有这个限制用户在发送消息的时候可以采用广播消息的方式让所有等待该消息的任务都获取到消息。 在实际任务间的通信中一个或多个任务发送一个消息给另一个任务是非常常见的而一个任务给多个任务发送消息的情况相对比较少 前者就很适合采用任务消息队列进行传递消息如果任务消息队列可以满足设计需求那么尽量不要使用普通消息队列这样子设计的系统会更加高效。 内核对象消息队列是用结构体OS_Q来管理的包含了管理消息的元素 MsgQ 和管理等待列表的元素 PendList等。 而任务消息队列的结构体成员变量就少了PendList因为等待任务消息队列只有拥有任务消息队列本身的任务才可以进行获取 故任务消息队列不需要等待列表的相关数据结构具体如下 注意 想要使用任务消息队列就必须将OS_CFG_TASK_Q_EN宏定义配置为1该宏定义位于os_cfg.h文件中。 struct os_msg_q {OS_MSG *InPtr; (1)OS_MSG *OutPtr; (2)OS_MSG_QTY NbrEntriesSize; (3)OS_MSG_QTY NbrEntries; (4)OS_MSG_QTY NbrEntriesMax; (5) };(1)、(2)任务消息队列中进出消息指针。(3)任务消息队列中最大可用的消息个数在创建任务的时候由用户指定这个值的大小。(4)记录任务消息队列中当前的消息个数 每当发送一个消息到任务消息队列的时候若任务没有在等待该消息那么新发送的消息被插入任务消息队列后此值加1 NbrEntries 的大小不能超过NbrEntriesSize。(5)记录任务消息队列最多的时候拥有的消息个数。 任务消息队列的运作机制与普通消息队列一样没什么差别。 2、任务消息队列的函数接口讲解 1. 任务消息队列发送函数OSTaskQPost() 函数 OSTaskQPost()用来发送任务消息队列参数中有指向消息要发送给的任务控制块的指针 任何任务都可以发送消息给拥有任务消息队列的任务任务在被创建的时候要设置参数 q_size 大于 0 其源码具体如下 #if OS_CFG_TASK_Q_EN 0u //如果启用了任务消息队列 void OSTaskQPost (OS_TCB *p_tcb, (1) //目标任务 void *p_void, (2) //消息内容地址OS_MSG_SIZE msg_size, (3) //消息长度OS_OPT opt, (4) //选项OS_ERR *p_err) (5) //返回错误类型 {CPU_TS ts;#ifdef OS_SAFETY_CRITICAL//如果启用默认禁用了安全检测if (p_err (OS_ERR *)0) //如果错误类型实参为空{OS_SAFETY_CRITICAL_EXCEPTION(); //执行安全检测异常函数return; //返回停止执行} #endif#if OS_CFG_ARG_CHK_EN 0u//如果启用了参数检测switch (opt) //根据选项分类处理{case OS_OPT_POST_FIFO: //如果选项在预期内case OS_OPT_POST_LIFO:case OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED:case OS_OPT_POST_LIFO | OS_OPT_POST_NO_SCHED:break; //直接跳出default: //如果选项超出预期*p_err OS_ERR_OPT_INVALID; //错误类型为“选项非法”return; //返回停止执行} #endifts OS_TS_GET(); //获取时间戳#if OS_CFG_ISR_POST_DEFERRED_EN 0u//如果启用了中断延迟发布if (OSIntNestingCtr (OS_NESTING_CTR)0) //如果该函数在中断中被调用{OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_MSG, //将消息先发布到中断消息队列(void *)p_tcb,(void *)p_void,(OS_MSG_SIZE)msg_size,(OS_FLAGS )0,(OS_OPT )opt,(CPU_TS )ts,(OS_ERR *)p_err); (6)return; //返回} #endifOS_TaskQPost(p_tcb, //将消息直接发布p_void,msg_size,opt,ts,p_err); (7) } #endif(1)目标任务。(2)任务消息内容指针。(3)任务消息的大小。(4)发送的选项。(5)用于保存返回的错误类型。(6)如果启用了中断延迟发布并且如果该函数在中断中被调用就先将消息先发布到中断消息队列。(7)调用OS_TaskQPost()函数将消息直接发送其源码具体如下 #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(); //使用到临界段在关/开中断时时必须用到该宏该宏声明和//定义一个局部变量用于保存关中断前的 CPU 状态寄存器// SR临界段关中断只需保存SR开中断时将该值还原。OS_CRITICAL_ENTER(); //进入临界段if (p_tcb (OS_TCB *)0) (1)//如果 p_tcb 为空{p_tcb OSTCBCurPtr; //目标任务为自身}*p_err OS_ERR_NONE; //错误类型为“无错误”switch (p_tcb-TaskState) (2)//根据任务状态分类处理{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, //把消息放入任务消息队列p_void,msg_size,opt,ts,p_err); (3)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) //如果等的是任务消息队列{OS_Post((OS_PEND_OBJ *)0, //把消息发布给目标任务p_tcb,p_void,msg_size,ts); (4)OS_CRITICAL_EXIT_NO_SCHED(); //退出临界段无调度if ((opt OS_OPT_POST_NO_SCHED) (OS_OPT)0u) //如果要调度任务{OSSched(); //调度任务}}else(5)//如果没在等待任务消息队列{OS_MsgQPut(p_tcb-MsgQ, //把消息放入任务消息队列p_void,msg_size,opt,ts,p_err);OS_CRITICAL_EXIT(); //退出临界段}break; //跳出default: (6)//如果状态超出预期OS_CRITICAL_EXIT(); //退出临界段*p_err OS_ERR_STATE_INVALID; //错误类型为“状态非法”break; //跳出} } #endif(1)如果目标任务为空则表示将任务消息释放给自己那么p_tcb就指向当前任务。(2)根据任务状态分类处理。(3)如果目标任务没等待状态就调用OS_MsgQPut()函数将消息放入队列中执行完毕就退出。(4)如果目标任务有等待状态 那就看看是不是在等待任务消息队列如果是的话调用OS_Post()函数把任务消息发送给目标任务。(5)如果任务并不是在等待任务消息队列 那么调用OS_MsgQPut()函数将消息放入任务消息队列中即可。(6)如果状态超出预期返回错误类型为“状态非法”的错误代码。 任务消息队列的发送过程是跟消息队列发送过程差不多先检查目标任务的状态如果该任务刚刚好在等待任务消息队列的消息 那么直接让任务脱离等待状态即可。 如果任务没有在等待任务消息队列的消息那么就将消息插入要发送消息的任务消息队列。 任务消息队列发送函数的使用实例具体如下 OS_ERR err;/* 发布消息到任务 AppTaskPend */ OSTaskQPost ((OS_TCB *)AppTaskPendTCB, //目标任务的控制块(void *)YeHuo μC/OS-III, //消息内容(OS_MSG_SIZE )sizeof ( YeHuo μC/OS-III ), //消息长度(OS_OPT )OS_OPT_POST_FIFO, //发布到任务消息队列的入口端(OS_ERR *)err); 2. 任务消息队列获取函数OSTaskQPend() 与OSTaskQPost()任务消息队列发送函数相对应OSTaskQPend()函数用于获取一个任务消息队列函数的参数中没有指定哪个任务获取任务消息 实际上就是当前执行的任务当任务调用了这个函数就表明这个任务需要获取任务消息OSTaskQPend()源码具体 #if OS_CFG_TASK_Q_EN 0u//如果启用了任务消息队列 void *OSTaskQPend (OS_TICK timeout, (1)//等待期限单位时钟节拍OS_OPT opt, (2) //选项OS_MSG_SIZE *p_msg_size, (3) //返回消息长度CPU_TS *p_ts, (4) //返回时间戳OS_ERR *p_err) (5) //返回错误类型 {OS_MSG_Q *p_msg_q;void *p_void;CPU_SR_ALLOC(); //使用到临界段在关/开中断时时必须用到该宏该宏声明和//定义一个局部变量用于保存关中断前的 CPU 状态寄存器// SR临界段关中断只需保存SR开中断时将该值还原。#ifdef OS_SAFETY_CRITICAL//如果启用默认禁用了安全检测if (p_err (OS_ERR *)0) //如果错误类型实参为空{OS_SAFETY_CRITICAL_EXCEPTION(); //执行安全检测异常函数return ((void *)0); //返回0有错误停止执行} #endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN 0u//如果启用了中断中非法调用检测if (OSIntNestingCtr (OS_NESTING_CTR)0) //如果该函数在中断中被调用{*p_err OS_ERR_PEND_ISR; //错误类型为“在中断中中止等待”return ((void *)0); //返回0有错误停止执行} #endif#if OS_CFG_ARG_CHK_EN 0u//如果启用了参数检测if (p_msg_size (OS_MSG_SIZE *)0) //如果 p_msg_size 为空{*p_err OS_ERR_PTR_INVALID; //错误类型为“指针不可用”return ((void *)0); //返回0有错误停止执行}switch (opt) //根据选项分类处理{case OS_OPT_PEND_BLOCKING: //如果选项在预期内case OS_OPT_PEND_NON_BLOCKING:break; //直接跳出default: //如果选项超出预期*p_err OS_ERR_OPT_INVALID; //错误类型为“选项非法”return ((void *)0); //返回0有错误停止执行} #endifif (p_ts ! (CPU_TS *)0) //如果 p_ts 非空{*p_ts (CPU_TS )0; //初始化清零p_ts待用于返回时间戳}CPU_CRITICAL_ENTER(); //关中断p_msg_q OSTCBCurPtr-MsgQ; (6)//获取当前任务的消息队列p_void OS_MsgQGet(p_msg_q, //从队列里获取一个消息p_msg_size,p_ts,p_err); (7)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(); //开中断return (p_void); //返回消息内容}/* 如果获取消息不成功队列里没有消息 */ (8)if ((opt OS_OPT_PEND_NON_BLOCKING) ! (OS_OPT)0) //如果选择了不阻塞任务{*p_err OS_ERR_PEND_WOULD_BLOCK; //错误类型为“缺乏阻塞”CPU_CRITICAL_EXIT(); //开中断return ((void *)0); //返回0有错误停止执行}else(9)//如果选择了阻塞任务{if (OSSchedLockNestingCtr (OS_NESTING_CTR)0) //如果调度器被锁{CPU_CRITICAL_EXIT(); //开中断*p_err OS_ERR_SCHED_LOCKED; //错误类型为“调度器被锁”return ((void *)0); //返回0有错误停止执行}}/* 如果调度器未被锁 */OS_CRITICAL_ENTER_CPU_EXIT(); (10)//锁调度器重开中断OS_Pend((OS_PEND_DATA *)0, (11)//阻塞当前任务等待消息(OS_PEND_OBJ *)0,(OS_STATE )OS_TASK_PEND_ON_TASK_Q,(OS_TICK )timeout);OS_CRITICAL_EXIT_NO_SCHED(); //解锁调度器无调度OSSched(); (12)//调度任务/* 当前任务获得消息队列的消息得以继续运行 */CPU_CRITICAL_ENTER(); (13)//关中断switch (OSTCBCurPtr-PendStatus) //根据任务的等待状态分类处理{case OS_STATUS_PEND_OK: (14)//如果任务已成功获得消息p_void OSTCBCurPtr-MsgPtr; //提取消息内容地址*p_msg_size OSTCBCurPtr-MsgSize; //提取消息长度if (p_ts ! (CPU_TS *)0) //如果 p_ts 非空{*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: (15)//如果等待被中止p_void (void *)0; //返回消息内容为空*p_msg_size (OS_MSG_SIZE)0; //返回消息大小为0if (p_ts ! (CPU_TS *)0) //如果 p_ts 非空{*p_ts (CPU_TS )0; //清零 p_ts}*p_err OS_ERR_PEND_ABORT; //错误类型为“等待被中止”break; //跳出case OS_STATUS_PEND_TIMEOUT: (16)//如果等待超时default: //或者任务状态超出预期。p_void (void *)0; //返回消息内容为空*p_msg_size (OS_MSG_SIZE)0; //返回消息大小为0if (p_ts ! (CPU_TS *)0) //如果 p_ts 非空{*p_ts OSTCBCurPtr-TS;}*p_err OS_ERR_TIMEOUT; //错误类为“等待超时”break; //跳出}CPU_CRITICAL_EXIT(); //开中断return (p_void); (17)//返回消息内容地址 } #endif(1)指定超时时间单位时钟节拍。(2)获取任务消息队列的选项。(3)返回消息大小。(4)返回时间戳。(5)返回错误类型。(6)获取当前任务的消息队列保存在p_msg_q变量中。(7)调用OS_MsgQGet()函数从消息队列获取一个消息如果获取消息成功则返回指向消息的指针。(8)如果获取消息不成功任务消息队列里没有消息 并且如果用户选择了不阻塞任务那么返回错误类型为“缺乏阻塞”的错误代码然后退出。(9)如果选择了阻塞任务先判断一下调度器是否被锁如果被锁了也就不能继续执行。(10)如果调度器未被锁系统会锁调度器重开中断。(11)调用OS_Pend()函数将当前任务脱离就绪列表 并根据用户指定的阻塞时间插入节拍列表但是不会插入队列等待列表然后打开调度器但不进行调度OS_Pend()源码具体见代码清单18‑18。(12)进行一次任务调度。(13)程序能执行到这里就说明大体上有两种情况 要么是任务获取到消息了任务还没获取到消息任务没获取到消息的情况有很多种无论是哪种情况都先把中断关掉再说然后根据当前运行任务的等待状态分类处理。(14)如果任务状态是OS_STATUS_PEND_OK 则表示任务获取到消息了那么就从任务控制块中提取消息这是因为在发送消息给任务的时候会将消息放入任务控制块的MsgPtr成员变量中 然后继续提取消息大小如果p_ts非空记录获取任务等到消息时的时间戳返回错误类型为“无错误”的错误代码跳出switch语句。(15)如果任务在等待阻塞重被中止 则返回消息内容为空返回消息大小为0返回错误类型为“等待被中止”的错误代码跳出switch语句。(16)如果任务等待阻塞超时说明等待的时间过去了 任务也没获取到消息则返回消息内容为空返回消息大小为0返回错误类型为“等待超时”的错误代码跳出switch语句。(17)打开中断返回消息内容。 3、任务消息队列实验 任务通知代替消息队列是在ΜC/OS中创建了两个任务其中一个任务是用于接收任务消息另一个任务发送任务消息。 两个任务独立运行发送消息任务每秒发送一次任务消息接收任务在就一直在等待消息 一旦获取到消息通知就把消息打印在串口调试助手里具体如下 #include includes.hstatic OS_TCB AppTaskStartTCB; //任务控制块 static OS_TCB AppTaskPostTCB; static OS_TCB AppTaskPendTCB; static CPU_STK AppTaskStartStk[APP_TASK_START_STK_SIZE]; //任务栈 static CPU_STK AppTaskPostStk [ APP_TASK_POST_STK_SIZE ]; static CPU_STK AppTaskPendStk [ APP_TASK_PEND_STK_SIZE ]; static void AppTaskStart ( void *p_arg); //任务函数声明 static void AppTaskPost ( void * p_arg ); static void AppTaskPend ( void * p_arg );int main (void) {OS_ERR err;OSInit(err); //初始化 μC/OS/* 创建起始任务 */OSTaskCreate((OS_TCB *)AppTaskStartTCB,//任务控制块地址(CPU_CHAR *)App Task Start, //任务名称(OS_TASK_PTR ) AppTaskStart, //任务函数(void *) 0,//传递给任务函数形参p_arg的实参(OS_PRIO ) APP_TASK_START_PRIO, //任务的优先级(CPU_STK *)AppTaskStartStk[0],//任务栈的基地址(CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10,//任务栈空间剩下1/10时限制其增长(CPU_STK_SIZE) APP_TASK_START_STK_SIZE,//任务栈空间单位sizeof(CPU_STK)(OS_MSG_QTY ) 5u,//任务可接收的最大消息数(OS_TICK ) 0u,//任务的时间片节拍数0表默认值OSCfg_TickRate_Hz/10(void *) 0,//任务扩展0表不扩展(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),//任务选项(OS_ERR *)err); //返回错误类型OSStart(err);//启动多任务管理交由μC/OS-III控制 }static void AppTaskStart (void *p_arg) {CPU_INT32U cpu_clk_freq;CPU_INT32U cnts;OS_ERR err;(void)p_arg;BSP_Init(); //板级初始化CPU_Init(); //初始化 CPU组件时间戳、关中断时间测量和主机名cpu_clk_freq BSP_CPU_ClkFreq();//获取 CPU内核时钟频率SysTick 工作时钟cnts cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;//根据用户设定的时钟节拍频率计算 SysTick 定时器的计数值OS_CPU_SysTickInit(cnts); //调用 SysTick初始化函数设置定时器计数值和启动定时器Mem_Init();//初始化内存管理组件堆内存池和内存池表#if OS_CFG_STAT_TASK_EN 0u//如果启用默认启用了统计任务OSStatTaskCPUUsageInit(err);#endifCPU_IntDisMeasMaxCurReset();//复位清零当前最大关中断时间/* 创建 AppTaskPost 任务 */OSTaskCreate((OS_TCB *)AppTaskPostTCB,//任务控制块地址(CPU_CHAR *)App Task Post, //任务名称(OS_TASK_PTR ) AppTaskPost, //任务函数(void *) 0,//传递给任务函数形参p_arg的实参(OS_PRIO ) APP_TASK_POST_PRIO, //任务的优先级(CPU_STK *)AppTaskPostStk[0],//任务栈的基地址(CPU_STK_SIZE) APP_TASK_POST_STK_SIZE / 10,//任务栈空间剩下1/10时限制其增长(CPU_STK_SIZE) APP_TASK_POST_STK_SIZE,//任务栈空间单位sizeof(CPU_STK)(OS_MSG_QTY ) 5u,//任务可接收的最大消息数(OS_TICK ) 0u,//任务的时间片节拍数0表默认值OSCfg_TickRate_Hz/10(void *) 0,//任务扩展0表不扩展(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),(OS_ERR *)err); //返回错误类型/* 创建 AppTaskPend 任务 */OSTaskCreate((OS_TCB *)AppTaskPendTCB,//任务控制块地址(CPU_CHAR *)App Task Pend, //任务名称(OS_TASK_PTR ) AppTaskPend, //任务函数(void *) 0,//传递给任务函数形参p_arg的实参(OS_PRIO ) APP_TASK_PEND_PRIO, //任务的优先级(CPU_STK *)AppTaskPendStk[0],//任务栈的基地址(CPU_STK_SIZE) APP_TASK_PEND_STK_SIZE / 10,//任务栈空间剩下1/10时限制其增长(CPU_STK_SIZE) APP_TASK_PEND_STK_SIZE,//任务栈空间单位sizeof(CPU_STK)(OS_MSG_QTY ) 50u,//任务可接收的最大消息数(OS_TICK ) 0u,//任务的时间片节拍数0表默认值OSCfg_TickRate_Hz/10(void *) 0,//任务扩展0表不扩展(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任务选项(OS_ERR *)err); //返回错误类型OSTaskDel ( AppTaskStartTCB, err );//删除起始任务本身该任务不再运行}static void AppTaskPost ( void * p_arg ) {OS_ERR err;(void)p_arg;while (DEF_TRUE) //任务体{/* 发送消息到任务 AppTaskPend */OSTaskQPost ((OS_TCB *)AppTaskPendTCB, //目标任务的控制块(void *)Fire μC/OS-III, //消息内容(OS_MSG_SIZE )sizeof( Fire μC/OS-III ), //消息长度(OS_OPT )OS_OPT_POST_FIFO,//发送到任务消息队列的入口端(OS_ERR *)err); //返回错误类型OSTimeDlyHMSM ( 0, 0, 1, 0, OS_OPT_TIME_DLY, err );} }static void AppTaskPend ( void * p_arg ) {OS_ERR err;OS_MSG_SIZE msg_size;CPU_TS ts;CPU_INT32U cpu_clk_freq;CPU_SR_ALLOC();char * pMsg;(void)p_arg;cpu_clk_freq BSP_CPU_ClkFreq();//获取CPU时钟时间戳是以该时钟计数while (DEF_TRUE) //任务体{/* 阻塞任务等待任务消息 */pMsg OSTaskQPend ((OS_TICK )0, //无期限等待(OS_OPT )OS_OPT_PEND_BLOCKING, //没有消息就阻塞任务(OS_MSG_SIZE *)msg_size, //返回消息长度(CPU_TS *)ts,//返回消息被发送的时间戳(OS_ERR *)err); //返回错误类型ts OS_TS_GET() - ts;//计算消息从发送到被接收的时间差macLED1_TOGGLE (); //切换LED1的亮灭状态OS_CRITICAL_ENTER();//进入临界段避免串口打印被打断printf ( \r\n接收到的消息的内容为%s长度是%d字节。,pMsg, msg_size );printf ( \r\n任务消息从被发送到被接收的时间差是%dus\r\n,ts / ( cpu_clk_freq / 1000000 ) );OS_CRITICAL_EXIT(); //退出临界段}}4、任务消息队列实验现象 打开串口调试助手然后复位开发板就可以在调试助手中看到串口的运行打印信息 具体见图
http://www.pierceye.com/news/726652/

相关文章:

  • 信息网站 模板中国建设银行手机银行下载官方网站
  • 番禺网站开发设计小程序后端数据库搭建
  • 丰都集团网站建设云南网站开发公司
  • 赶集网的二级域名网站怎么做海南网站建设报价方案
  • dede做手机网站网站开发小作业
  • 网站建设推广ppt室内设计知名网站
  • asp 网站源码网站搭建好了怎么上到服务器
  • 网站有什么到期wordpress怎么编辑保存
  • 服务器添加网站300500启迪设计
  • 上海市建设安全协会网站移动端页面
  • 手机做网站公司成都住房和城乡建设厅官网
  • 锋创科技园网站建设网站开发ide php
  • 山东做网站的公司有哪些电脑怎么制作视频短片
  • 书画网站 建站维护网站成本
  • 什么事网站开发网站服务器租用报价
  • 做黏土的网站青岛网站建设微动力
  • 建网站权威公司广告发布平台
  • 自助游网站开发分析报告总结怎么注册公司微信公众号
  • 网站开发公司业务员培训黄聪wordpress
  • 网站规划与建设ppt模板下载响应式网站模板费用
  • 江苏商城网站建设服务网站建设优化石家庄
  • 高师院校语言类课程体系改革与建设 教学成果奖申报网站wordpress 4.8.2 漏洞
  • 以小说名字做网站的小说网wordpress的数据库主机
  • 永嘉高端网站建设价格h5页面制作多少钱
  • 北京网站建设课程培训WordPress分类id在哪
  • 宁夏网站备案青岛专业网站建设公司
  • 廊坊营销网站团队佛山市创意动力信息科技有限公司
  • 怎么学习做网站网络公司 网站建设
  • 网站权重怎么提升网站开发多线程开发
  • wordpress下拉列表沈阳网站排名优化