笔记之uC/OS 多任务机制OSTaskCreate()
想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与uC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。
任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。任务不能由中断服务程序(ISR)来建立。
OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,OSTaskCreate()需要四个参数:
task是任务代码的指针,
pdata是当任务开始执行时传递给任务的参数的指针,
ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),
prio是分配给任务的优先级。
OSTaskCreate函数源码
- //建立一个新任务
- #if OS_TASK_CREATE_EN > 0 //允许生成OSTaskCreate()函数
- INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
- {
- #if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3
- OS_CPU_SR cpu_sr;
- #endif
- OS_STK *psp; //初始化任务堆栈指针变量,返回新的栈顶指针
- INT8U err; //定义(获得并定义初始化任务控制块)是否成功
- #if OS_ARG_CHK_EN > 0 //所有参数必须在指定的参数内
- if (prio > OS_LOWEST_PRIO) { //检查任务优先级是否合法
- return (OS_PRIO_INVALID); //参数指定的优先级大于OS_LOWEST_PRIO
- }
- #endif
- OS_ENTER_CRITICAL(); //关闭中断
- if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0
- OSTCBPrioTbl[prio] = (OS_TCB *)1; //保留这个优先级,将就绪态设为1
- OS_EXIT_CRITICAL(); //打开中断
- psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); //初始化任务堆栈
- err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); //获得并初始化任务控制块
- if (err == OS_NO_ERR) { //任务控制初始化成功
- OS_ENTER_CRITICAL(); //关闭中断
- OSTaskCtr++; //任务计数器加1
- OS_EXIT_CRITICAL(); //打开中断
- if (OSRunning == TRUE) { //检查是否有(某个)任务在运行
- OS_Sched(); //任务调度,最高任务优先级运行
- }
- } else { //否则,任务初始化失败
- OS_ENTER_CRITICAL(); //关闭中断
- OSTCBPrioTbl[prio] = (OS_TCB *)0; //放弃任务,设此任务就绪态为0
- OS_EXIT_CRITICAL(); //打开中断
- }
- return (err); //返回(获得并定义初始化任务控制块是否成功)
- }
- OS_EXIT_CRITICAL(); //打开中断
- return (OS_PRIO_EXIST); //返回(具有该优先级的任务已经存在)
- }
- #endif
OSTaskCreate函数源码解析
OSTaskCreate()一开始先检测分配给任务的优先级是否有效[L4.1(1)]。任务的优先级必须在0到OS_LOWEST_PRIO之间。接着,OSTaskCreate()要确保在规定的优先级上还没有建立任务[L4.1(2)]。在使用UC/OS-Ⅱ时,每个任务都有特定的优先级。如果某个优先级是空闲的,UC/OS-Ⅱ通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级[L4.1(3)]。这就使得OSTaskCreate()在设置任务数据结构的其他部分时能重新允许中断[L4.1(4)]。
然后,OSTaskCreate()调用OSTaskStkInit()[L4.1(5)],它负责建立任务的堆栈。该函数是与处理器的硬件体系相关的函数,可以在OS_CPU_C.C文件中找到。有关实现OSTaskStkInit()的细节可参看第8章——移植UC/OS-Ⅱ。如果已经有人在你用的处理器上成功地移植了UC/OS-Ⅱ,而你又得到了他的代码,就不必考虑该函数的实现细节了。OSTaskStkInit()函数返回新的堆栈栈顶(psp),并被保存在任务的0S_TCB中。注意用户得将传递给OSTaskStkInit()函数的第四个参数opt置0,因为OSTaskCreate()与OSTaskCreateExt()不同,它不支持用户为任务的创建过程设置不同的选项,所以没有任何选项可以通过opt参数传递给OSTaskStkInit()。
UC/OS-Ⅱ支持的处理器的堆栈既可以从上(高地址)往下(低地址)递减也可以从下往上递增。用户在调用OSTaskCreate()的时候必须知道堆栈是递增的还是递减的(参看所用处理器的OS_CPU.H中的OS_STACK_GROWTH),因为用户必须得把堆栈的栈顶传递给OSTaskCreate(),而栈顶可能是堆栈的最高地址(堆栈从上往下递减),也可能是最低地址(堆栈从下往上长)。
一旦OSTaskStkInit()函数完成了建立堆栈的任务,OSTaskCreate()就调用OSTCBInit()[L4.1(6)],从空闲的OS_TCB池中获得并初始化一个OS_TCB。OSTCBInit()的代码如程序清单 L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。
OSTCBInit()函数首先从OS_TCB缓冲池中获得一个OS_TCB[L4.2(1)],如果OS_TCB池中有空闲的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB被分配,该任务的创建者就已经完全拥有它了,即使这时内核又创建了其它的任务,这些新任务也不可能对已分配的OS_TCB作任何操作,所以OSTCBInit()在这时就可以允许中断,并继续初始化OS_TCB的数据单元。
OSTaskCreateExt函数源码
- //建立一个新任务。与OSTaskCreate()不同的是,OSTaskCreateExt()允许用户设置更多的细节
- //内容。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立,但中断处理
- //程序中不能建立新任务。一个任务必须为无限循环结构,且不能有返回点。
- #if OS_TASK_CREATE_EXT_EN > 0 //允许生成OSTaskCreateExt()函数
- INT8U OSTaskCreateExt (void (*task)(void *pd), //建立扩展任务(任务代码指针)
- void *pdata, //传递参数指针
- OS_STK *ptos, //分配任务堆栈栈顶指针
- INT8U prio, //分配任务优先级
- INT16U id, //(未来的)优先级标识(与优先级相同)
- OS_STK *pbos, //分配任务堆栈栈底指针
- INT32U stk_size, //指定堆栈的容量(检验用)
- void *pext, //指向用户附加的数据域的指针
- INT16U opt) //建立任务设定选项
- {
- #if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3
- OS_CPU_SR cpu_sr;
- #endif
- OS_STK *psp; //初始化任务堆栈指针变量,返回新的栈顶指针
- INT8U err; //定义(获得定义初始化任务控制块)是否成功
- #if OS_ARG_CHK_EN > 0 //所有参数必须在指定的参数内
- if (prio > OS_LOWEST_PRIO) { //检查任务优先级是否合法
- return (OS_PRIO_INVALID); //参数指定的优先级大于OS_LOWEST_PRIO
- }
- #endif
- OS_ENTER_CRITICAL(); //关闭中断
- if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //确认优先级未被使用,即就绪态为0
- OSTCBPrioTbl[prio] = (OS_TCB *)1; //保留这个优先级,将就绪态设为0
- OS_EXIT_CRITICAL(); //打开中断
- //以下两为1堆栈才能清0
- if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || //检验任务堆栈,CHK=1
- ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) { //任务建立时是否清0,CLR=1
- #if OS_STK_GROWTH == 1 //堆栈生长方向
- (void)memset(pbos, 0, stk_size * sizeof(OS_STK)); //从下向上递增
- #else
- (void)memset(ptos, 0, stk_size * sizeof(OS_STK)); //从下向下递减
- #endif
- }
- psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); //初始化任务堆栈
- err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt); //获得并初始化任务控制块
- if (err == OS_NO_ERR) { //任务控制初始化成功
- OS_ENTER_CRITICAL(); //关闭中断
- OSTaskCtr++; //任务计数器加1
- OS_EXIT_CRITICAL(); //打开中断
- if (OSRunning == TRUE) { //检查是否有(某个)任务在运行
- OS_Sched(); //任务调度,最高任务优先级运行
- }
- } else { //否则,任务初始化失败
- OS_ENTER_CRITICAL(); //关闭中断
- OSTCBPrioTbl[prio] = (OS_TCB *)0; //放弃任务,设此任务就绪态为0
- OS_EXIT_CRITICAL(); //打开中断
- }
- return (err); //返回(获得并定义初始化任务控制块是否成功)
- }
- OS_EXIT_CRITICAL(); //打开中断
- return (OS_PRIO_EXIST); //具有该优先级的任务已经存在
- }
- #endif
http://blog.csdn.net/liuhui_8989/article/details/8781407
笔记之uC/OS 多任务机制OSTaskCreate()相关推荐
- uc/OS II——多任务设计
uc/OS II--多任务设计 (1)设计 开始任务 [1]/声明 开始任务 任务块 static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE]; ...
- uC/OS任务创建函数OSTaskCreate ()参数详解
要使用 uC/OS 的任务必须先声明任务控制块和创建任务,调用 OSTaskCreate () 函数可以创建一个任务.OSTaskCreate () 函数的信息如下表所示.
- 将uc/OS移植到stm32F103上
将uc/OS移植到stm32F103上 一.嵌入式实时操作系统(RTOS) 1.定义 2.实时任务 3.特征 二.使用CubeMX建立STM32F103C8T6HAL库 三.移植uC/OS-III 四 ...
- uC/OS 的进程调度(上)
操作系统最重要的任务之一就是进程调度,它涉及三个主要方面: 何时进行调度 如何选择下一个活动进程 如何实现进程切换 每种操作系统差别很大,本文对uC/OS的进程调度机制进行一些细致分析. 何时进行调度 ...
- uc/os学习之路(一) —— 初识uc/os
初识实时操作系统 实时操作系统是指当外界事件或数据产生时,能在规定的时间内进行处理并作出相应.实时操作系统有一下基本特征: 多任务操作系统 多级中断机制 优先调度机制 现广泛使用的实时操作系统有很多种 ...
- 嵌入式系统 操作系统 uC/OS uClinux
摘要:嵌入式操作系统是嵌入式系统应用的核心软件.本文通过对两种典型的开源嵌入式操作系统的对比,分析和总结嵌入式操作系统应用中的若干问题,归纳嵌入式操作系统的选型依据. 关键词:嵌入式系统 操作系统 u ...
- STM32F103C8T6移植uc/OS
STM32F103C8T6移植uc/OS STM32F103C8T6移植uc/OS STM32F103C8T6移植uc/OS 一.题目要求 二.使用STM32CubeMX建立HAL库 三.准备uCOS ...
- -uc/OS系统移植(基于STM32F103C8T6,超详细讲解)
完成STM32F103C8基于HAL库的-uc/OS系统移植 一.创建HAL库 二.下载uc/OSIII源码及移植准备 1.下载uc/OSIII源码 2.将uc/OS源码文件复制到工程 三.将uc/O ...
- 基于STM32的uc/OS系统移植及用Saleae Logic 16抓取分析波形
文章目录 一.关于uc/OS系统 1.操作系统与裸机的区别 2.uc/OS运行流程 二.详细移植过程 1.STM32Cubex创建工程 2.为工程添加源码 3.添加头文件路径 4.添加代码 1)bsp ...
最新文章
- Java双向链表快速排序_双向链表的插入,删除,以及链表的快速排序
- C#中使用OpenGL(API)创建OpenGL渲染环境
- 《大话设计模式》 国外资料
- 学习笔记(14):Python网络编程并发编程-文件传输功能实现
- 中科院博士返乡卖汉服:3个月卖了300万,预计全年能破1500万
- cuda笔记-GPU多线程的奇偶排序
- LINQ to DataSet
- 如何让oracle用户不过期,Oracle用户密码设为不过期的两种方法
- OpenGL(5)——变换
- 批处理批量更改文件名并排序
- 基于xxtea算法文件加密工具
- 职称计算机2015年,2015年职称计算机考试题库最新版.doc
- gabor滤波器matlab实现,使用matlab实现Gabor滤波器
- 最新AZ自动发卡网源码-全网首发
- 磁盘压缩卷只能压缩一半
- 计算机组成实验箱控制信号测,计算机组成原理实验报告-杨睿.doc
- php编写六十甲子纳音表_史上最完整的六十甲子纳音表详细说明
- php函数阅读,[PHP源码阅读]strtolower和strtoupper函数
- 进阶1·调用高德API获取交通数据(多个URL访问,字典提取,while无限循环下的程序间断运行)
- Greedy——HDOJ 1789