UCOS操作系统——创建与删除任务(三)
UCOS操作系统
文章目录
- UCOS操作系统
- 一、创建任务
- 二、删除任务
一、创建任务
UCOSIII 是多任务系统,那么肯定要能创建任务,创建任务就是将任务控制块、任务堆栈、任务代码等联系在一起,并且初始化任务控制块的相应字段。在 UCOSIII 中我们通过函数OSTaskCreate()来创建任务,OSTaskCreate()函数原型如下(在 os_task.c 中有定义)。调用OSTaskCreat()创建一个任务以后,刚创建的任务就会进入就绪态,注意!不能在中断服务程序中调用 OSTaskCreat()函数来创建任务。
void OSTaskCreate (OS_TCB *p_tcb,CPU_CHAR *p_name,OS_TASK_PTR p_task,void *p_arg,OS_PRIO prio,CPU_STK *p_stk_base,CPU_STK_SIZE stk_limit,CPU_STK_SIZE stk_size,OS_MSG_QTY q_size,OS_TICK time_quanta,void *p_ext,OS_OPT opt,OS_ERR *p_err)
*p_tcb: 指向任务的任务控制块 OS_TCB。
*p_name: 指向任务的名字,我们可以给每个任务取一个名字
p_task: 执行任务代码,也就是任务函数名字
*p_arg: 传递给任务的参数
prio: 任务优先级,数值越低优先级越高,用户不能使用系统任务使用的那些优先级!
*p_stk_base:指向任务堆栈的基地址。
stk_limit: 任务堆栈的堆栈深度,用来检测和确保堆栈不溢出。
stk_size: 任务堆栈大小
q_size: UCOSIII 中每个任务都有一个可选的内部消息队列,我们要定义宏
OS_CFG_TASK_Q_EN>0,这是才会使用这个内部消息队列。
time_quanta:在使能时间片轮转调度时用来设置任务的时间片长度,默认值为时钟节拍除以
10。
*p_ext: 指向用户补充的存储区。
opt: 包含任务的特定选项,有如下选项可以设置。
OS_OPT_TASK_NONE 表示没有任何选项
OS_OPT_TASK_STK_CHK 指定是否允许检测该任务的堆栈
OS_OPT_TASK_STK_CLR 指定是否清除该任务的堆栈
OS_OPT_TASK_SAVE_FP 指定是否存储浮点寄存器,CPU 需要有浮点
运算硬件并且有专用代码保存浮点寄存器。
*p_err: 用来保存调用该函数后返回的错误码。
相应的参数可以看这个图,这里第一个参数是任务控制块要与RTOS相区分
OS_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(); //Í˳öÁÙ½çÇø
err是这个函数返回的错误码,在我们调试的时候是很方便的。
二、删除任务
OSTaskDel()函数用来删除任务,当一个任务不需要运行的话,我们就可以将其删除掉,删
除任务不是说删除任务代码,而是 UCOSIII 不再管理这个任务,在有些应用中我们只需要某个
任务只运行一次,运行完成后就将其删除掉,比如外设初始化任务,OSTaskDel()函数原型如下:
void OSTaskDel (OS_TCB *p_tcb,OS_ERR *p_err)
ucos中的任务控制块相当于RTOS中的任务句柄
*p_tcb: 指向要删除的任务 TCB,也可以传递一个 NULL 指针来删除调用 OSTaskDel()函数的任务自身。
*p_err: 指向一个变量用来保存调用 OSTaskDel()函数后返回的错误码。
1、删除某个任务以后,它占用的OS_TCB和堆栈就可以再次利用来创建其他的任务。
2、尽管UCOSIII允许在系统运行中删除任务,但是应该尽量避免这种操作,如果这个任务可能占有与其他任务共享的资源,在删除此任务之前这个被占有的资源没有被释放就有可能导致奇怪的结果。
三、完整代码
#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;OSInit(&err); //³õʼ»¯UCOSIII 初始化ucosOS_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);
#endif OS_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) {OSTaskDel((OS_TCB*)&Task2_TaskTCB,&err); //ÈÎÎñ1Ö´ÐÐ5´Ëºóɾ³ýµôÈÎÎñ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}
}
开始任务 start_task 只是用来创建任务 task1_task 和 task2_task,那么这个任务肯定只需要执行一次,两个任务创建完成以后就可以删除掉 start_task 任务了,这里我们使用 OSTaskDel()
函数删除掉任务自身,这里传递给 OSTaskDel()函数参数 p_tcb 的值为 0,表示删除掉任务自身。根据要求我们在任务 1 执行 5 次后由任务 1 删除掉任务 2,这里通过调用 OSTaskDel()函数删除掉任务 2,注意这时我们传递给 OSTaskDel()中参数 p_tcb 的值为任务 2 的任务控制块Task2_TaskTCB 的地址,因此这里我们用了取址符号“&”。
调用函数 OSTimeDlyHMSM()延时 1s,调用 OSTimeDlyHMSM()函数以后就会发起一个任务切换。
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err)延时函数第一个代表小时,然后是分钟,然后是秒钟,再然后是毫秒,这里延迟1秒,写在秒钟的位置,延时的目的是为了任务切换。这个函数内置任务切换的函数。
UCOS操作系统——创建与删除任务(三)相关推荐
- 合肥工业大学—SQL Server数据库实验三:SQL语句创建和删除基本表
SQL语句创建和删除基本表 1. 编写6个基本表 2. 修改基本表结构,完整性约束条件 3. 用Drop table 语句删除基本表 1. 编写6个基本表 设有简单教学管理的6个关系模式如下: 系(系 ...
- UCOS操作系统——信号量与互斥信号量(九)
UCOS操作系统 文章目录 UCOS操作系统 一.信号量简介 1.二进制信号量 2.计数型信号量 二.使用信号量 1.相关API函数 2.OSSemCreate()创建信号量 3.OSSemPend( ...
- UCOS操作系统——事件标志组(十四)
UCOS操作系统 文章目录 UCOS操作系统 前言 一.事件标志组 二.相关函数 1.创建事件标志组 2. 等待事件标志组 3.向事件标志组发布标志 三.事件标志组实验 前言 前面我们提到过可以使用信 ...
- Oracle数据库实例的创建、删除、修改
以SUSE10SP2.Oracle10gR2为例. 本文中的数据库实例这一称谓应该换做数据库更为准确,数据库可以理解为是一个物理的静态概念,主要包括一些物理存在的数据库文件,而数据库实例则是一个动态概 ...
- 1.4 File类(文件操作类)获取文件属性,创建和删除文件\目录,遍历目录
在 Java 中,File 类是 java.io 包中唯一代表磁盘文件本身的对象,也就是说,如果希望在程序中操作文件和目录,则都可以通过 File 类来完成.File 类定义了一些方法来操作文件,如新 ...
- STM32学习之ucos操作系统
ucos操作系统是一种实时的嵌入式操作系统,特点是源码公开,可移植,可固化,可裁剪,多任务,任务栈等等,我们想要使用ucos操作系统需要根据自己的芯片内核还有型号来下载不同版本的操作系统源码,并且移植 ...
- sun服务器删除多余文件,Sun V440服务器下如何创建、删除及恢复硬RAID 1的方法.doc...
Sun V440服务器下如何创建.删除及恢复硬RAID 1的方法 Sun V440服务器下如何创建.删除及恢复硬RAID 1的方法 在Sun Fire V440 服务器上,可以使用板载Ultra-4 ...
- 【Linux入门到精通系列讲解】Linux如何创建和删除swap分区
Linux中的swap分区类似Windows的虚拟内存,在硬盘空间不足的情况下,可通过创建swap分区来解决,下面小编就给大家介绍下Linux如何创建和删除swap分区. 文章目录 1 swap概述 ...
- VC++动态创建和删除菜单(转)
在应用程序中,往往要根据当前的操作来增加相应的菜单.动态增加菜单的方法有多 种,本文只讲述利用资源编辑器预创建菜单资源,然后在程序运行中动态加入(或删 除)到主菜单中去的方法. 一.用AppWizar ...
- 【STM32】FreeRTOS创建和删除任务示例(静态方法)(了解)
00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 结果验证 06. 附录 07. 参考 01. 概述 FreeRTOS中创建和删除任务A ...
最新文章
- [置顶] Android面试题目之二:整形转换为字符串
- 在RHEL6.6环境下进行LVS-NAT实验(Vmware模式)
- 推荐一个MDI模式的远程桌面管理程序
- mysql遇到时区问题的坑(Java解决方案)
- android opengl es 绘制位图字体
- Primes on Interval(CF-237C)
- 【华为云技术分享】Batch Normalization (BN) 介绍
- 【iOS开发】关于Xcode8后产生的viewForHeaderInSection、viewForFooterInSection设置不产生效果的问题
- java设计模式--创建模式--单例模式
- SQL必知必会 课后题答案
- 为什么一用迅雷下东西wifi就上不了网了?限速也没用
- python 高等数学_Python在高等数学中的应用
- 后台开发 vs App应用开发?
- 最新全国省市区县乡镇街道行政区划数据提取(2022年)
- Java设置时间为0时0分0秒和23时59分59秒
- 炼数成金-Spark大数据平台
- SOLIDWORKS如何建立基准面
- matlab取中间的几位数,Excel中取前几位数、中间几位数、后几位数的方法
- ArcMap制作3D地形图
- 云帆加速扶凯:坚守本源 做技术流的CDN