Genie shell for UCOS II 详细说明及使用指南
转:一步一步教你使用uCOS-II
转:⼀步⼀步教你使⽤uCOS-II第⼀篇 UCOS介绍第⼀篇 UCOS介绍这个⼤家都知道。
呵呵。
考虑到咱们学习的完整性还是在这⾥唠叨⼀下。
让⼤家再熟悉⼀下。
⾼⼿们忍耐⼀下吧! uC/OS II(Micro Control Operation System Two)是⼀个可以基于ROM运⾏的、可裁减的、抢占式、实时多任务内核,具有⾼度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。
为了提供最好的移植性能,uC/OS II最⼤程度上使⽤ANSI C语⾔进⾏开发,并且已经移植到近40多种处理器体系上,涵盖了从8位到64位各种CPU(包括DSP)。
uC/OS II可以简单的视为⼀个多任务调度器,在这个任务调度器之上完善并添加了和多任务操作系统相关的系统服务,如信号量、邮箱等。
其主要特点有公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好,可裁剪,可固化。
内核属于抢占式,最多可以管理60个任务。
µC/OS-II 的前⾝是µC/OS,最早出⾃于1992 年美国嵌⼊式系统专家Jean brosse 在《嵌⼊式系统编程》杂志的5 ⽉和6 ⽉刊上刊登的⽂章连载,并把µC/OS 的源码发布在该杂志的B B S 上。
µC/OS 和µC/OS-II 是专门为计算机的嵌⼊式应⽤设计的,绝⼤部分代码是⽤C语⾔编写的。
CPU 硬件相关部分是⽤汇编语⾔编写的、总量约200⾏的汇编语⾔部分被压缩到最低限度,为的是便于移植到任何⼀种其它的CPU 上。
⽤户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件⼯具,就可以将µC/OS-II嵌⼈到开发的产品中。
µC/OS-II 具有执⾏效率⾼、占⽤空间⼩、实时性能优良和可扩展性强等特点,最⼩内核可编译⾄ 2KB 。
µC/OS-II 已经移植到了⼏乎所有知名的CPU 上。
1-uCOS-II 工作流程图
至少创建一个任务。 一般创建一个最高优 先级别 TaskStart 任 务(建议),任务调 度后,在这个任务中 再创建其他任务,初 始化硬件,并开中 断。
进入多任务管理阶 段,将就绪表中最高 优先级任务的栈指针 加载到 SP 中,并强 制中断返回。
uC/OS 的任务调度工作: ①查找就绪表中最高优先级任务。 ②实现任务切换。 分为:
⑥ ①
初始化变量 OSIint
中断
②
创建任务 OSTasБайду номын сангаасCreate
③
进入多任务管理阶段 OSStart
④
任务调度 OSSched/OSIntExt
⑤
用户任务 MyTask
初始化所有全局变量、数 据结构、创建最低优先级 空闲任务 OSTaskIde, (如果使用了统计任务, 也在此创建),创建 6 个 空数据链表: ①空任务控制块链表 ②空事件控制块链表 ③空队列控制块链表 ④空标志组链表 ⑤空内存控制块链表 ⑥空闲定时器控制块链表
主动让出 CPU:延时、 请求临界资源而挂起、
如果按照刚才的建议 去做,首次调度时, 肯定运行 TaskStart ,在这任 务中再创建其他任
任务调度,是内核的主要服务,是 区分裸机跟多任务系统的最大特 点。好的调度策略,能更好地发挥 系统的效率
务,并开中断(前面 已经提到)。
COPYRIGHT 2011 野火嵌入式开发工作室 uC/OS 详细工作流程图 By 野火团队:
uC/OS 的实时性就是靠定时中断来完成。 每个时钟节拍到来,就会产生一次定时中断,中断后进行任务调度,运行 就绪表中优先级最高的任务(非抢先型内核中断后继续运行被中断任 务)。即过一段时间就检测是否有重要任务需要运行,是的就转而运行更 重要的任务,从而确保实时性(裸机程序就无法这样做了)。
uCOS2中文手册第9章
µC/OS-II在80x86上的移植本章将介绍如何将µC/OS-II移植到Intel 80x86系列CPU上,本章所介绍的移植和代码都是针对80x86的实模式的,且编译器在大模式下编译和连接。
本章的内容同样适用于下述CPU:80186802868038680486PentiumPentium II实际上,将要介绍的移植过程适用于所有与80x86兼容的CPU,如AMD,Cyrix,NEC (V-系列)等等。
以Intel的为例只是一种更典型的情况。
80x86 CPU每年的产量有数百万,大部分用于个人计算机,但用于嵌入式系统的数量也在不断增加。
最快的处理器(Pentium系列)将在2000年达到1G的工作频率。
大部分支持80x86(实模式)的C编译器都提供了不同的内存使用模式,每一种都有不同的内存组织方式,适用于不同规模的应用程序。
在大模式下,应用程序和数据最大寻址空间为1Mb,程序指针为32位。
下一节将介绍为什么32位指针只用到了其中的20位来寻址(1Mb)。
本章所介绍的内容也适用于8086处理器,但由于8086没有PUSHA指令,移植的时候要用几条PUSH指令来代替。
图F9.1显示了工作在实模式下的80x86处理器的编程模式。
所有的寄存器都是16位,在任务切换时需要保存寄存器内容。
图F9.1 80x86 实模式内部寄存器图.80x86提供了一种特殊的机制,使得用16位寄存器可以寻址1Mb地址空间,这就是存储器分段的方法。
内存的物理地址用段地址寄存器和偏移量寄存器共同表示。
计算方法是:段地址寄存器的内容左移4位(乘以16),再加上偏移量寄存器(其他6个寄存器中的一个,AX,BP,SP,SI,DI或IP)的内容,产生可寻址1Mb的20位物理地址。
图F9.2表明了寄存器是如何组合的。
段寄存器可以指向一个内存块,称为一个段。
一个16位的段寄存器可以表示65,536个不同的段,因此可以寻址1,048,576字节。
嵌入式实时操作系统uCOSII第12章 配置手册
第12章配置手册本章将介绍μC/OS-II中的初始化配置项。
由于μC/OS-II向用户提供源代码,初始化配置项由一系列#define constant语句构成,都在文件OS_CFG.H中。
用户的工程文件组中都应该包含这个文件。
本节介绍每个用#define constant定义的常量,介绍的顺序和它们在OS_CFG.H中出现的顺序是相同的。
表12.1列出了常量控制的μC/OS-II函数。
“类型”为函数所属的类型,“置1”表示当定义常量为1时可以打开相应的函数,“其他常量”为与这个函数有关的其他控制常量。
注意编译工程文件时要包含OS_CFG.H,使定义的常量生效。
表T12.1 μC/OS-II函数和相关的常量(#define constant定义)表 T12.1 µC/OS-II 函数和相关常量类型置1其他常量杂相OSInit()无OS_MAX_EVENTSOS_Q_EN and OS_MAX_QSOS_MEM_ENOS_TASK_IDLE_STK_SIZEOS_TASK_STAT_ENOS_TASK_STAT_STK_SIZEOSSchedLock()无无OSSchedUnlock()无无OSStart()无无OSStatInit()OS_TASK_STAT_EN &&OS_TICKS_PER_SECOS_TASK_CREATE_EXT_ENOSVersion()无无中断处理OSIntEnter()无无OSIntExit()无无消息邮箱OSMboxAccept()OS_MBOX_EN无OSMboxCreate()OS_MBOX_EN OS_MAX_EVENTS OSMboxPend()OS_MBOX_EN无OSMboxPost()OS_MBOX_EN无OSMboxQuery()OS_MBOX_EN无内存块管理OSMemCreate()OS_MEM_EN OS_MAX_MEM_PART OSMemGet()OS_MEM_EN无OSMemPut()OS_MEM_EN无OSMemQuery()OS_MEM_EN无消息队列OSQAccept()OS_Q_EN无OSQCreate()OS_Q_EN OS_MAX_EVENTSOS_MAX_QS OSQFlush()OS_Q_EN无OSQPend()OS_Q_EN无OSQPost()OS_Q_EN无OSQPostFront()OS_Q_EN无OSQQuery()OS_Q_EN无信号量管理OSSemAccept()OS_SEM_EN无OSSemCreate()OS_SEM_EN OS_MAX_EVENTS OSSemPend()OS_SEM_EN无OSSemPost()OS_SEM_EN无OSSemQuery()OS_SEM_EN无任务管理OSTaskChangePrio()OS_TASK_CHANGE_PRIO_ENOS_LOWEST_PRIOOSTaskCreate()OS_TASK_CREATE_EN OS_MAX_TASKSOS_LOWEST_PRIOOSTaskCreateExt()OS_TASK_CREATE_EXT_EN OS_MAX_TASKS OS_STK_GROWTH OS_LOWEST_PRIOOSTaskDel()OS_TASK_DEL_EN OS_LOWEST_PRIO OSTaskDelReq()OS_TASK_DEL_EN OS_LOWEST_PRIO OSTaskResume()OS_TASK_SUSPEND_EN OS_LOWEST_PRIO OSTaskStkChk()OS_TASK_CREATE_EXT_E OS_LOWEST_PRIONOSTaskSuspend()OS_TASK_SUSPEND_EN OS_LOWEST_PRIO OSTaskQuery()OS_LOWEST_PRIO时钟管理OSTimeDly()无无OSTimeDlyHMSM()无OS_TICKS_PER_SEC OSTimeDlyResume()无OS_LOWEST_PRIO OSTimeGet()无无OSTimeSet()无无OSTimeTick()无无用户定义函数OSTaskCreateHook()OS_CPU_HOOKS_EN无OSTaskDelHook()OS_CPU_HOOKS_EN无OSTaskStatHook()OS_CPU_HOOKS_EN无OSTaskSwHook()OS_CPU_HOOKS_EN无OSTimeTickHook()OS_CPU_HOOKS_EN无OS_MAX_EVENTSOS_MAX_EVENTS定义系统中最大的事件控制块的数量。
ucOS-II入门教程(任哲) 我见过的讲得最好的RTOS讲解ppt
应用:通讯录中的一条记录、
操作系统中经常使用 的数据结构(链表)
struct Student{ Student*next int age; char*name; char sex; };
两个元素的链表
next next
使用上的特点: 1。同数据类型数据的集合; 2。不占用连续内存空间。
1。分类存放,但 需要大量的连续存 2。检索速度慢, 定;
处理器中的运行环境和内存中的运行环境任务代码任务堆栈内存处理器pcsp多任务时的问题任务代码任务堆栈内存任务代码任务堆栈当有多个任务时处理器中的运行环境应该怎寄存器组程序运行环境程序虚拟处理器pcsp虚拟处理器pcsp虚拟处理器pcsp虚拟处理器pcsp调度器多任务时任务与处理器之间关系的处理程序处理器pcsp在内存中为每个任务创建一个虚拟的处理器处理器部分的运行环境由操作系统的调度器按某种规则来进行这两个复制工作复制当需要运行某个任务时就把该任务的虚拟处理器复制到实际处理器中复制当需要中止当前任应的虚拟处理器复制到内存复制再把另一个需要运行的任务的虚拟处理器复制到实寄存器组寄存器组也就是说任务的切换是任务虚拟处理器虚拟处理器应该存储的主要信息
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
3
4 5 6 7 y
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0
应用软件 操 作 系 统
用户可以调用(普 •通过提供函数(应用程序接 通调用或系统调用) 口(API)),从而使应用程 它们来对系统资源 序的设计人员得以在一个友 好的平台上进行应用程序的 进行操作。
uCOS-II的介绍和uCOS-II在单片机使用中的一些特点资料概述
uCOS-II的介绍和uCOS-II在单片机使用中的一些特点资料概述早在20世纪60年代,就已经有人开始研究和开发嵌入式操作系统。
但直到最近,它才在国内被越来越多的提及,在通信、电子、自动化等需要实时处理的领域所日益显现的重要性吸引了人们越来越多的注意力。
但是,人们所谈论的往往是一些著名的商业内核,诸如VxWorks、PSOS等。
这些商业内核性能优越,但价格昂贵,主要用于16位和32位处理器中,针对国内大部分用户使用的51系列8位单片机,可以选择免费的uC/OS-II。
uC/OS-II的特点1.uC/OS-II是由Labrosse先生编写的一个开放式内核,最主要的特点就是源码公开。
这一点对于用户来说可谓利弊各半,好处在于,一方面它是免费的,另一方面用户可以根据自己的需要对它进行修改。
缺点在于它缺乏必要的支持,没有功能强大的软件包,用户通常需要自己编写驱动程序,特别是如果用户使用的是不太常用的单片机,还必须自己编写移植程序。
2.uC/OS-II是一个占先式的内核,即已经准备就绪的高优先级任务可以剥夺正在运行的低优先级任务的CPU使用权。
这个特点使得它的实时性比非占先式的内核要好。
通常我们都是在中断服务程序中使高优先级任务进入就绪态(例如发信号),这样退出中断服务程序后,将进行任务切换,高优先级任务将被执行。
拿51单片机为例,比较一下就可以发现这样做的好处。
假如需要用中断方式采集一批数据并进行处理,在传统的编程方法中不能在中断服务程序中进行复杂的数据处理,因为这会使得关中断时间过长。
所以经常采用的方法是置一标志位,然后退出中断。
由于主程序是循环执行的,所以它总有机会检测到这一标志并转到数据处理程序中去。
但是因为无法确定发生中断时程序到底执行到了什么地方,也就无法判断要经过多长时间数据处理程序才会执行,中断响应时间无法确定,系统的实时性不强。
如果使用uC/OS-II的话,只要把数据处理程序的优先级设定得高一些,并在中断服务程序中使它进入就绪态,中断结束后数据处理程序就会被立即执行。
uC_OS-II中文教程
1.01 INCLUDES.H
用户将注意到本书中所有的 *.C 文件都包括了以下定义:
#include "includes.h"
INCLUDE.H 可以使用户不必在工程项目中每个*.C 文件中都考虑需要什么样的头文件。 换句话说,INCLUDE.H 是主头文件。这样做唯一的缺点是 INCLUDES.H 中许多头文件在一些 *.C 文件的编译中是不需要的。这意味着逐个编译这些文件要花费额外的时间。这虽有些不 便,但代码的可移植性却增加了。本书中所有的例子使用一个共同的头文件 INCLUDES.H,3 个 副 本 分 别 存 放 在 \SOFTWARE\uCOS-II\EX1_x86L , \SOFTWARE\uCOS-II\EX2_x86L , 以 及 \SOFTWARE\uCOS-II\EX3_x86L 中。当然可以重新编辑 INCLUDES.H 以添加用户自己的头文 件。
#include "includes.h"
当编译器处理.C 文件时,它强制 xxx_EXT(在相应.H 文件中可以找到)为空, (因为 xxx_GLOBALS 已经定义) 。 所以编译器给每个全局变量分配内存空间, 而当编译器处理其他.C
文件时,xxx_GLOBAL 没有定义,xxx_EXT 被定义为 extern,这样用户就可以调用外部全局 变量。为了说明这个概念,可以参见 uC/OS_II.H,其中包括以下定义:
1.02 不依赖于编译的数据类型
因为不同的微处理器有不同的字长,µC/OS-II 的移植文件包括很多类型定义以确保可 移植性(参见\SOFTWARE\uCOS-II\Ix86L\OS_CPU.H,它是针对 80x86 的实模式,在大模式下 编译) 。µCOS-II 不使用 C 语言中的 short,int,long 等数据类型的定义,因为它们与处理器 类型有关,隐含着不可移植性。笔者代之以移植性强的整数数据类型,这样,既直观又可移 植,如表 L1.1 所示。为了方便起见,还定义了浮点数数据类型,虽然 µC/OS-II 中没有使 用浮点数。
uCOS-II的移植及使用
uC/OS-II 概述-性能特点
• 源代码公开 • 可移植(Portable) – 大部分代码用ANSI C写,与处理器无关,移植时不 需修改 – 少量与微处理器硬件相关的部分用C与汇编编写, 移植时需修改:
• OS_CPU.H //与硬件相关,移植时需修改 • OS_CPU_A.ASM //集中了所有与处理器相关的汇编语言 代码 • OS_CPU.C //集中了所有与处理器相关的汇编语言代码
uC/OS-II 概述--文件结构
应用软件 (用户代码) μC/OS-II (与处理器类型无关的代码) μC/OS-II配置文件 (与应用程序有关) OS_CFG.H INCLUDES.H
体系 结构
OS_CORE.C OS_FLAG.C OS_MBOX.C OS_MEM.C OS_MUTEX.C
OS_Q.C OS_SEM.C OS_TASK.C OS_TIME.C uC/OS-II.C uC/OS-II.H
任务控制块就相当于是一个任务的身份证,没 有任务控制块的任务是不能被系统承认和管理 的。
任务控制块的结构
typedef struct os_tcb { OS_STK *OSTCBStkPtr;
//指向当前任务堆栈栈顶的指针。每个任务的堆栈容量可以是任意的。
#if OS_TASK_CREATE_EXT_EN
为了有效的对中断进行控制,在任务的代码里可使用UC/OS-II定义的宏 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来控制何时响应中断, 何时屏蔽中断。在运行这两个宏之间的代码时是不会响应中断的,这种受保 护的代码段叫临界段。
2.1.2 uC/OS-II的任务—任务控制块(TCB)
uC/OS-II 概述-性能特点
uCOS2中文手册第4章
第4章任务管理 (1)4.0建立任务,OSTaskCreate() (2)4.1建立任务,OSTaskCreateExt() (6)4.2任务堆栈 (9)4.3堆栈检验,OSTaskStkChk() (11)4.4删除任务,OSTaskDel() (14)4.5请求删除任务,OSTaskDelReq() (17)4.6改变任务的优先级,OSTaskChangePrio() (20)4.7挂起任务,OSTaskSuspend() (23)4.8恢复任务,OSTaskResume() (25)4.9获得有关任务的信息,OSTaskQuery() (26)第4章任务管理在前面的章节中,笔者曾说过任务可以是一个无限的循环,也可以是在一次执行完毕后被删除掉。
这里要注意的是,任务代码并不是被真正的删除了,而只是µC/OS-Ⅱ不再理会该任务代码,所以该任务代码不会再运行。
任务看起来与任何C函数一样,具有一个返回类型和一个参数,只是它从不返回。
任务的返回类型必须被定义成void型。
在本章中所提到的函数可以在OS_TASK文件中找到。
如前所述,任务必须是以下两种结构之一:void YourTask (void *pdata){for (;;) {/* 用户代码 */调用µC/OS-Ⅱ的服务例程之一:OSMboxPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/* 用户代码 */}}或void YourTask (void *pdata){/* 用户代码 */OSTaskDel(OS_PRIO_SELF);}本章所讲的内容包括如何在用户的应用程序中建立任务、删除任务、改变任务的优先级、挂起和恢复任务,以及获得有关任务的信息。
µC/OS-Ⅱ可以管理多达64个任务,并从中保留了四个最高优先级和四个最低优先级的任务供自己使用,所以用户可以使用的只有56个任务。
UCOS_II在PC上运行的配置过程
在PC上配置Borland C++环境练习uc/os-II
1、安装下载好的Borland C++和TASM 5.0 。
按照软件的提示即可
完成安装。
安装完毕后再在系统的环境变量path里添加bin文件的路径。
如:C:\BC45\BIN;C:\TASM\BIN
2、运行Borland C++,新建工程,如下所示:
工程所在路经根据实际情况,通过Browse来选择。
3、工程建立完毕后要添加文件。
首先要把工程自动建立的CPP文
件删掉。
4、将uc/os-II源码文件夹(SOFTWARE\uCOS-II)里面的EX1_x86L文件
夹复制一份到你要存放到另外的目录下面,就是你放练习工程用的目录。
然后把OS_CPU_C.C、OS_CPU_A.SAM、PC.C文件以及和他们名字一样的以.H结尾的文件都拷贝到工程目录下面。
把uc/os-II源码文件里的source文件夹也拷贝到工程目录里。
5、然后在Borland C++里添加源文件,一共要添加五个分别是:
Test.c、OS_CPU_C.C、OS_CPU_A.SAM、PC.C、ucos_II.c。
添加完毕后要打开uc/os_II文件,然后把里面的include后的路径进行修改,使其对应到工程目录下的source文件里。
这样在编译的时候就不会出错。
6、最后就是Build all,然后Run,如果没有错误就能看到最后的结
果。
7、以后的练习可以用这个工程作为模板,只是改变test.c就可以
了。
2011-08-22
------By Tank。
ucos ii移植过程详解
uCOS-II移值过程实例讲解我将uCOS-II 移植到了EPONS 的C33209的平台上,接下来我就基于我移植好的代码讲解如何将uCOS-II从一种MCU移植到另一种MCU。
首先介绍uCOS-II的文件,如下表:ucos_ii.hos_cfg.hos_cpu.hos_core.cos_dbg_r.cos_flag.cos_mbox.cos_mem.cos_mutex.cos_q.cos_sem.cos_task.cos_time.cucos_ii.cos_cpu_c.cos_cpu_a.asm其中我们和硬件平台相关的文件的文件名被加粗了,也就是说若要将uCOS-II移植到新的平台上只要关心被以上四个文件就行了。
当然你也可以根据需要再添加你自己的和平台相关的文件,事实上我也是这么做的。
在我移植的例子中就添加了四个和平台相关的文件,文件如下表:crt0.cdrv_rtc.cvector.cext.scrt0.c是用来初始化系统的比如说MCU的一些特殊寄存器、设置外围的总线接口,等。
drv_rtc.c是用来初始化系统中的一个RTC的,这个RTC可以为内核提供必要的基于时间片调度的时基。
同时提供了对RTC开始和停止的操作函数。
在我的例子中RTC会每秒产生32次中断。
vector.c顾名思义,它是系统上电后为系统提供矢量入口表的文件,当然也包括中断向量表。
ext.s是为uc/OS-II 提供OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()函数的具体实现以及在用户程序的中断函数出入时要调用的状态保护和状态恢复函数OS_SA VEALL ()和OS_RESTOREALL ()。
前面两个函数的功能是:OS_ENTER_CRITICAL()屏蔽中断;OS_EXIT_CRITICAL()恢复原来的中断使能状态。
1. os_cpu_a.asm的说明要想顺利的移植首先要了解uCOS-II的一些基本概念。
Ucos_II_中文注释版
Ucos_II2.52源码中文译注作者: 钟常慰 Ucos_II2.52是一份非常完美的嵌入式开发系统,在学习ARM的基础上,嵌入ucos系统并增加自己的源码是一件不错的选择,目前在市面上已经有了大量的ucos嵌入案例,特别是在arm和dsp的应用当中,已经成为一种主流,虽然和其它的嵌入式系统相比,ucos不是很完善,如没有内存分配、任务级别不多;但却是一个代码简短、条理清晰、实时性及安全性能很高的嵌入式操作系统。
Ucos_II2.52对比2.8版的256个任务而言,任务数量相比过少,但却是目前应用量最大的一个版本,相对而言,能够满足我们的基本要求,而且增加了很多消息处理,特别是在优先级别方面,具有不可比拟的优势;我曾试图阅读ecos的源码,但还是失败了,还有挑战linux0.01版源码的想法,最终我不能不被屈服;对于Ucos而言,很多入门者是一个福音,因为它的代码非常的少,而且能够对应贝贝老师的书本直接参考,他的书本对结构方面讲解的极为xian详细。
在学习Ucos的整个过程中,E文的理解是一个致命的打击,原因是我的E文水平很差,不过Ucos还是给了我尝试的动力,在作者的原基础上增加中文译码,也许是一件非常不错的选择,相信在中国和我这种水平的人多不胜数,中文的注解对源码而言,能够具有极高的理解价值,可以在极短的时间内,能够充分了解ucos的真正含义。
整个翻译过程历时4个月,每每在寒冬腊月坐在计算机前面,不断的查阅贝贝老师的书来对整个Ucos进行理解,对每个源码进行逐条翻译,也是一件非常需要勇气的事情,但E文的翻译过程中很多变量是不能完全理解的,所以在翻译过程中不乏错误译文很多,于此带来的错误还请读者纠正,相信克服种种困难一定会有所了解的。
对于经济窘迫的我来说,曾试图希望卖一点资料来养家糊口,但这种做法根本不现实,很多的读者可能和我一样,习惯了拿不收费的资料,并对变相收费有一种深恶痛绝的感觉;想了很多决定还是把它贡献出来,让更多的人来(更容易)了解ucos,贡献自己的一点力量。
uCOS-II 入门理解
uCOS-II 初级程序员指南(一)uC/OS-II 简介uC/OS-II是一种基于优先级的可抢先的硬实时内核。
自从92年发布以来,在世界各地都获得了广泛的应用,它是一种专门为嵌入式设备设计的内核,目前已经被移植到40多种不同结构的CPU 上,运行在从8位到64位的各种系统之上。
尤其值得一提的是,该系统自从2.51版本之后,就通过了美国FAA认证,可以运行在诸如航天器等对安全要求极为苛刻的系统之上。
鉴于uC/OS-II可以免费获得代码,对于嵌入式RTOS而言,选择uC/OS无疑是最经济的选择。
(二)uC/OS-II应用程序基本结构应用uC/OS-II,自然要为它开发应用程序,下面论述基于uC/OS-II的应用程序的基本结构以及注意事项。
每一个uC/OS-II应用至少要有一个任务。
而每一个任务必须被写成无限循环的形式。
以下是推荐的结构:void task ( void* pdata ){INT8U err;InitTimer(); // 可选For( ;; ){// 你的应用程序代码…….……..OSTimeDly(1); // 可选}}以上就是基本结构,至于为什么要写成无限循环的形式呢?那是因为系统会为每一个任务保留一个堆栈空间,由系统在任务切换的时候换恢复上下文,并执行一条reti 指令返回。
如果允许任务执行到最后一个花括号(那一般都意味着一条ret指令)的话,很可能会破坏系统堆栈空间从而使应用程序的执行不确定。
换句话说,就是“跑飞”了。
所以,每一个任务必须被写成无限循环的形式。
程序员一定要相信,自己的任务是会放弃CPU使用权的,而不管是系统强制(通过ISR)还是主动放弃(通过调用OS API)。
现在来谈论上面程序中的InitTimer()函数,这个函数应该由系统提供,程序员有义务在优先级最高的任务内调用它而且不能在for循环内调用。
注意,这个函数是和所使用的CPU相关的,每种系统都有自己的Timer初始化程序。
uCOSII原理及应用
任务控制块
用于存储任务的运行状态和控制信息,包括任 务的优先级、状态、堆栈指针等。
任务切换函数
用于实现任务之间的切换,包括保存当前任务的上下文和恢复下一个任务的上 下文。
ucosii的任务管理
创建任务
通过调用ucosii提供的函数, 创建新的任务并分配相应的 资源。
在物联网应用中,ucosii能够为各种智能硬件提供统一的操 作系统平台,实现设备的互联互通和智能化管理。同时, ucosii还提供了丰富的中间件和驱动程序,方便开发者快速 开发出各种智能硬件和应用软件。
ucosii在嵌入式系统中的应用
嵌入式系统是指嵌入到硬件中的计算机系统,具有特定的功能和性能要求。ucosii作为一种实时操作 系统,在嵌入式系统中也有着广泛的应用。
调试工具
使用JTAG、SWD等调试工具,通过串口、网络等方式与目标板进行通信,实现程序的 下载、运行、断点设置等操作。
调试步骤
首先确认硬件连接正确,然后通过调试工具将程序下载到目标板中,设置断点并运行程 序,观察程序运行过程中变量的变化和程序的执行流程。
常见问题
硬件连接问题、调试工具配置问题、程序编译错误等。
ucosii的性能分析
性能指标
响应时间、吞吐量、资源利用率等。
分析方法
通过代码审查、性能测试、瓶颈分析等方法,找出影响性能的 关键因素,如算法复杂度、内存访问模式、IO性能等。
优化建议
针对分析结果,提出优化建议,如改进算法、优化数据结 构、减少IO操作等。
ucosii的优化建议
算法优化
通过改进算法,减少计算量和复杂度,提高程序执行效率。
易用性
UCOS-II操作系统详解
VμC/OS 和μC/OS-II是专门为计算机的嵌入式应用设计的,绝大部分代码是用C语言编写的。
CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。
工作原理编辑uC/OS-II是一种基于优先级的可抢先的硬实时内核。
要实现多任务机制,那么目标CPU必须具备一种在运行期更改PC的途径,否则无法做到切换。
不幸的是,直接设置PC指针,还没有哪个CPU支持这样的指令。
但是一般CPU都允许通过类似JMP,CALL这样的指令来间接的修改PC。
我们的多任务机制的实现也正是基于这个出发点。
事实上,我们使用CALL指令或者软中断指令来修改PC,主要是软中断。
但在一些CPU上,并不存在软中断这样的概念,所以,我们在那些CPU上,使用几条PUSH指令加上一条CALL指令来模拟一次软中断的发生。
在uC/OS-II里,每个任务都有一个任务控制块(Task Control Block),这是一个比较复杂的数据结构。
在任务控制块的偏移为0的地方,存储着一个指针,它记录了所属任务的专用堆栈地址。
事实上,在uC/OS-II内,每个任务都有自己的专用堆栈,彼此之间不能侵犯。
这点要求程序员在他们的程序中保证。
一般的做法是把他们申明成静态数组。
而且要申明成OS_STK类型。
当任务有了自己的堆栈,那么就可以将每一个任务堆栈在那里记录到前面谈到的任务控制快偏移为0的地方。
以后每当发生任务切换,系统必然会先进入一个中断,这一般是通过软中断或者时钟中断实现。
然后系统会先把当前任务的堆栈地址保存起来,仅接着恢复要切换的任务的堆栈地址。
由于哪个任务的堆栈里一定也存的是地址(还记得我们前面说过的,每当发生任务切换,系统必然会先进入一个中断,而一旦中断CPU就会把地址压入堆栈),这样,就达到了修改PC为下一个任务的地址的目的。
任务管理编辑uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。
ucOS-II最详细的解释
FLTCH
■结构体数组的初始化 在定义结构体数组的同时指定初值。 struct student { int num; char name[20]; int score; }; struct student a[2]= {{1001,”LiLi”,85},{1002,”wang”,90}};
FLTCH
应用软件
操 高级语言的接口 作 用汇编语言编写 系 的 统 硬件抽象层
计算机硬件
FLTCH
API
什么是API? API(Application Programming Interface,应 用程序编程接口)是一些预先定义的函数,目的是 提供应用程序与开发人员基于某软件或硬件的以访 问一组例程的能力,而又无需访问源码,或理解内 部工作机制的细节。
FLTCH
μC/OS-II
μC/OS-II
μC/OS-II是一种可移植的,可植入ROM的,可 裁剪的,抢占式的,实时多任务操作系统内核。它 被广泛应用于微处理器、微控制器和数字信号处理 器。 μC/OS-II 的前身是μC/OS, 是专门为计 算机的嵌入式应用设计的 。
FLTCH
主要内容
1. 计算机操作系统的基本概念 2. 操作系统中常用的数据结构
struct student { int num; char name[20]; int score; };
FLTCH
main() { int i; struct student st,stmax,stmin; stmax.score=0; stmin.score=100; for(i=1;i<=100;i++) { scanf(“%d%s%d”,&st.num,,&st.score); if(st.score>stmax.score) stmax=st; if(st.score<stmin.score) stmin=st; } printf(“\n%5d%15s%5d”,stmax.num,, stmax.score); printf(“\n%5d%15s%5d”,stmin.num,, stmin.score); }
UCOS-II API 参考手册_带书签
UCOS-II API参考手册本章提供了μC/OS-Ⅱ的用户指南。
每一个用户可以调用的内核函数都按字母顺序加以说明,包括:l函数的功能描述l函数原型l函数名称及源代码l函数使用到的常量l函数参数l函数返回值l特殊说明和注意点OSInit()Void OSInit(void);所属文件调用者开关量OS_CORE.C启动代码无OSinit()初始化μC/OS-Ⅱ,对这个函数的调用必须在调用OSStart()函数之前,而OSStart ()函数真正开始运行多任务。
参数无返回值无注意/警告必须先于OSStart()函数的调用范例:void main(void){.OSInit();/*初始化uC/OS-II*/.OSStart();/*启动多任务内核*/}μC/OS-II:实时操作系统内核OSIntEnter()Void OSIntEnter(void);所属文件调用者开关量OS_CORE.C中断无OSIntEnter()通知μC/OS-Ⅱ一个中断处理函数正在执行,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。
OSIntEnter()函数通常和OSIntExit()函数联合使用。
参数无返回值无注意/警告在任务级不能调用该函数。
如果系统使用的处理器能够执行自动的独立执行读取-修改-写入的操作,那么就可以直接递增中断嵌套层数(OSIntNesting),这样可以避免调用函数所带来的额外的开销。
范例一:(Intel80x86的实模式,在大模式下编译,,real mode,large model)ISRx PROC FARPUSHA;保存中断现场PUSH ESPUSH DS;MOV AX,DGROUP;读入数据段MOV DS,AX;CALL FAR PTR_OSIntEnter;通知内核进入中断..POP DS;恢复中断现场POP ESPOPAIRET;中断返回ISRx ENDP范例二:(Intel80x86的实模式,在大模式下编译,,real mode,large model)ISRx PROC FAR参考手册PUSHA;保存中断现场PUSH ESPUSH DS;MOV AX,DGROUP;读入数据段MOV DS,AX;INC BYTE PTR_OSIntNesting;通知内核进入中断...POP DS;恢复中断现场POP ESPOPAIRET;中断返回ISRx ENDPμC/OS-II:实时操作系统内核OSIntExit()Void OSIntExit(void);所属文件调用者开关量OS_CORE.C中断无OSIntExit()通知μC/OS-Ⅱ一个中断服务已执行完毕,这有助于μC/OS-Ⅱ掌握中断嵌套的情况。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Genie shell for UCOS II 详细说明及使用指南
作者:杨晔 yangye@
2003-3-11 ver0.2
1 简单介绍
uCOSII只提供了操作系统内核,用户要自己添加文件处理、人机界面、网络接口等重要部分。
其中Shell(人机界面)提供了人与机器交互的界面,是机器服务于人的体现,是系统必不可少的重要组成部分。
现代的很多OS如UNIX、DOS、VxWorks都提供了友好的命令行界面。
Windows更是提供了GUI。
大部分人认识OS都是从这里开始的。
由于Skyeye下的仿真串口USART已经实现了中断方式的接收(实际是从键盘接收输入),而且串口输出(实际上是输出到终端屏幕)也已经实现,所以实现一个类似DOS或Bash的简化版Shell并不困难。
其本质思想就是:Shell作为一个uC/OSII下的任务,接收用户输入的字符,存储到缓冲区,并回显在屏幕上,以回车键为用户输入的结束信号,随后解析用户输入的命令名称、参数,调用相应的命令函数。
一直到这个命令函数运行返回,才继续Shell的人机交互界面。
Shell作为一个任务工作于内核之外,占用一个任务号。
其流程图如下:
命令输入、解析参数、调用命令函数功能,以及两条示例性的命令。
这个Shell的特色是采用了一些面向对象的思路来实现Shell的各种命令。
2.Genie Shell实现分析
2.1 Genie Shell的实现基础(串口通讯函数)
Genie shell与硬件相关的部份有三个函数:
CommRxIntEn(UART0); 初始化串口硬件
CommGetChar(UART0,0,&err); 从串口接收一个字符,这个串口最好是中断方式的,否则用轮询方式Genie shell就会占用全部cpu。
参数0表示永远等待,没有timeout的情况。
printf函数向串口打印字符,注意虽然在Skyeye中是打印在屏幕上的,但实际上是向串口发送字符,只是Skyeye的串口仿真输出就是到终端屏幕。
以上三个函数由用户根据自己的单片机上的串口去实现。
在Skyeye中我们已经实现了,参见ucosii\samples目录下的例子。
2.2 shell task部份:(shelltask.[ch])
A.void shelltask(void) 这是应该由用户在ucosII中用OSTaskCreate建立的任务(task)。
首先做以下初始化工作:
CommRxIntEn(UART0); //初始化串口
InitCommands(); //初始化命令对象数组
CommandBuf[0] = '\0';
然后进入无限循环(for(;;))中,用CommGetChar函数接收输入字符。
对不同的输入字符分别做不同的处理:
退格键光标回退,删除显示的字符,光标再回退
回车键:命令输入结束,调用CommandAnalys函数分析命令格式和参
数,CommandAnalys会返回命令号,然后根据命令号从ShellComms
对象数组中找到相应的命令对象,然后执行这个命令对象的方法
(也就是命令函数),命令参数也会传递过去。
普通合法字符:先显示(printf),再放入CommandBuf中等待分析
非法字符:不接收输入。
此外还做了一些简化,如不接收连续两个空格,不接收行首的空格。
嵌入式系统嘛,简单一些。
B.INT8U CommandAnalys(char *Buf);
对用户输入的字符串做分析,根据字符串的内容,分析出命令名称,命令参数。
分析过程本文不详细描述了。
2.3 Command命令部份(command.[ch])
把每个命令看成一个对象,对象的属性是命令名,而对象的方法就是命令 Genie
Shell
的执行函数本身。
用户输入命令及参数后,将参数传递给对象的方法并执行。
在shell中增加一条命令,就是增加一个对象,并实现这个对象的方法。
在c语言中实际是一个带函数指针的结构体:
struct{
typedef
int num; //命令序号
char *name; //命令名称(目前的设定是小于20个字符)
INT8U (*CommandFunc)(INT8U argc,char **argv); //命令函数
}command;
每条命令对应一个command对象,所有的命令对象都存放在command数组ShellComms[MAX_COMMAND_NUM]中。
MAX_COMMAND_NUM是总的命令个数,用户应该根据自己shell的命令个数设置,注意MAX_COMMAND_NUM应该正好等于总的命令个数,不能多也不能少。
用户增加自己的命令时,首先把在commands.h中把MAX_COMMAND_NUM加1;然后在commands.c中InitCommands()函数里增加如下语句:
ShellComms[i].num = 0;
ShellComms[i].name = "hello";
ShellComms[i].CommandFunc = HelloFunc;
其中的i和具体值由用户根据情况决定。
最后实现命令函数,并把函数名称赋给ShellComms[i].CommandFunc就可以了。
请参照commands.c中已经有的两个例子。
2.4. 目前的例子
目前的genie shell带有两条命令:
hostname命令在屏幕上打印一句话,很简单。
hello 命令可以带多个参数,如hello a b c d,回车后会显示:
hello,I am Genie
your argv is:
a
b
c
d
这个例子说明了参数的解析和传递方法,具体这里不分析了,请参考源代码。