UCOS操作系统——任务的挂起与恢复(四)
UCOS操作系统
文章目录
- UCOS操作系统
- 前言
- 一、任务挂起OSTaskSuspend()函数
- 二、任务恢复 OSTaskResume()函数
- 三、完整代码
- 总结
前言
任务的删除是直接删除这个任务,以后都不在执行,但是我要是想等某一个状态触发了继续执行怎么办,这个时候就轮到任务的挂起与恢复发挥作用了。
一、任务挂起OSTaskSuspend()函数
有时候有些任务因为某些原因需要暂停运行,但是以后还要运行,因此我们就不能删除掉任务,这里我们可以使用 OSTaskSuspend()函数挂起这个任务,以后再恢复运行,函数OSTaskSuspend()的原型如下:
void OSTaskSuspend (OS_TCB *p_tcb,OS_ERR *p_err)
*p_tcb : 指向需要挂起的任务的 OS_TCB,可以通过指向一个 NULL 指针将调用该函数的任务挂起。
*p_err: 指向一个变量,用来保存该函数的错误码。
我们可以多次调用 OSTaskSuspend ()函数来挂起一个任务,因此我们需要调用同样次数的OSTaskResume()函数才可以恢复被挂起的任务,这一点非常重要。意思是挂起一次,然后需要解挂一次,你可以再次挂起,然后再次解挂。
二、任务恢复 OSTaskResume()函数
OSTaskResume()函数用来恢复被 OSTaskSuspend()函数挂起的任务,OSTaskResume()函数是唯一能恢复被挂起任务的函数。如果被挂起的任务还在等待别的内核对象,比如事件标志组、信号量、互斥信号量、消息队列等,即使使用 OSTaskResume()函数恢复了被挂起的任务,该任务也不一定能立即运行,该任务还是要等相应的内核对象,只有等到内核对象后才可以继续运行,OSTaskResume()函数原型如下:
void OSTaskResume (OS_TCB *p_tcb,OS_ERR *p_err)
*p_tcb : 指向需要解挂的任务的 OS_TCB,指向一个 NULL 指针是无效的,因为该任务正在运行,不需要解挂。
*p_err: 指向一个变量,用来保存该函数的错误码。
三、完整代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "includes.h"//ÈÎÎñÓÅÏȼ¶
#define START_TASK_PRIO 3
//ÈÎÎñ¶ÑÕ»´óС
#define START_STK_SIZE 128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB StartTaskTCB;
//ÈÎÎñ¶ÑÕ»
CPU_STK START_TASK_STK[START_STK_SIZE];
//ÈÎÎñº¯Êý
void start_task(void *p_arg);//ÈÎÎñÓÅÏȼ¶
#define TASK1_TASK_PRIO 4
//ÈÎÎñ¶ÑÕ»´óС
#define TASK1_STK_SIZE 128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB Task1_TaskTCB;
//ÈÎÎñ¶ÑÕ»
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
void task1_task(void *p_arg);//ÈÎÎñÓÅÏȼ¶
#define TASK2_TASK_PRIO 5
//ÈÎÎñ¶ÑÕ»´óС
#define TASK2_STK_SIZE 128
//ÈÎÎñ¿ØÖÆ¿é
OS_TCB Task2_TaskTCB;
//ÈÎÎñ¶ÑÕ»
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
//ÈÎÎñº¯Êý
void task2_task(void *p_arg);//LCDË¢ÆÁʱʹÓõÄÑÕÉ«
int lcd_discolor[14]={ WHITE, BLACK, BLUE, BRED, GRED, GBLUE, RED, MAGENTA, GREEN, CYAN, YELLOW,BROWN, BRRED, GRAY };//Ö÷º¯Êý
int main(void)
{OS_ERR err;CPU_SR_ALLOC();delay_init(); //ʱÖÓ³õʼ»¯NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÖжϷÖ×éÅäÖÃuart_init(115200); //´®¿Ú³õʼ»¯LED_Init(); //LED³õʼ»¯ LCD_Init(); //LCD³õʼ»¯ POINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"ALIENTEK STM32F1"); LCD_ShowString(30,30,200,16,16,"UCOSIII Examp 6-2");LCD_ShowString(30,50,200,16,16,"Task Suspend and Resume");LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");LCD_ShowString(30,90,200,16,16,"2015/3/19");OSInit(&err); //³õʼ»¯UCOSIIIOS_CRITICAL_ENTER(); //½øÈëÁÙ½çÇø //´´½¨¿ªÊ¼ÈÎÎñOSTaskCreate((OS_TCB * )&StartTaskTCB, //ÈÎÎñ¿ØÖÆ¿é(CPU_CHAR * )"start task", //ÈÎÎñÃû×Ö(OS_TASK_PTR )start_task, //ÈÎÎñº¯Êý(void * )0, //´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý(OS_PRIO )START_TASK_PRIO, //ÈÎÎñÓÅÏȼ¶(CPU_STK * )&START_TASK_STK[0], //ÈÎÎñ¶ÑÕ»»ùµØÖ·(CPU_STK_SIZE)START_STK_SIZE/10, //ÈÎÎñ¶ÑÕ»Éî¶ÈÏÞλ(CPU_STK_SIZE)START_STK_SIZE, //ÈÎÎñ¶ÑÕ»´óС(OS_MSG_QTY )0, //ÈÎÎñÄÚ²¿ÏûÏ¢¶ÓÁÐÄܹ»½ÓÊÕµÄ×î´óÏûÏ¢ÊýÄ¿,Ϊ0ʱ½ûÖ¹½ÓÊÕÏûÏ¢(OS_TICK )0, //µ±Ê¹ÄÜʱ¼äƬÂÖתʱµÄʱ¼äƬ³¤¶È£¬Îª0ʱΪĬÈϳ¤¶È£¬(void * )0, //Óû§²¹³äµÄ´æ´¢Çø(OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //ÈÎÎñÑ¡Ïî(OS_ERR * )&err); //´æ·Å¸Ãº¯Êý´íÎóʱµÄ·µ»ØÖµOS_CRITICAL_EXIT(); //Í˳öÁÙ½çÇø OSStart(&err); //¿ªÆôUCOSIII
}//¿ªÊ¼ÈÎÎñÈÎÎñº¯Êý
void start_task(void *p_arg)
{OS_ERR err;CPU_SR_ALLOC();p_arg = p_arg;CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0uOSStatTaskCPUUsageInit(&err); //ͳ¼ÆÈÎÎñ
#endif#ifdef CPU_CFG_INT_DIS_MEAS_EN //Èç¹ûʹÄÜÁ˲âÁ¿ÖжϹرÕʱ¼äCPU_IntDisMeasMaxCurReset();
#endif#if OS_CFG_SCHED_ROUND_ROBIN_EN //µ±Ê¹ÓÃʱ¼äƬÂÖתµÄʱºò//ʹÄÜʱ¼äƬÂÖתµ÷¶È¹¦ÄÜ,ʱ¼äƬ³¤¶ÈΪ1¸öϵͳʱÖÓ½ÚÅÄ£¬¼È1*5=5msOSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endifOS_CRITICAL_ENTER(); //½øÈëÁÙ½çÇø//´´½¨TASK1ÈÎÎñOSTaskCreate((OS_TCB * )&Task1_TaskTCB, (CPU_CHAR * )"Task1 task", (OS_TASK_PTR )task1_task, (void * )0, (OS_PRIO )TASK1_TASK_PRIO, (CPU_STK * )&TASK1_TASK_STK[0], (CPU_STK_SIZE)TASK1_STK_SIZE/10, (CPU_STK_SIZE)TASK1_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); //´´½¨TASK2ÈÎÎñOSTaskCreate((OS_TCB * )&Task2_TaskTCB, (CPU_CHAR * )"task2 task", (OS_TASK_PTR )task2_task, (void * )0, (OS_PRIO )TASK2_TASK_PRIO, (CPU_STK * )&TASK2_TASK_STK[0], (CPU_STK_SIZE)TASK2_STK_SIZE/10, (CPU_STK_SIZE)TASK2_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); OS_CRITICAL_EXIT(); //Í˳öÁÙ½çÇøOSTaskDel((OS_TCB*)0,&err); //ɾ³ýstart_taskÈÎÎñ×ÔÉí
}//task1ÈÎÎñº¯Êý
void task1_task(void *p_arg)
{u8 task1_num=0;OS_ERR err;CPU_SR_ALLOC();p_arg = p_arg;POINT_COLOR = BLACK;OS_CRITICAL_ENTER();LCD_DrawRectangle(5,110,115,314); //»Ò»¸ö¾ØÐÎ LCD_DrawLine(5,130,115,130); //»ÏßPOINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,"Task1 Run:000");OS_CRITICAL_EXIT();while(1){task1_num++; //ÈÎÎñ1Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num1¼Óµ½255µÄʱºò»áÇåÁ㣡£¡LED0= ~LED0;printf("ÈÎÎñ1ÒѾִÐУº%d´Î\r\n",task1_num);if(task1_num==5) {OSTaskSuspend((OS_TCB*)&Task2_TaskTCB,&err);//ÈÎÎñ1Ö´ÐÐ5´Îºó¹ÒÆðÈÎÎñ2printf("ÈÎÎñ1¹ÒÆðÁËÈÎÎñ2!\r\n");}if(task1_num==10) {OSTaskResume((OS_TCB*)&Task2_TaskTCB,&err); //ÈÎÎñ1ÔËÐÐ10´Îºó»Ö¸´ÈÎÎñ2printf("ÈÎÎñ1»Ö¸´ÁËÈÎÎñ2!\r\n");}LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //Ìî³äÇøÓòLCD_ShowxNum(86,111,task1_num,3,16,0x80); //ÏÔʾÈÎÎñÖ´ÐдÎÊýOSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s}
}//task2ÈÎÎñº¯Êý
void task2_task(void *p_arg)
{u8 task2_num=0;OS_ERR err;CPU_SR_ALLOC();p_arg = p_arg;POINT_COLOR = BLACK;OS_CRITICAL_ENTER();LCD_DrawRectangle(125,110,234,314); //»Ò»¸ö¾ØÐÎ LCD_DrawLine(125,130,234,130); //»ÏßPOINT_COLOR = BLUE;LCD_ShowString(126,111,110,16,16,"Task2 Run:000");OS_CRITICAL_EXIT();while(1){task2_num++; //ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡LED1=~LED1;printf("ÈÎÎñ2ÒѾִÐУº%d´Î\r\n",task2_num);LCD_ShowxNum(206,111,task2_num,3,16,0x80); //ÏÔʾÈÎÎñÖ´ÐдÎÊýLCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //Ìî³äÇøÓòOSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err); //ÑÓʱ1s}
}
任务 1 运行 5 次后调用 OSTaskSuspend()函数挂起任务 2。当任务 1 运行到第 10 次就调用函数 OSTaskResume()函数解挂任务 2。
总结
学了FreeRTOS之后在学ucos感觉很简单,其实都是相同的,只是用的函数不一样。
UCOS操作系统——任务的挂起与恢复(四)相关推荐
- STM32mini使用UCOSII信号量和邮箱实现任务挂起和恢复
本文结构 1.UCOSII原理 2.UCOSII实验代码 1.UCOSII原理 UCOSII 是一个可以基于ROM 运行的.可裁减的.抢占式.实时多任务内核,具有高度可 移植性,特别适合于微处理器和控 ...
- UCOS操作系统——信号量与互斥信号量(九)
UCOS操作系统 文章目录 UCOS操作系统 一.信号量简介 1.二进制信号量 2.计数型信号量 二.使用信号量 1.相关API函数 2.OSSemCreate()创建信号量 3.OSSemPend( ...
- UCOS操作系统——事件标志组(十四)
UCOS操作系统 文章目录 UCOS操作系统 前言 一.事件标志组 二.相关函数 1.创建事件标志组 2. 等待事件标志组 3.向事件标志组发布标志 三.事件标志组实验 前言 前面我们提到过可以使用信 ...
- 分析Kotlin协程只挂起不恢复会怎样(是否存在协程泄漏),以及挂起的协程存在哪里?
前言 刚开始正式学协程原理的时候(以前只是学api怎么用),大概是20年6月,也就是bennyhuo大佬出书<深入理解Kotlin协程>的时候,我买了本然后细细研究,我的内心就一直有一个问 ...
- 树莓派cpu检测_【树莓派3B+测评】线程的挂起与恢复CPU温度检测
[树莓派3B+测评]线程的挂起与恢复&CPU温度检测 [复制链接] 本帖最后由 donatello1996 于 2018-12-22 17:33 编辑 在TCP通信中,除了线程的创建和删除以外 ...
- Java并发编程(3):线程挂起、恢复与终止的正确方法(含代码)
挂起和恢复线程 Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的.如果在不合适的时候挂起线程(比如,锁定共享资源时),此时 ...
- (58)模拟线程切换——添加挂起、恢复线程功能
一.回顾 我们在上一篇博客分析了模拟线程切换的源码. <模拟线程切换> 我们着重分析了 Scheduling 和 SwitchContext 这两个函数,对线程切换的过程有了新的认识: 线 ...
- Java线程的挂起与恢复 wait(), notify()方法介绍
一, 什么是线程的挂起与恢复 从字面理解也很简单. 所谓线程挂起就是指暂停线程的执行(阻塞状态). 而恢复时就是让暂停的线程得以继续执行.(返回就绪状态) 二, 为何需要挂起和恢复线程. 我们来看1个 ...
- java怎么看具体被挂起的线程_Java线程的挂起、恢复和终止
有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线 ...
- 【STM32】FreeRTOS任务挂起和恢复示例
00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 执行结果 06. 附录 07. 参考 01. 概述 任务挂起和恢复,当某个任务要停止运 ...
最新文章
- elasticsearch 结构化搜索_在案例中实战基于range filter来进行范围过滤
- 关于联合利华:我的第一次正式实习的单位!撒花!
- python 中cookie_使用Python分析Cookies
- 在linux oracle 10g/11g x64bit环境中,goldengate随os启动而自己主动启动的脚本
- Spring Cloud源码分析(一)Eureka
- win8关机快捷键_关机这么简单的电脑操作,大家了解吗?
- 苹果css攻击,研究人员设计了一种新的CSS和HTML攻击 导致iPhone重启或冻结Mac
- Java进阶之路——从初级程序员到架构师,从小工到专家(转)
- 16进制储存的农历信息的正确打开方式
- 《剑指offer》重建二叉树的解法
- Windows10 怎么添加开机启动项
- ORacle异常:ORA-00980:同义词转换不再有效
- 在Linux系统下安装更换操作系统
- 企业微信批量导入用户
- 004--自找麻烦之 vue2.0
- android 视频剪切,安卓手机视频剪辑app 将视频某一段截取下来,或者删除视频中某一部分...
- 如何将域名http转换成https?
- BIMBase参数化建库软件使用手册
- Flink迟到数据处理
- Linux系统调用八、link系列API函数详解