uCOS-II的移植--初学者学习
UCOS_II在PC上的移植(详细版)
UCOS II在PC上的移植网上移植教程有不少,不过对于初学者还是容易出问题,在这里将移植的详细过程记录如下,建议有兴趣的同学,找台电脑,从头试一遍,这样就算是入门了.一、准备工作在PC上移植ucos系统,因为ucos系统的源代码是c语言写的,因此编译C的软件必不可少。
在pc机上运行,还需要对pc的设备进行一空的控制,会用到汇编语言,因此汇编语言的编译软件也必不可少。
再有就是操作系统的源码,这些都准备好了,就可以进行移植了。
一些教材在移植是c编译环境选BORLAND C++ 4.5,汇编编译用TASM5.0,网络上能找到的移植方法基本都是基于这2个软件的。
这2个编译软件和操作系统源码可以通过网络下载。
图1 ucos移植的必备文件下载解压后,如图1所示。
下边开始安装,编译软件。
BORLAND C++和TASM5.0安装顺序不会影响到使用,在安装之前先来看下c盘的文件结构。
在图2中,c盘根目录下只有3个文件夹,当我们配置完成后,会多出4个文件夹。
图2 编译环境安装前c盘文件结构二、开始安装1.安装编译软件BORLAND C++ 4.5。
在BORLAND C++ 4.5安装文件包里找到找到install.exe文件并双击,默认的安装路径就C:\BC45。
因此安装时,可以用默认设置一直继续,安装过程如图3所示(注意安装包里还有一个setup文件,请不要用它来安装)。
图3 bc4.5安装界面2.安装汇编编译软件TASM5.0(1)这一步如果不小心,很容易安装不正确。
先在C盘建立一个名为TASM的文件夹,然后把TASM5.0安装文件里的所有文件都复制进去。
如图4所示,双击图4中的install 文件开始安装。
图4 TASM5.0安装(2)在弹出的界面按回车键继续,出现安装选择文件界面,将默认的A改为C如图5所示。
图5 修改盘符(3)按回车键继续,出现一个路径设置的界面,继续按回车键,出现安装配置界面如图6所示。
实验一 uCOS-II的移植
实验一uC/OS-II的移植1.实验目的(1)理解uCOS-II实时内核的工作原理;(2)熟悉uCOS-II在XS128上的移植过程;(3)掌握uCOS-II移植的细节。
2.实验任务(1)观察示例程序中的代码,体会实时操作系统与前后台程序的不同之处。
(2)完成由前后台程序编程到基于实时操作系统编程的思想转变。
3.预习要求(1)参考《嵌入式实时操作系统uCOS-II》(第2版),熟悉uCOS-II各模块的基本工作原理。
(2)参考《单片机与嵌入式系统开发方法》第9章内容以及《uCOS-II移植说明文档》。
熟悉uCOS-II在XS128上的移植过程。
4.实验步骤(1)打开示例程序,观察程序结构。
(2)识别出哪些是与硬件无关的文件,哪些是移植需要修改和添加的文件。
(3)打开OS_CPU.H文件,该文件定义CPU的数据类型,定义相关的宏。
打开OS_CPU_C文件,分析文件里各个函数的作用。
这两个文件是与CPU特性有关的文件。
(4)分别打开OS_CFG.H, INCLUDES.H. OS_CFG.H这三个文件,了解这三个文件的作用。
用户根据自己的应用系统来定制合适的内核服务功能.包括两个文件:OS_CFG.H, INCLUDES.H. OS_CFG.H是来配置内核, 用户根据需要对内核进行定制, 留下需要的部分, 去掉不需要的部分, 设置系统的基本情况. 比如系统可提供的最大任务数量, 是否定制邮箱服务, 是否需要系统提供任务挂起功能, 是否提供任务优先级动态改变功能等等;头文件INCLUDES.H为整个实时系统程序所需要的文件,包括了内核和用户的头文件。
(5)修改.prm文件中的中断向量,将其中的ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF;改为ROM_C000 = READ_ONLYDATA_NEAR IBCC_NEAR 0xC000 TO 0xEEFF;将结尾处原有的VECTOR 0 _Startup;改为VECTOR ADDRESS 0xEFFE _Startup;再添加上VECTOR ADDRESS 0xEFF6 OSCtxSw;VECTOR ADDRESS 0xEFF0 OSTickISR两个中断向量。
一步步移植uCOS-IIandLwIP(一)
一步步移植uCOS-IIandLwIP(一)STM32F103ZE下移植uCOS-II and LwIP 汇总本文主要记录嵌入式实时操作系统uCOS-II(Ver 2.85)和轻量型TCP/IP协议栈LwIP(Ver 1.4.1)在32bit单片机STM32F103ZE上的移植过程,并列举几个simple examples说明两者工作原理。
本文的叙述原则是“用到什么知识点,就查阅相关资料”,对于其它延伸知识点不再概述。
所需物资:- 硬件开发平台,本平台网卡为DM9000A- uCOS-II(Ver 2.85)源码,可直接从Micrium官网下载uCOS 在cortex-M3上的移植例程uCOSII-ST-STM32F103ZE-SK - LwIP(Ver 1.4.1)源码,下载链接LwIP1.4.1一、Lwip移植TCP/IP协议分为网络链路层、网络层、传输层和应用层四个部分,网络链路层主要涉及底层硬件驱动的编写,另外三个上次协议一般采用协议栈的方式软件实现。
要实现与其它网络设备通信,首当其冲的是要移植好底层网卡驱动。
LwIP协议栈已经为我们提供了网络链路底层接口,我们要做到主要工作涉及到以下几个方面:- 单片机与网卡DM9000芯片的通信;- 完善LwIP协议栈文件ethernetif.c接口函数,该部分的难点在于实现LwIP规定的struct pbuf类型的数据包与网卡数据之间相互转换;- 上层软件协议的simple explain;1、网卡DM9000底层驱动的编写首先查阅DM9000的Datasheet(建议直接从芯片官网上查找,一般会有该芯片的Application note or Demo)本文主要是运用DM9000的16-bit mode,其总线形式类似与intel 8080总线,涉及读写指令和数据的控制引脚为CS#、IOW#、IOR#、CMD,数据总线引脚SD0~SD15,中断引脚INT。
UCOS-II的详细移植笔记两种处理器的移植比较(S1C33209S3C44BOX)
UCOS-II的详细移植笔记两种处理器的移植比较(S1C33209S3C44BOX)UC/OS-II的详细移植笔记两种处理器的移植比较(S1C33209&&S3C44BOX) [原创 2007-05-20 23:03:21] 字号:大中小UC/OS-II的移植步骤分析zqcumt 07-4-15关于UC/OS-II的移植网上介绍的已经很多了,比较流行的几款处理器(例如ARM)在网上都可以直接下载移植好的代码。
由于最近选修了一门嵌入式系统的课,用的处理器是EPSON公司的S1C33系列,做实验的时候要进行操作系统的移植,这个周末花了一天半的时间学习了一下,因为毕业设计的时候做过ARM上的移植,于是将两者比较了一下,给出一般的移植要点。
由于将来实验还要设计到GUI的移植以及文件系统的移植和网络协议的移植,我会将自己的学习笔记都记录下来。
大家下载到源码后,针对Intel 80x86的代码在uCOS-II\Ix86L目录下。
代码是80x86实模式,且在编译器大模式下编译的。
移植部分的代码可在下述文件中找到:OS_CPU.H, OS_CPU_C.C, 和OS_CPU_A.ASM。
大家可以参考这个例子,对它进行修改。
INCLUDES.H 是主头文件,在所有后缀名为.C的文件的开始都包含INCLUDES.H文件。
使用INCLUDES.H的好处是所有的.C文件都只包含一个头文件,程序简洁,可读性强。
缺点是.C文件可能会包含一些它并不需要的头文件,额外的增加编译时间。
与优点相比,多一些编译时间还是可以接受的。
用户可以改写INCLUDES.H文件,增加自己的头文件,但必须加在文件末尾。
/////////////////////////////////////////////////////////////////// ////////////一、(1)OS_CPU.H文件的移植 (针对S1C33209)//////////////////////////////////////////////////////////////////////////OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。
一步步移植uCOS-IIandLwIP(四)
一步步移植uCOS-IIandLwIP(四)二、uCOS-II移植嵌入式实时操作系统uCOS-II移植的核心在于任务切换时上下文环境的保存及恢复,针对Cortex-M3内核的单片机,其采用了PendSVHandler中断处理的方式解决这一核心问题。
我们要做的就是在任务切换及中断任务切换过程中开启触发PendSV中断,并在PendSVHandler中实现上下文环境的切换,即保存CPU内部寄存器值和恢复切换任务的相关信息。
为什么要使用PendSV中断实现上下文切换呢?参阅Cortex-M3的一段话。
另一个相关的异常是PendSV(可悬起的系统调用),它和SVC 协同使用。
一方面,SVC异常是必须在执行SVC指令后立即得到响应的(对于SVC异常来说,若因优先级不比当前正处理的高,或是其它原因使之无法立即响应,将上访成硬fault——译者注),应用程序执行SVC时都是希望所需的请求立即得到响应。
另一方面,PendSV则不同,它是可以像普通的中断一样被悬起的(不像SVC那样会上访)。
OS可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。
悬起PendSV 的方法是:手工往NVIC的PendSV悬起寄存器中写1。
悬起后,如果优先级不够高,则将缓期等待执行。
PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。
例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是:- 执行一个系统调用-系统滴答定时器(SYSTICK)中断,(轮转调度中需要)让我们举个简单的例子来辅助理解。
假设有这么一个系统,里面有两个就绪的任务,并且通过SysTick异常启动上下文切换。
如图所示。
上图是两个任务轮转调度的示意图。
但若在产生SysTick 异常时正在响应一个中断,则SysTick异常会抢占其ISR。
在这种情况下,OS 是不能执行上下文切换的,否则将使中断请求被延迟,而且在真实系统中延迟时间还往往不可预知——任何有一丁点实时要求的系统都决不能容忍这种事。
UCOS-II在51单片机上的移植
UCOS-II在51单片机上的移植做操作系统的移植首先明白什么是移植,操作系统是一种鱼硬件(处理器)相关的软件,根据某一种处理器来设计的操作系统通常不能运行在那其他处理器。
所谓的移植是指修改操作系统,然后加载到一个处理器上。
本文只讲解步骤,至于理论知识,需要大家自己学习。
步骤:1,在UCOS-II的官网上下载,操作系统。
2,在网上找到或者自己建三四个文件:OS_CPU_A.ASSMOS_CPU.HOS_CPU_C.COS_CFG.H以上文件需要修改3,移植源码的编写和修改❖OS_CPU.H1)定义与编译器有关的数据类型typedef unsigned char BOOLEAN; /* 不能使用bit定义,结构中无法使用*/typedef unsigned char INT8U; /* 无符号8位数*/typedef unsigned char INT8S; /* 有符号8位数*/typedef unsigned int INT16U; /* 无符号16位数*/typedef signed int INT16S; /* 有符号16位数*/typedef unsigned long INT32U; /* 无符号32位数*/typedef signed long INT32S; /* 有符号32位数*/typedef float FP32; /* 单精度浮点数*/typedef double FP64; /* 双精度浮点数*/typedef unsigned char OS_STK; /* 定义堆栈入口宽度为8位*/typedef unsigned char OS_CPU_SR; /* 定义CPU状态字的宽度为8位*/2)定义堆栈增长方向#define OS_STK_GROWTH 0 /* MCS-51堆栈从下往上增长,1=向下,0=向上*/3)定义任务级的任务切换宏#define OS_TASK_SW() OSCtxSw() /* 任务级的任务切换宏*/4)定义临界段宏:#define OS_ENTER_CRITICAL() EA=0#define OS_EXIT_CRITICAL() EA=1❖OS_CPU_C.C①初始化任务栈void *OSTaskStkInit(void(*task)(void *pd), void *ppdata, void *ptos, INT16U opt) REENTRANT{O S_STK *stk;p pdata=ppdata; //pata data 为52文件关键字o pt =opt; /* opt没被用到,保留此语句防止警告产生 */s tk =(OS_STK *)ptos; /* 任务堆栈最低有效地址*/*stk++=15; /* 任务堆栈长度*/ *stk++=(INT16U)task & 0xFF; /* 任务代码地址低8位*/*stk++=(INT16U)task >> 8; /* 任务代码地址高8位*//* 处理器是按特定的顺序将寄存器存入堆栈的,所以用户在将寄存器存入堆栈的时候也要依照这一顺序 */*stk++=0x00; /* PSW*/*stk++=0x0A; /* ACC*/*stk++=0x0B; /* B */ *stk++=0x00; /* DPL*/*stk++=0x00; /* DPH*/*stk++=0x00; /* R0 */ *stk++=0x01; /* R1 */ *stk++=0x02; /* R2 */ *stk++=0x03; /* R3 */ *stk++=0x04; /* R4 */ *stk++=0x05; /* R5 */ *stk++=0x06; /* R6 */ *stk++=0x07; /* R7 */ /* 不用保存SP,任务切换时根据用户堆栈长度计算得出*/*stk++=(INT16U)(ptos+MAX_STK_SIZE) >> 8; /* ?C_XBP 仿真堆栈指针高8位 */*stk++=(INT16U)(ptos+MAX_STK_SIZE) & 0xFF; /* ?C_XBP 仿真堆栈低8位*/r eturn ((void *)ptos); /* 返回最低地址,这里不用弹出栈顶指针是为了提高计算效率 */}②初始化定时器void InitTimer0(void) REENTRANT{TMOD=TMOD&0xF0; //屏蔽高四位TMOD=TMOD|0x01; /* 模式1(16位定时器),仅受TR0控制 */ TH0=TIMER_20MS_TH0;TL0=TIMER_20MS_TL0;E A=0; /* EA和ET0,51上电缺省值为0,EA将在OSStartHighRdy()中打开*/ET0=0; /* 满足在OSStart()前不产生时钟中断的要求,系统启动后第一时间开定时器T0中断 */TR0=1;}❖OS_CPU_A.ASM编写4个函数OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()❖OS_CFG.H主要为参数和使能的宏定义#define MAX_STK_SIZE 1024 /* 最大堆栈大小为1k*/#define OS_MAX_EVENTS 5 /* 应用程序中事件控制块的最大数量(必须大于零)*/#define OS_MAX_FLAGS 2 /* 应用程序中事件标志组的最大数目(必须大于零)*/#define OS_MAX_MEM_PART 5 /* 内存分区的最大数目(必须大于零)*/#define OS_MAX_QS 2 /* 应用程序中队列控制块的最大数目(必须大于零)*/#define OS_MAX_TASKS 11 /* 应用程序中任务的最大数目(必须大于2)*/#define TASK_START_PRIO 2 /* 应用程序开始优先级*/#define OS_LOWEST_PRIO 12 /* 定义可分配的最低优先级(必须大于63)*/#define TASK_STK_SIZE 512 /* 默认任务堆栈大小*/#define OS_TICKS_PER_SEC 50 /* 设置每秒节拍数*/#define TIMER_20MS_TH0 0x70 /* CPU=22.1184MHz, OS_TICKS_PER_SEC=50, TH0=0x70 */#define TIMER_20MS_TL0 0x00 /* CPU=22.1184MHz, OS_TICKS_PER_SEC=50, TL0=0x00 */晶振频率为22.1184MHz时才有OS_TICKS_PER_SEC=50,OS_TICKS_PER_SEC=50。
uCOS II 移植笔记
uC/OS II 移植笔记2009.2.28其实之前很早就看过uC/OS II这个操作系统。
而且当时也看了一些材料。
但是后来自己头脑发昏,以为搞嵌入式就一定要搞Linux或winCE,再加个TCP/IP之类的才是。
最后吃力不讨好。
反而自信心受重挫。
最终呢,还是回归原始,回归最简单,最本质的那些东西。
这次呢,打算把uC/OS II这个操作系统移植到周立功公司的EASYARM2104上面。
为什么会有这样的想法呢。
其实本来是想自己实现一个操作系统的。
一个简单的内核也行。
也是呢,找了一大堆的编写操作系统的资料,还有一些国内外开源的嵌入式实时操作系统。
所以,当时我们科研小组在做第二次报告的时候,我选的题目就是FDGKos的设计。
我做完报告之后,吴老师说,我之前很多的师兄都有想实现一个系统的想法,但是,谈何容易呢。
它要求一个人有很高的编程水平,及对硬件、操作系统原理十分了解才行。
我后来反复的思考了吴老师说的这几句话。
也不是没有道理的。
那好。
我不一步到位。
我先把uC/OS II在LPC2104上面玩转了再说。
开始干活了才知道。
原来一切都没有自己想象的那么容易。
我很快了,花了几天时间,把绍贝贝学生翻译的那本书给啃了一遍。
然后迫不及待的想运行起来。
要运行起来,当然得先移植才行啊。
这移植的工作量也不小啊。
我想啊,没事,也当一次练兵的机会。
周立功写的书里面有移植笔记,我先按着他的笔记,把代码敲进去。
写入flash运行之后发现,我这程序,在系统初始化之后,创建了两个任务,但是这些任务只有刚开始执行以下,碰到有OSTimeDly()函数的时候,一调度,就没有办法回到那两个任务里面来。
而是一直执行空闲任务。
如果任务里面延迟函数用周立功写的DelayNS()函数的话,有没有问题。
这个问题一直困惑了我好久,也一直没有办法解决。
代码了一遍又一遍,代码也读了一遍又一遍。
最后火了。
直接建立一个ucos for lpc210x的工程模板。
一步一步教你使用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/O S 的源码发布在该杂志的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 上。
严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
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的一些基本概念。
ucosII 学习总结
UCOS II入门学习一、写在前面的话在进行学习ucos II之前,我们先考虑几个问题:1、ucos II是什么?-μCOS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。
2、那什么是操作系统,什么是内核?-非计算机相关专业的人,看到这个问题,可能就一下子吓怕了,要学习ucos II是不是一定要先从这些基础学起,是不是要去拿计算机专业的相关知识系统的学一次?个人觉得如果觉得真的很疑惑,可以先百度看看简单的概念,或者可以直接的跳过这个问题的答案,但是脑子里要有这个问题。
配套教材《嵌入式实时操作系统μCOS原理与实践》也有相关介绍;这个时侯可以先什么都不管,我们就以自己只写过简单的C代码的基础,去看看ucos II到底是什么东西。
代码框架二、二、代码框架这是卢有亮教程里的,在VC环境中的配套代码,在C51环境中的划分如下;我们看到基本上是一样的,只是与CPU有关的部分不同而已,而且对于我们的入门学习,这个部分不是我们的重点,这个到最后需要移植时再具体去分析。
现在我们的重点是与CPU无关的CORE即内核代码。
整个UCOS II最主要的代码就是这部分了。
剩下的是用户部分,这里面就是我们根据自己的需要编写的、实现某些具体功能的函数、变量集合。
然后与CPU有关的也是一些具体的功能函数,宏定义等。
现在,我们看到ucos II的所有代码都在这里了,你说很复杂吗,应该也不算,但是简单吗,也不见得。
下面我们看看最主要的、最核心的部分代码即CORE 里面的,到底用来干什么。
三、core内核的功能在具体分析这部分代码之前,我们首先看一个例子:如图:有一个服务员,为了充分利用时间,同时为三个窗口服务,而且要保证这三个窗口中,他觉得最重要的窗口先得到服务。
1、我们先看看他是怎么充分利用时间的:假设当前服务员为窗口3服务,在交谈过程中,窗口3的人需要思考或者接电话等,就是有别的事吧。
这时候服务员为了充分利用时间,不再等他思考完毕,直接给窗口2服务,如果窗口2又有事,服务员就又到窗口1服务,服务完了又回到2或者3中;就这样来回的跑在这三个窗口之间,如果服务员跑得很快,而且服务过程也很快,那么三个窗口的人都会觉得服务员在一直为自己服务。
uCOS-II 移植与深入实战指南
教程简介名称《uCOS-II移植与深入实战指南》作者WildFire Team@野火科技版本V1.0硬件平台野火STM32ISO/ISO-MINI开发板淘宝店论坛野火系列教程简介,可到论坛下载。
STM32篇《零死角玩转STM32》系统篇《uCOS-II移植与深入实战指南》GUI篇《emWin实战指南》GSM篇《野火WF-SIM900A数据手册》《野火WF-SIM900A用户手册》GPS篇《野火WF-NEO-6M模块数据手册》《野火WF-NEO-6M模块用户手册》开源共享共同进步!从0开始移植UCOS-II到野火STM32开发板前言uC/OS是一个微型的实时操作系统,包括了一个操作系统最基本的一些特性,如任务调度、任务通信、内存管理、中断管理、定时管理等。
而且这是一个代码完全开放的实时操作系统,简单明了的结构和严谨的代码风格,非常适合初涉嵌入式操作系统的人士学习。
很多人在学习STM32中,都想亲自移植一下uC/OS,而不是总是用别人已经移植好的。
在我学习uC/OS的过程中,查找了很多资料,也看过很多关于如何移植uC/OS到STM32处理器上的教程,但都不尽人意,主要是写得太随意了,思路很乱,读者看到最后还是不确定该怎样移植。
为此,我决定写这个教程,让广大读者真正了解怎样移植。
学前建议:C语言+数据结构Wildfire Team2011年11月3日1、官方源代码介绍首先我们下载源代码,官方下载地址:/page/downloads/ports/st/stm32(下载资料需要注册帐号)或者网盘下载:/c0jnhmfxcp我们需要下载的就是下面这个,因为我用到的开发板芯片是STM32F103VET6注意:下载的源代码开发环境是IAR编译器的。
我们使用的uCOS是2.86版本。
下载解压后可以看到Micrium含有三个文件夹:文件名说明AppNote s 包含uCOS-II的说明文件,其中文件Micrium\AppNotes\AN1xxx-RTOS\AN1018-uCOS-II-Cortex-M3\AN-1018.pdf是很重要的。
uCOS-II在STM32上的移植步骤
uCOS-II在STM32上的移植步骤前言:说点废话,网上有很多关于uCOS-ii 移植的文章,好多都是千篇一律,理论性很强,分析了一大堆虚头巴脑的东西,真想问他们,你确定你分析的这些东西是需要你做的工作吗?实操性严重欠缺。
这方面我也走了很多弯路,下面就将自己的移植过程一步步的记录下来,也给大家做做参考。
首先,简单总结一下移植的大概过程:(1)去uC/OS-ii 官网下载你要移植芯片CPU 的相关案例,不一定完全对应,那就找相应系列吧。
(2)编程环境一般有两种,分别是IAR 和MDK,这个根据你自己的编程环境进行下载。
(3)本案例需要将uC/OS-II 移植到STM32F103ZET6 上,而我使用的编程环境是MDK,很遗憾,官网上提供的案例是基于IAR 的,所以要基于IAR 的案例进行更改。
(4)使用MDK 创建一个无操作系统的最简单程序,确保这个程序能够使用,这样做的目的是为了一步步的排查错误,假如无操作系统时,都有错误,移植过程中也肯定会有编译错误,那么在排查错误的时候也就增加了难度,不会写物操作系统的简单程序怎么办。
那就不要往下看了。
(5)移植的最大的改动主要有两部分,一个是一些头文件的增减,另外一个就是向量表中PendSV_Handler 和SysTick_Handler 的修改。
这里我要吐槽一下,网上说了一大堆关于什么OS_CPU.H 的更改还有各种函数的的分析,这都是扯淡。
这些根本就不用移植者去修改,官网提供的案例都已经提供了,除非你选择移植的CPU 是比较偏的,那么这些东西需要移植者自己去编写。
好了,下面就开始详细的记录怎么去移植。
一、创建一个无操作系统的简单裸板系统1.创建源文件工程文件夹,如下图所示:其中文件夹CMSIS 为内核的接口,包含的文件如下图文件夹STM32_StdPeriph 为固件驱动文件夹,这个把STM32 的固件全都添加进去即可。
文件夹User 为其他文件,如下图所示:文件夹Output 和。
实验二 uCOS-II在windows下的移植
实验二uCOS-II在windows下的移植
一:实验目的:
1.掌握uCOS-II在windows下的移植。
二:实验内容:
完成实验环境搭建,并且将uCOS-II移植到d盘下。
三:实验步骤:
1.可以将该工程所需的五个文件:OS_CPU_A.ASM,OS_CPU_C.C,PC.C,TEST.C,Ucos_II.C
放到一个独立的文件夹中,添加的时候便于添加。
2.按照实验一的步骤建立工程
添加所需要的文件:
3.若是将工程建到同software文件夹同一磁盘,但并未如之前一样放到“software\uCOS-II\EX1_x86L\BC45\source\”路径下,在编译运行时会提醒:“unable to open includes.h”和“unable to open os_cfg.h”,解决方法如下:
方法一:将#include “includes.h”改为
“#include “..\SOFTWARE\uCOS-II\EX1_x86L\BC45\SOURCE\includes.h””
将#include “os_cfg.h”改为
“#include “..\SOFTWARE\uCOS-II\EX1_x86L\BC45\SOURCE\os_cfg.h””
方法二:将“..\SOFTWARE\uCOS-II\EX1_x86L\BC45\SOURCE\”路径下的“includes.h”和“os_cfg.h”复制到工程所在的目录之下。
3.运行程序:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "os_cpu.h" #include "os_cfg.h" #include "ucos_ii.h" #include <reg51.h> #include <string.h>
9
7.1.7 OS_CPU.H
� OS_CPU.H中包括与处理器相关的常量、宏以及类型。
/******************* typedef unsigned typedef unsigned typedef signed typedef unsigned typedef signed typedef unsigned typedef signed typedef float typedef double typedef unsigned char char char int int long long
CPU 系统堆栈 被中止运行的任 务堆栈
……
SP
……
被运行的任务堆栈
……
片外的RAM用来存放任务堆栈,片内 RAM中是系统的公共堆栈,当系统运行某 个任务时,就要把该任务的堆栈映像复制 到系统堆栈中;而在中止这个任务时,再 把系统堆栈中的内容复制回任务堆栈映像 中。
图7-1 系统栈与任务栈的关系
6
7.1.4 uC/OS-II文件结构
用,而不必担心会破坏数据。 � 也就是说,可重入型函数在任何时候都可以被中断执行,过一段时间以后 又可以继续运行,而不会因为在函数中断的时候被其他的任务重新调用, 影响函数中的数据。 � 可重入的代码的实现主要是编程技术,所有嵌入式集成开发环境都能产生 可重入的代码。
int temp; void Swap(int *x, int *y) { temp = *x; *x = *y; *y = temp; }
例如,任务A和任务B都要调用函数 Swap(),而该函数又使用了全局变量 temp。 于是当任务A调用Swap()函数期间,系统发 生了任务切换而使任务 B也调用了Swap(), 那么任务B将要改变全局变量 temp的值,使 任务A传递给全局变量 temp的值丢失而出 现错误。 一般来说,一个可重入函数应该在函数中 只使用局部变量,因为函数的局部变量存 储在任务的堆栈中,所以可保证不同的任 务在调用同一个函数时不会发生冲突。
12
7.1.9 OS_STK_GROWTH
绝大多数的微处理器和微控制器的堆栈是从上往下长的。但是某些处理器 是用另外一种方式工作的。µC/OS-Ⅱ被设计成两种情况都可以处理,只要在 结构常量OS_STK_GROWTH(在OS_CPU.H中) 中指定堆栈的生长方式(如下 所示)就可以了。
�
置OS_STK_GROWTH为0表示堆栈从下往上长。 置OS_STK_GROWTH为1表示堆栈从上往下长。
图7-2 uC/OS-II的文件结构
7
7.1.5 需要修改的关键函数和宏定义
名称
OS_CRITICAL_METHOD OS_STK_GROWTH OS_ENTER_CRITICAL() OS_EXIT_CRITICAL() OSStartHighRdy() OSCtxSw() OSIntCtxSw() OSTickISR() OSTaskStkInit()
数据类型
(与编译器相关的内容) ********************/
int
BOOLEAN; IN32S; FP32; FP64; OS_STK;
10
7.1.7 OS_CPU.H(续)
/ ******************* 与处理器相关的代码 ********************/ #define OS_CRITICAL_METHOD ?? #if OS_CRITICAL_METHOD = = 1 #define OS_ENTER_CRITICAL() ?? #define OS_EXIT_CRITICAL() ?? #endif #if OS_CRITICAL_METHOD = = 2 #define OS_ENTER_CRITICAL() ?? #define OS_EXIT_CRITICAL() ?? #endif #if OS_CRITICAL_METHOD = = 3 #define OS_ENTER_CRITICAL() ?? #define OS_EXIT_CRITICAL() ?? #endif #define OS_STK_GROWTH #define OS_TASK_SW() 1 ???
3
7.1.1移植uC/OS-II满足的条件
� 处理器的C编译器能产生可重入代码。 � 在程序中可以打开或者关闭中断。 � 处理器支持中断,并且能产生定时中断(通常在10-100Hz之
间)。 � 处理器支持能够容纳一定量数据的硬件堆栈(可能达几KB) � 处理器有将堆栈指针和其他CPU寄存器存储和读出到堆栈(或 者内存)的指令。
2
7.1 uc/os-II 操作系统的移植
� 所谓操作系统的移植,是指使一个实时操作系统能够在某个特定的 微处理器平台上运行。 � µCOS-II的主要代码都是由标准的C语言写成的,移植方便。但仍需 要用汇编语言写一些与处理器相关的代码,这是因为µC/OS-Ⅱ在读 写处理器寄存器时只能通过汇编语言来实现。 � 移植的主要工作是修改部分与处理器硬件相关的代码。
功能
处理临界段方式选择 堆栈增长方向 进入临界区 退出临界区 就绪态最高优先级任务运行 任务级任务切换 中断级任务切换 时钟节拍 任务堆栈初始化
表7-1 需要修改的关键函数和宏定义
8
7.1.6 INCLUDES.H
� � � � 使得项目中的每个.c文件不用分别考虑它实际上需要那些头文件。 它会包含一些不相关的头文件 INCLUDES.H 是一个头文件,它在所有的.c文件的第一行被包含。 ” #include “includes.h includes.h”
唯一必要的函数是OSTaskStkInit(),其它九个属于钩子函数,必须得声明但没 必要包含代码。
15
7.1.11.1 OSTaskStkInit()
OSTaskCreate()和OSTaskCreateExt()通过调用OSTaskStkInt()来初始化任务的堆栈 结构,因此,堆栈看起来就像刚发生过中断并将所有的寄存器保存到堆栈中的情形 一样。 编写OSTaskStkInit()函数的第一步就是堆栈设计。需要考虑以下因素: ① CPU自动入栈的寄存器及压栈顺序。 ② 需要额外保存哪些寄存器。 ③ 所采用的编译器对形式参数的传递方法。 ④ 堆栈的增长方向。 ⑤ 堆栈指针是指向下一个可用空间还是指向上次入栈数据。 ⑥ 所采用的CPU是否存在系统堆栈。 ⑦ 堆栈深度。
13
7.1.10 OS_TASK_SW()
� OS_TASK_SW()是一个宏,它是在µC/OS-Ⅱ从低优先级任务切换到最高优先级任务时 被调用的。 �在µC/OS-Ⅱ中,处于就绪状态的任务的堆栈结构看起来就像刚发生过中断并将所有 的寄存器保存到堆栈中的情形一样。换句话说,µC/OS-Ⅱ要运行处于就绪状态的任务 必须要做的事就是将所有处理器寄存器从任务堆栈中恢复出来,并且执行中断的返回。 为了切换任务可以通过执行OS_TASK_SW()来产生中断。大部分的处理器会提供软中断 或是陷阱(TRAP)指令来完成这个功能。 � 例如,在Intel或者80x86处理器上可以使用INT指令。但是中断处理向量需要指向 OSCtxSw()。 � 一些处理器并不提供软中断机制。在这种情况下,用户需要尽自己的所能将堆栈结 当多任务内核决定运行另外的任务时,它保存正 构设置成与中断堆栈结构一样,再用函数调用方式来实现任务切换,也就是说通过函 在运行任务的当前状态,即 CPU寄存器中的全部 数来模仿软中断指令。如#define OS_TASK_SW()内容。这些内容保存在任务的当前状态保存区, OSCtxSw()
嵌入式操作系统原理
1
第七章: uCOS-II的移植
目标: 本章旨在向学员介绍uC/OS-II的 移植,通过本章的学习,学员应 该掌握如下知识: 1)移植uC/OS-II的一般性问题 2)在MCS-51系统上移植uC/OS-II 时的堆栈设计 3)移植的测试
时间:7.0学时 教学方法:讲授PPT+ 练习
也就是任务自己的堆栈区中。入栈工作完成后, 就是把下一个将要运行任务的当前状态从该任务 的堆栈中重新装入 CPU寄存器,并开始下一个任 务的运行,这个过程叫任务切换。
14
7.1.11 OS_CPU_C.C
OS_CPU_C.C文件包含10个C函数:
OSTaskStkInit() OSTaskCreateHook() OSTaskDelHook() OSTaskSwHook() OSTaskIdleHook() OSTaskStatHook() OSTimeTickHook() OSInitHookBegin() OSInitHookEnd() OSTCBInitHook()
#define OS_ENTER_CRITICAL() \ asm(“PUSH PSW”); asm(“DI”);
� 三种实现方法。 方法1: 在 方法2: 方法3:
#define OS_EXIT_CRITICAL() \ 在OS_ENTER_CRITICAL()中调用处理器指令来禁止中断,以及 OS_EXIT_CRITICAL()中调用允许中断指令。 asm(“POP PSW”); void some_ucos_ii_service() { 是先将中断禁止状态保存到堆栈中,然后禁止中断。 OS_CPU_SR cpu_sr; cpu_sr = get_processor_psw(); 有些编译器提供扩展功能,可以得到当前处理器状态字的值。 disable_interrupts(); * µC/OS-II 临界代码段 */ / /* set_processor_psw(cpu_sr); }