uCOS操作系统及其移植
实操性最强: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和List主要是放那些编译产生的乱七八糟的文件,为了使工程代码更加简洁。
ucosII多核移植和扩展的原理以及注意事项
uC/OS-II是源码开放、可固化、可移植、可裁剪、可剥夺的实时多任务OS 内核,适用于任务多、对实时性要求较高的场合。
uC/OS-II适合小型系统,具有执行效率高、占用空间小、实时性优良和可扩展性等特点,最小内核可编译至2K。
uC/OS-II内核提供任务调度与管理、时间管理、任务间同步与通信、内存管理和中断服务等功能。
所谓RTOS移植,就是使一个实时内核能在某个微处理器或微控制器上运行。
大部分的uC/OS-II代码试用C写的,但仍需要用C和ASM写一些与处理器相关的代码,这是因为uC/OS-II在读写处理器寄存器时只能通过ASM实现。
要是uC/OS-II正常运行,处理器必须满足一定的条件:处理器的C编译器能产生可重入代码;用C语言就可以打开和关闭中断;处理器支持中断,并能产生定时中断;处理器支持能够容纳一定量数据的硬件堆栈;处理器有将SP和其他CPU reg读出和存储到堆栈或内存中的指令;uC/OS-II移植工作主要包括以下三个方面的内容:(1)修改与处理器核编译器相关的代码:主要在includes.h中,修改数据类型定义说明,OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()和堆栈增长方向定义OS_STK_GROWTH。
(2)用C语言编写10个移植相关的函数:主要在OS_CPU_C.C中,包括堆栈初始化OSTaskStkInit()和各种回调函数。
(3)编写4个汇编语言函数:主要在OS_CPU_A.ASM中,包括:_OSTickISR //时钟中断处理函数_OSIntCtxSW //从ISR中调用的任务切换函数_OSCtxSW //从任务中调用的任务切换函数_OSStartHighRdy //启动最高优先级的任务uC/OS-II移植的关键问题:(1)临界区访问:uC/OS-II需要先禁止中断再访问代码临界段,并且在访问完毕后重新允许中断,这就使得uC/OS-II能够保护临界段代码免受多任务或ISR的破坏。
ucosiii移植原理
ucosiii移植原理
uCOSIII(MicroC/OS-III)是一款开源的实时操作系统(RTOS),适用于各种嵌入式系统和实时应用。
uCOSIII的移植原理主要包括以下几个方面:
1. 硬件抽象层(HAL):首先,需要针对特定硬件平台(如STM32、ARM、AVR等)编写硬件抽象层代码。
硬件抽象层的作用是将硬件平台的特性和接口抽象成统一的、易于操作的接口,以便于上层应用程序和实时操作系统进行调用。
2. 移植uCOSIII内核:将uCOSIII内核代码移植到目标硬件平台,主要包括以下几个步骤:
a. 配置uCOSIII内核:根据目标硬件平台的特性,配置uCOSIII内核的参数,如内存大小、任务数量等。
b. 修改内核代码:根据目标硬件平台的实际情况,修改内核代码,以适应不同硬件平台的需求。
这可能包括:修改内存管理代码、时钟管理代码、中断处理代码等。
c. 编写初始化代码:编写初始化代码,用于在系统启动时初始化
内核及其相关组件。
3. 移植uCOSIII的应用实例:根据项目需求,编写基于uCOSIII的应用实例。
这可能包括:编写驱动程序、编写通信协议、编写应用程序等。
4. 集成测试:将编写好的硬件抽象层、内核及应用实例集成到一起,进行系统测试和调试,确保整个系统的稳定性和可靠性。
5. 优化与调试:根据实际运行情况,对系统进行优化和调试,以提高系统的性能和资源利用率。
总之,uCOSIII的移植原理主要包括硬件抽象层的编写、uCOSIII内核的移植、应用实例的编写、集成测试以及优化与调试。
通过这些步骤,可以将uCOSIII成功移植到不同的硬件平台,并应用于各种实时系统。
uCOS平台下的LwIP移植非常详细
1 下载LwIP...................................................................................... (2)2 建立一个最基本的工程......................................................................................... (2)3 把LwIP加入工程......................................................................................... (2)4 编写操作系统模拟层相关代码........................................................................................ . (3)操作系统模拟层移植说明――中文翻译..................................................................................... (3)编写操作系统模拟层.................................................................................... (6)准备工作――建立文件、定义数据类型及其它 (6)信号量操作函数................................................................................ (8)邮箱操作函数................................................................................ (13)实现sys_thread_new()函数................................................................................. (20)实现sys_arch_timeouts()函数................................................................................. (22)实现临界保护函数................................................................................ (25)扫尾――结束操作系统模拟层的编写................................................................................. (26)5 LwIP接口――初始设置及网络驱动........................................................................................ (28)准备工作――建立LwIP入口函数文件..................................................................................... (28)ilvInitLwIP().................................................................... (29)ilvSetLwIP()..................................................................... (30)ethernetif_init()――初始化底层界面..................................................................................... (35)ethernetif_init()函数分析................................................................................. (35)low_level_output()――链路层发送函数 (36)low_level_init()――网卡初始化函数...................................................................................38EMACInit()――网卡初始化工作的实际完成者 (40)ethernetif_input()――实现接收线程...................................................................................47low_level_input()――得到一整帧数据.................................................................................49GetInputPacketLen()――获得帧长................................................................................. (50)EMACReadPacket()――复制,从接收缓冲区到pbuf (53)EMACSendPacket()――发送一帧资料................................................................................. (55)编译――及................................................................................. (56)6 ping――结束LwIP的移植......................................................................................... (57)编译、链接整个工程.................................................................................... (57)ping测试...................................................................................... (59)后记......................................................................................... .. (62)本文将指导读者一步步完成LwIP在开发环境下的移植工作,包括底层驱动的编写。
嵌入式实时操作系统UC/OS-Ⅱ及在DSP上的移植
应用 于 各种 系统 中,性能 值得 信 赖 。
2 可 移 植性 好 _ 2
U / — 绝大 多数 源 码 用ANS C OSI I I C写成 ,与 处
能 随时 被 中断 ,这是 多任务运 行 的基 本要 求 。 2 . 3可裁 剪及 可 固化 以 T 30 26 目 标 C U时 , UCOSI的 MS 2 C 0 为 P / — I
关 键 词 :UC O — 移植 / SI I 中 图分 类号 :M7 9 T 6
T 3 0 2 6DS 。 MS 2 C 0 P
Ke y wor :UC/ I Trns a t TM S3 ds O —I a pl n 20C2 SP 06D
文献标识码 : B
1前 言 .
广州 南方 电力集 团科技 发 展有 限 公司 詹兴 俊
Gun z o na gP we ru ce c a g h uNa fn o r o pS i e&T cn lg e eo me t o L d Z a njn G n eh oo yD v lp n . t. h nXigu C
维普资讯
嵌 人式实时操 作系统U / — 及在DS 上的移植 COSI I P
嵌 入 式 实 时 操 作 系统UC OSI 在 DS 上 的 移 植 / —及 I P
UC/ S・IEm be ・ e I sa tOp r to yse a t r ns l n o DSP O ・ I d- t yp n t n e a i n S t m nd isT a p a t t
Ab t a t I i p p r t e f a e fUC/ —I si t d c d b if , h y a d n t e o st n p a t o TM S 2 C2 6 s r c : n t s a e , h e t so h ur OS I i r u e r l t e wa n o i sf ri a s ln n o ey c t r t 30 0 DS r n l z d i ea l a dt e o e ai n st t no / —I n T S 2 C2 6 DS a e n a s a i ae . P a ea a y e d t i n p r t i i f n , h o ua o UC OS I i M 3 0 0 Ph sb e lo v l td d
UCOSII移植过程及心得
UCOSII V2.86在LPC2378上的移植(编译器ADS1.2)忙了几天,终于移植成功了。
移植UCOS需要准备一些东西,首先当然是OS源代码,再就是选定编译器,需要弄清一下几点:1、UCOS需要移植的内容2、编译器的特性(在这里主要是ATPCS)3、处理器的特性(这里主要注意ARM7的模式)以下先简要说一下这几点,为后面的程序说明做准备首先说说第一点,UCOS需要移植的内容。
1、数据类型的定义,这个根据平台来处理。
具体代码如下:2、任务切换函数,就是两个任务环境之间的切换。
3、处理临界代码前要关闭中断,之后再打开,这个实现的方法与平台关系很大。
4、栈的初始化,栈中保存的是任务的运行环境,不同的处理器中的寄存器自然是不一样的。
5、还有一个和任务切换差不多的,这个函数只运行一次,就是将第一个运行的任务的运行环境复制到CPU中。
再说说编译器的特性,ATPCS规定(想要详细一些的可以看看ADS 的帮助文档):R0-R3用来传递参数,R4-R12用来处理局部变量。
这个在处理汇编和C的接口时十分重要。
最后是CPU的特性。
ARM7有7种模式,但是有些模式对于UCOS在ARM7上的运行用处不大,经过综合考虑,可以只使用四种模式:SVC:运行OS代码和用户代码SYS:用于IRQ的嵌套处理,(暂时还未实现)IRQ:处理中断,处于OS的控制范围内FIQ:独立于操作系统,处理快速中断有了上面的说明,下面可以具体讨论了,因为网页中显示代码及注释不方便,所以把它们放在了附件中。
标题中前面是内容,括号内是涉及到的需要移植的函数1、任务栈(OSTaskStkInit)任务栈相当于CPU的一个备份,可以这样认为,当运行一个任务时,将栈中的数据复制到CPU中,由于某种原因停止运行一个任务时将CPU复制到任务栈中。
ARM7的CPU需要保存的寄存器如下:PC任务断点LRR12R11R10R9R8R7R6R5R4R3R2R1R0CPSR还有一个栈指针SP,这个保存在任务控制块中。
实验一 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两个中断向量。
uCOSII在cortexM3上的移植方法和步骤
void void
OS_CPU_SysTickInit(void); OS_CPU_SysTickClkFreq(void);
3. 修改 OS_CPU_C.C: 将以下代码注释掉:
4. 修改 OS_CPU_A.ASM: 由于编译器的原因,将“PUBLIC”关键词改为”EXPORT”. 并将原来的: RESG CODE: CODE:NOROOT(2) 修改为:
二、 建立存放目录:
在选定的逻辑盘上新建一个文件夹,如: LED,在 LED 文件夹下面新建下面 5 个文件夹, 如下图所示:
这些文件夹存放内容分配如下: 1. BSP: 主要用来存放板级支撑程序,如:功能模块初始化程序,端口初始化程序等。 2. Libraries: 用来存放 Stm32 官方库函数文件,这些库文件可以从官方网站下载得到, 本文中使用的版本是 3.5 版,进入 Ligraries 后可以看到下面两个文件夹:
3. Project: 存放工程文件,包括输出文件,列表文件等,具体存放内容再后面会有进 一步的介绍。 4. uCOS-II: 存放操作系统文件, 将前面讲到的文件夹 Ports 和 Sourec 连内容一起复制 到此文件下面,如下图所示:
2 / 12
5. User:存放用户源程序文件。
三、 创建工程:
1. 打开 Keil MDK,新建一个名为”LED”的工程,将工程文件存放在 LEDProject 文件下 面,控制器选 STM32F103RB。 2. 按下图建立 Project Target,Groups。
3 / 12
3. 在相应的 Groups 下面添加或者新建源程序文件和头文件:
4 / 12
ห้องสมุดไป่ตู้
在51系列单片机上移植uCOS
μC/OS II在MCS51单片机上的移植2008-05-29 12:07摘要:嵌入式系统融合了微电子、计算机软/硬件、通信和电子工程等多种技术、广泛应用于各种工业和民用领域,是科技集成创新的主要手段。
嵌入式操作系统也由于编程方式比传统方式有着明显的优越性,在越来越多的场合得到广泛的应用。
在中国,单片机具有相当广泛的使用基础,虽然51系列单片机功能相对较低,但是针对某些任务较简单、要求具备较高实时性的场合,研究嵌入式系统的移植还是具有重要的现实意义。
本文从探讨嵌入式系统移植的意义开始,通过阐述嵌入式系统在过去几十年期间的发展过程以及当今的发展现状,总结出嵌入式系统的发展趋势,并简要的描述μC/OS II在MCS51单片机上的移植方法,综合讲述了嵌入式系统移植这一课题的技术和背景。
关键词:μC/OS II 移植意义现状发展1 引言:单片机是电子信息行业最杰出的作品之一,由于它具有出色的面向控制能力,因此在工业控制、智能仪器仪表、家用电器、外设控制、机器人和军事装置等方面都得到了广泛的应用。
但是当面对多任务的应用场合时,如果没有精心复杂的设计以及丰富的后期维护调试经验,采用传统的编程方式设计往往会发生不可预料的错误且难以弥补。
此外,在这种条件下应用程序对硬件具有很强的依赖性,硬件只要稍微发生变化,软件就必须要作大量的变更和调试工作。
这也是限制单片机应用进一步发展的重要原因。
在电子技术迅猛发展的当今,随着实用电子系统的复杂化和系统实时性需求的提高,以及应用软件的系统化发展,嵌入式实时操作系统(Embedded Real-time Operating System)已经广泛地使用在各式各样的以单片机为代表的硬件平台上,从而很大程度的解决了多任务使用环境的需求问题。
在实际的生产生活中,使用着大量以MCS51为代表的8位单片机,虽然性能及存储空间有限,但是从经济方面考虑,对于某些应用场合,在8位MCU上使用操作系统依然是可行的。
基于STM32单片机的uCOS-II操作系统移植
第6期2020年12月机电元件ELECTROMECHANICALCOMPONENTSVol 40No 6Dec 2020收稿日期:2020-10-20基于STM32单片机的uC/OS-II操作系统移植张中前(贵州航天电器股份有限公司,贵州贵阳,550009) 摘要:网络技术和信息技术的发展,嵌入式系统应用越来越普及,嵌入式设备的应用也越来越多。
uC/OS-II广泛应用于路由器、飞行器及工业控制等。
uC/OS-II操作系统执行效率高,占用存储空间少,具有实时性及可扩展性等优点,在小型嵌入式设备中具有广泛应用。
本文介绍了基于ARMCORTEXM3系列单片机上的uC/OS-II移植,对电子控制组件的设计具有参考作用。
关键词:实时操作系统;uC/OS-II;内存管理;任务管理;STM32;移植Doi:10.3969/j.issn.1000-6133.2020.06.015中图分类号:TN784 文献标识码:A 文章编号:1000-6133(2020)06-0057-051 引言操作系统是裸机的第一层软件,操作系统直接运行在硬件上,上层软件通过提供应用程序接口(API函数),实现对底层硬件的访问,同时,通过操作系统实现对多个上层应用软件(任务)管理,实现对硬件CPU管理、存储管理、I/O接口管理及文件管理,如图1所示。
图1 操作系统功能组成示意图 STM32系列单片机以其优良的价格,大容量的FLASH及RAM存储空间,极易用于较为复杂的控制系统;在STM32单片机上进行uC/OS-II实时操作系统的移植,提高了产品的设计灵活性,实现较为复杂的系统功能;通过将开源的uC/OS-II移植在STM32单片机上,以其较为低廉的硬件成本获得较高的使用性能,具有良好的应用前景。
2 uC/OS-II操作系统2.1 uC/OS-II操作系统的基本特征uC/OS-II是一个完整的、可移植、可固化、可剪裁的基于优先级调度的抢占式实时多任务操作系统;它能够在外界事件或数据产生时,能够接收图2 uC/OS-II文件结构示意图并以足够快的速度响应,其处理的结果又能够在规定的时间内输出,并控制所有实时任务协调、一致运行。
嵌入式实时操作系统uc_OS_在MSP430F149上的移植应用
栈的上下文保存结构与任务切换的实现密切相
关, 所以, 在设计堆栈的上下文结构的时候, 必须
把能方便和快速地实现任务切换作为一个重要
因素来考虑。
4.3 OSStartHighRdy 的实现。操作系统初始
一步步移植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在51单片机上的移植
功能
处理临界段方式选择 堆栈增长方向 进入临界区 退出临界区 就绪态最高优先级任务运行 任务级任务切换 中断级任务切换 时钟节拍 任务堆栈初始化
表7-1 需要修改的关键函数和宏定义
6
7.1.6 INCLUDES.H
* * * * * * 文件名 : INCLUDES.H * 作者 : Jean J. Labrosse ****************************************************************************/
9
7.1.8 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()
临界代码的概念。 uC/OS-II定义的两个宏。
{ OS_ENTER_CRITICAL(); /* µC/OS-II 临界代码段 */ OS_EXIT_CRITICAL(); }
#define OS_ENTER_CRITICAL() EA=0 #define OS_EXIT_CRITICAL() EA=1 #define OS_ENTER_CRITICAL() \
例如,任务A和任务B都要调用函数Swap(), 而该函数又使用了全局变量temp。于是当任 务A调用Swap()函数期间,系统发生了任务 切换而使任务B也调用了Swap(),那么任务B 将要改变全局变量temp的值,使任务A传递 给全局变量temp的值丢失而出现错误。
一般来说,一个可重入函数应该在函数中只 使用局部变量,因为函数的局部变量存储在 任务的堆栈中,所以可保证不同的任务在调 用同一个函数时不会发生冲突。
/ ******************* 与处理器相关的代码 ********************/ #define OS_CRITICAL_METHOD ?? #if OS_CRITICAL_METHOD = = 1 #define OS_ENTER_CRITICAL() ?? #define OS_EXIT_CRITICAL() ?? #endif
ucos移植系统详解教程
Ucos 移植Ucos是一个微型的实时操作,包括了一个操作系统最基本的一些特性,如任务调度,任务通信,内存管理,中断管理,定时管理等。
Ports文件夹Cpu.h 定义数据类型,处理器相关的代码,声明函数原型;Cpu_c.c 定义用户钩子扩充函数,提供软件功能的入口点;Cpu_a.asm 与处理器相关的汇编函数,主要是任务切换函数;Os_dbg.c 内核调试数据和函数Source文件夹Ucos_ii.h 内部函数参数设置Os_core.c 内核结构管理,ucos的核心,任务切换,事件块管理等。
Os_time.c 时间管理,主要是延时Os_tmr.c 定时器管理Os_task.c 任务管理Os_mem.c 内存管理Os_sem.c 信号量Os_mutex.c 互斥信号量Os_mbox.c 消息邮箱Os_q.c 队列Os_flag.c 事件标志组Os_cfg.h 内核配置定义数据类型,处理器相关代码,声明函数原型。
全局变量OS_CPU_GLOBALS和OS_CPU_EXT允许我们是否使用全局变量。
#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif数据类型typedef unsigned char BOOLEAN;typedef unsigned char INT8U; /* Unsigned 8 bit quantity */typedef signed char INT8S; /* Signed 8 bit quantity*/typedef unsigned short INT16U; /* Unsigned 16 bit quantity*/typedef signed short INT16S; /* Signed 16 bit quantity*/typedef unsigned int INT32U; /* Unsigned 32 bit quantity*/typedef signed int INT32S; /* Signed 32 bit quantity*/typedef float FP32; /* Single precision floating point */typedef double FP64; /* Double precision floating point */typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide*/ typedef unsigned int OS_CPU_SR; /* Define size of CPU status register(PSR = 32 bits) */临界段Ucos定义两个宏来关中断OS_ENTER_CRITICAL() 和开中断OS_EXIT_CRITICAL()#define OS_CRITICAL_METHOD 3#if OS_CRITICAL_METHOD == 3#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}#endif栈生长的方向#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */任务切换宏#define OS_TASK_SW() OSCtxSw()函数原型开中断和关中断OS_CPU_SR_Save();OS_CPU_SR_Restore(cpu_sr);任务管理void OSCtxSw(void);void OSIntCtxSw(void);void OSStartHighRdy(void);void OS_CPU_PendSVHandler(void);需要自己编写/* See OS_CPU_C.C */void OS_CPU_SysTickHandler(void);void OS_CPU_SysTickInit(void);/* See BSP.C */INT32U OS_CPU_SysTickClkFreq(void);OS_CPU_C.C移植ucos时,我们需要编写9个钩子函数和一个任务堆栈结构初始化函数。
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嵌入式操作系统介绍与移植
OSStartHighRd
1、该函数是在OSStart函数中调用 2、负责从最高优先级任务的TCB中获得该任务的堆
栈指针sp,并依次将cpu现场恢复,这时系统就将 控制权交给用户创建的该任务进程,直到该任务被 阻塞或者被其他更高优先级的任务抢占cpu 3、该函数仅在多任务启动时被执行一次,用来启 动之前创建的第一个,也就是最高优先级的任务执 行
3、可从网站上获 得全部源码及其在各种体系结构平 台上的移植范例。
uC/OS-II特点
1、uC/OS-II内核具有可抢占的实时 多任务调度功能
2、提供了许多系统服务,如信号量、 消息队列、邮箱、内存管理、时间 函数等
3、这些功能可以根据不同的需求进 行裁减。
uC/OS-II的移植
ARM处理器相关宏定义
1、退出临界区
#defineOS_ENTER_CRITICAL() ARMDisableInt()
2、进入临界区
#defineOS_EXIT_CRITICAL() ARMEnableInt()
堆栈增长方向
1、堆栈由高地址向低地址增长,这个也 是和编译器有关的,当进行函数调用时, 入口参数和返回地址一般都会保存在当 前任务的堆栈中,编译器的编译选项和 由此生成的堆栈指令就会决定堆栈的增 长方向。
#define OS_STK_GROWTH 1
OS_CPU.c的移植
1、任务堆栈初始化 2、系统hook函数 3、中断级任务切换函数
任务堆栈初始化OSTaskStkInit
1、由OSTaskCreate或OSTaskCreateExt调用 2、用来初始化任务的堆栈并返回新的堆栈指针stk。
退出/进入临界区函数 ARMDisableInt/ARMEnableInt
嵌入式实时操作系统ucosII
嵌入式实时操作系统ucosIIucosII是一款源代码公开、可免费使用的嵌入式实时操作系统。
它是由德国嵌入式系统专家brosse于1992年编写完成的,主要适用于嵌入式系统的开发。
ucosII具有源代码短小精悍、可移植性好、稳定性高等优点,被广泛应用于各种嵌入式系统中。
源代码短小精悍:ucosII的源代码只有几百KB,相对于其他RTOS来说,其代码量较小,易于理解和修改。
可移植性好:ucosII采用了可移植性的设计方法,可以在不同的处理器和编译器上进行移植和优化。
稳定性高:ucosII在各种嵌入式系统中得到了广泛应用,其稳定性和可靠性得到了充分的验证。
支持多任务:ucosII支持多任务处理,可以同时运行多个任务,提高系统的效率和响应速度。
实时性:ucosII具有较高的实时性,可以满足各种实时性要求高的应用场景。
可扩展性:ucosII具有较好的可扩展性,可以根据需要进行功能扩展和优化。
系统内核:包括任务调度、任务管理、时间管理、内存管理等核心功能。
中断处理程序:处理各种中断请求,包括硬件中断、软件中断等。
系统API:提供了一套完善的API函数,方便应用程序的开发和调试。
调试和测试工具:包括各种调试和测试工具,如内存检查工具、性能分析工具等。
ucosII被广泛应用于各种嵌入式系统中,如工业控制、智能家居、智能交通、航空航天等。
其应用场景涵盖了消费类电子产品、医疗设备、通信设备、汽车电子等领域。
ucosII作为一款源代码公开、可免费使用的嵌入式实时操作系统,具有短小精悍、可移植性好、稳定性高等优点。
它广泛应用于各种嵌入式系统中,为应用程序的开发提供了便利和支持。
其可扩展性和实时性也使得它在各种领域中具有广泛的应用前景。
随着嵌入式系统的广泛应用,对嵌入式操作系统的需求也日益增长。
uCOSII是一种流行的实时嵌入式操作系统,具有轻量级、实时性、可扩展性等优点。
本文将介绍如何在AT91平台上实现uCOSII的移植。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
μC/OS-II的应用流程
μC/OS-II的初始 化,创建空闲任务
板级初始化
设置系统节拍
创建初始任务
创建用户任务
开启多任务调度 , 操作系统启动
删除初始任务
初始化函数 函数 OSInit( OSInit( ) 将对 ) μ 对数据结构进行初 C/OS-II 的所有的 在使用μC/OS-II的所有服务之 始化时,主要要创建包括空任务控制块 全局变量和数据结构进行初始化,同时 前,必须要调用 μ C/OS-II 的初 链表等空数据缓冲区。同时,为了可以 创建空闲任务OSTaskIdle,并赋之以最 始化函数 OSInit( )对μC/OS-II 快速地查询任务控制块链表中的各个元 低的优先级别和永远的就绪状态。如果 自身的运行环境进行初始化 。 素,初始化函数 用户应用程序还要使用统计任务的话 OSInit( )还要创建一个 数组 (常数 OSTCBPrioTbl[OS_LOWEST_PRIO OS_TASK_STAT_EN=1),则 + 1]OSInit( ,在这个数组中,按任务的优先级别 )还要以优先级别为 OS_LOWEST_PRIO-1来创建统计任务 的顺序把任务控制块的指针存放在了对 应的元素中
信号量及其操作
uC/OS-II的移植
移植就是修改一个软件,使得它能在新的环 境下(不同的处理器平台,或者不同的处理 器型号,或者不同的板子,或者不同的系统 下)运行 移植工作量取决于被移植软件的复杂程度和 移植的层次
举例
将linux移植到alpha处理器上,属于第一类: 移植到新的处理器架构上。工作量巨大,非高 手不能为 将linux移植到s3c2410上,属于第二类:移植 到不同处理器型号。工作量大大降低 将linux移植到你开发的开发板上,属于第3类: 移植到不同board上,如果你的board采用了如 s3c2410这样的处理器,则工作量很小 将QQ移植到linux平台上,属于第四类,把软 件移植到不同的系统(操作系统)上 ……
任务创建 的一般方法
应用程序通过调用 OSTaskCreate( ) 函数来创 建一个任务,OSTaskCreate( )函数的原型如下: INT8U OSTaskCreate ( void (*task)(void *pd),//指向任务的指针 void *pdata, //传递给任务的参数 OS_STK *ptos, //指向任务堆栈栈顶的指针 INT8U prio //任务的优先级 )
μC/OS-II的组成部分
核心部分(OSCore.c) 任务处理部分(OSTask.c) 时钟部分(OSTime.c) 任务同步和通信部分 与CPU的接口部分
μC/OS-II的组成部分(续)
核心部分是操作系统的处理核心,包括操作系统 初始化、操作系统运行、中断进出的前导、时钟 节拍、任务调度、事件处理等多部分。能够维持 系统基本工作的部分都在这里。 任务处理部分中的内容都是与任务的操作密切相 关的。包括任务的建立、删除、挂起、恢复等等 时钟部分即产生时钟节拍。任务延时等操作是在 这里完成的。
void main(void) { …… OSInit( ); //对μC/OS-II进行初始化 …… OSTaskCreate (TaskStart,……);//创建任务TaskStart 一般来说,任务可以在调用函数 OSStart( ) 启 OSStart( ); //开始多任务调度 } 动任务调度之前来创建,也可以在任务中来创 建。但是, μC/OS-II有一个规定:在调用启动 void TaskStart(void*pdata) { 任务函数 OSStart( ) 之前,必须已经创建了至 ……//在这个位置安装并启动μC/OS-II的时钟 少一个任务。因此,人们习惯上在调用函数 OSStatInit( ); //初始化统计任务 OSStart( ) 之前先创建一个任务,并赋予它最 ……//在这个位置创建其他任务 高的优先级别,从而使它成为起始任务。然后 for(;;) 在这个起始任务中,再创建其他各任务。 { 如果要使用系统提供的统计任务,则统计任务 起始任务TaskStart的代码 的初始化函数也必须在这个起始任务中来调用 } }
μC/OS-II的组成部分(续)
任务同步和通信部分为事件处理部分,包括信号 量、邮箱、邮箱队列、事件标志等部分;主要用 于任务间的互相联系和对临界资源的访问。 与CPU的接口部分是指μC/OS-II针对所使用的 CPU的移植部分。这部分内容由于牵涉到SP等系 统指针,所以通常用汇编语言编写。主要包括中 断级任务切换的底层实现、任务级任务切换的底 层实现、时钟节拍的产生和处理、中断的相关处 理部分等内容。
设计和开发,大大地提高了 应用程序的开发效率。
高级语言的接口
用汇编语言编写 的 硬件抽象层 计算机硬件
计算机操作系统的功能
任务管理
任务表
存储管理
存储 分表
处理器的管理
总之,需要一大堆表
操作系统
设备表
文件管理
文件 目录
网络和通信的 管理
I/O设备管理
操作系统的分类
实时系统
操作系统
分时系统
C/OS简介
计算机操作系统的作用
•它在计算机应用程序与计算 从用户的角度来看, 机硬件系统之间,屏蔽了计 算机硬件工作的一些细节, 它就是一大堆函数 并对系统中的资源进行有效 ( API 和系统函数), 的管理。
应用软件 操 作 系 统
用户可以调用(普 •通过提供函数(应用程序接 通调用或系统调用) 口(API)),从而使应用程 它们来对系统资源 序的设计人员得以在一个友 好的平台上进行应用程序的 进行操作。
μC/OS-II的 初始化
void OSTaskIdle(void* pdata) { # 在多任务系统运行时,系统经 if OS_CRITICAL_METHOD = = 3 OS_CPU_SR cpu_sr; 常会在某个时间内无用户任务 空闲任务只是做了一 #endif 个计数工作
μC/OS-II规定,一个 用户应用程序必须 可运行而处于所谓的空闲状态, pdata =CPU pdata; //防止某些编译器报错 系统提供的空闲任务 使用这个空闲任务, 为了使 在没有用户任务可执 for(;;) 行的时候有事可做, μC/OS-II { 而且这个任务是不 OS_ENTER_CRITICAL( );//关闭中断 提供了一个叫做空闲任务 能用软件来删除的 OSdleCtr++; //计数
OSTickISR( )。中断服务程序中会调用任务 切换函数来进行任务切换。
在使用信号量之前,应用程序必须调用函数 任 务 通 过 调 用 函 数 OSSemPend( ) 请 求 信 号 量 , 函 数 任务获得信号量,并在访问共享资源结束以后,必须要释放信 )的原型如下: 应OSSemPend( 用 程序如果不 需要某 个 信号 量建 了, 那个 么可 以调 用量 函数 OSSemCreate( ) 来 创 一 信 号 , 号量,释放信号量也叫做发送信号量,发送信号量需调用函数 OSSemDel( )来删除该信号量,这个函数的原型为: OSSemPost ( )。OSSemPost ( )函数在对信号量的计数器操作之前, OSSemCreate( )的原型为: void OSSemPend ( OS_EVENT *pevent, //信号量的指针 首先要检查是否还有等待该信号量的任务。如果没有,就把信 INT16U timeout, //等待时限 OS_EVENT *OSSemDel ( 号量计数器 OSEventCnt 加一;如果有,则调用调度器 OS_Sched( ) INT8U *err) ; // 错误信息 OS_EVENT *pevent, // 信号量的指针 OS_EVENT *OSSemCreate ( 去运行等待任务中优先级别最高的任务。 INT8U opt, //删除条件选项 函数 OSSemPost ( )的原型为: INT16U cnt //信号量计数器初值 参数 pevent INT8U *err 是被请求信号量的指针。 //错误信息 ); ); 为防止任务因得不到信号量而处于长期的等待状态,函数 INT8U OSSemPost ( OSSemPend 允许用参数 timeout设置一个等待时间的限制, OS_EVENT *pevent //信号量的指针 当任务等待的时间超过 timeout时可以结束等待状态而进入 ); 函数的返回值为已创建的信号量的指针 。 就绪状态。如果参数 timeout被设置为 0 ,则表明任务的等 待时间为无限长。 调用函数成功后,函数返回值为OS_ON_ERR,否则会根据具体 错误返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。
UCOS-ii操作系统及其移植
一
• 操作系统简介
二
• UCOS-ii操作系统 • 操作系统的移植 • UCOS-ii向430中移植
三
四
什么是计算机操作系统
(Operating System,OS)
•操作系统是一种为应用 程序提供服务的系统软 件,是一个完整计算机 系统的有机组成部分。
•从层次来看,操作系统 位于计算机硬件之上, 应用软件之下。所以也 把它叫做应用软件的运 行平台。
OSTaskCreate( )函数
μC/OS-II进行任务的管理是从调用
启动函数OSStart( )开始的,当然 其前提条件是在调用该函数之前至 少创建了一个用户任务
μC/OS-II的启动
调度时机 很容易想到的调度时机就 对于实时系统来说,应该尽 是定时调度。 可能地实现即时调度。
一般任务结束调用函数 OS×××Post ( ) 发送一个事件时, μ C/OS-II 与大多数计算机系统一样,用硬 注意!中断服务子程序运行结束 函数 OS_EventTaskRdy ( )将被函数OS ××× Post ( )所调用。 件定时器产生一个周期为 ms 级的周期性中 之后,系统将会根据情况进行一 该函数的作用就是把等待OS×××Post ( )所释放事件的任 断来实现系统时钟,最小的时钟单位就是 务在任务等待表中的位置清 0(解除等待状态)后,再把 次任务调度去运行优先级别最高 该任务在任务就绪表中对应的位置 1 ,然后引发一次任务 两次中断之间相间隔的时间,这个最小时 的就绪任务,而并不是一定要接 调度。 钟单位叫做时钟节拍(Time Tick)。 μ C/OS-II系统响应中断,当中断服务子程序的运行结束后, 续运行被中断的任务的 。 硬件定时器以时钟节拍为周期定时地产生 系统将会根据情况返回到被中止的任务继续运行或者转向 运行另一个具有更高优先级别的就绪任务。 中断,该中断的中断服务程序叫做