一种裸奔多任务嵌入式操作系统模型

合集下载

嵌入式实时操作系统

嵌入式实时操作系统

嵌入式实时操作系统嵌入式实时操作系统(Embedded Real-time Operation System,RTOS)。

1 嵌入式实时操作系统概念当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的嵌入式操作系统。

2 嵌入式实时操作系统特点1)多任务;2)有线程优先级3)多种中断级别3 嵌入式实时操作系统应用在工业控制、军事设备、航空航天等领域对系统的响应时间有苛刻的要求,这就需要使用实时系统。

采用嵌入式实时操作系统(简称RTOS)能够支持多任务,使得程序开发更加容易,便于维护,同时能够提高系统的稳定性和可靠性。

4 实时操作系统的必要性:首先,嵌入式实时操作系统提高了系统的可靠性。

其次,提高了开发效率,缩短了开发周期。

实时操作系统的优缺点:在嵌入式实时操作系统环境下开发实时应用程序使程序的设计和扩展变得容易,不需要大的改动就可以增加新的功能。

通过将应用程序分割成若干独立的任务模块,使应用程序的设计过程大为简化;而且对实时性要求苛刻的事件都得到了快速、可靠的处理。

通过有效的系统服务,嵌入式实时操作系统使得系统资源得到更好的利用。

但是,使用嵌入式实时操作系统还需要额外的ROM/RAM 开销,2~5% 的CPU 额外负荷,以及内核的费用。

5 实时系统与非实时系统的根本区别实时系统与非实时系统的根本区别在于:实时系统具有与外部环境及时交互作用的能力。

也就是说实时系统从外部获取信息以及系统得出结论要在很短的限制时间内完成。

它具有嵌入式软件共有的可裁剪、低资源占用、低功耗等特点;实时任务之间可能还会有一些复杂的关联和同步关系,如执行顺序限制、共享资源的互斥访问要求等。

实时操作系统所遵循的最重要的设计原则是:采用各种算法和策略,始终保证系统行为的可预测性(predictability)。

可预测性是指在系统运行的任何时刻,在任何情况下,实时操作系统的资源调配策略都能为争夺资源(包括CPU、内存、网络带宽等)的多个实时任务合理地分配资源,使每个实时任务的实时性要求都能得到满足。

四种常见的嵌入式操作系统方案

四种常见的嵌入式操作系统方案

四种常见的嵌入式操作系统方案常见的四种嵌入式操作系统嵌入式操作系统EOS(Embedded Operating System)又称实时操作系统RTOS(Real Time Operation System)是一种支持嵌入式系统应用的操作系统软件,它是嵌入式系统(包括硬、软件系统)极为重要的组成部分,通常包括与硬件相关的底层驱动软件、系统核、设备驱动接口、通信协议、图形界面、标准化浏览器Browser 等。

嵌入式操作系统具有通用操作系统的基本特点,如能够有效管理越来越复杂的系统资源;能够把硬件虚拟化,使得开发人员从繁忙的驱动程序移植和维护中解脱出来;能够提供库函数、驱动程序、工具集以及应用程序。

嵌入式操作系统负责嵌入式系统的全部软、硬件资源的分配、调度、控制、协调并发活动;它必须体现其所在系统的特征,能够通过装卸某些模块来达到系统所要求的功能。

在嵌入式实时操作系统环境下开发实时应用程序使程序的设计和扩展变得容易,不需要大的改动就可以增加新的功能。

通过将应用程序分割成若干独立的任务模块,使应用程序的设计过程大为简化;而且对实时性要求苛刻的事件都得到了快速、可靠的处理。

通过有效的系统服务,嵌入式实时操作系统使得系统资源得到更好的利用。

但是,使用嵌入式实时操作系统还需要额外的ROM/RAM 开销,2~5%的CPU 额外负荷。

到目前为止,商业化嵌入式操作系统的发展主要受到用户嵌入式系统的功能需求、硬件资源以及嵌入式操作系统自身灵活性的制约。

而随着嵌入式系统的功能越来越复杂,硬件所提供的条件越来越好,选择嵌入式操作系统也就越来越有必要了。

到了高端产品的阶段,可以说采用商业化嵌入式操作系统是最经济可行的方案,而这个阶段的应用也为嵌入式操作系统的发展指出了方向现在主流的嵌入式操作系统包括Linux、VxWorks、Windows CE、μC/OSⅡ等。

(一)嵌入式Linux这是嵌入式操作系统的一个新成员,其最大的特点是源代码公开并且遵循GPL协议,在近一年多以来成为研究热点,据IDG预测嵌入式Linux将占未来两年的嵌入式操作系统份额的50%。

如何设计一个小型嵌入式操作系统

如何设计一个小型嵌入式操作系统

如何设计一个小型嵌入式操作系统前言本文的目的是设计一个简单的嵌入式操作系统,只实现一个基本任务调度器的功能。

虽然不能称为操作系统,但已体现了小型嵌入式操作系统的精髓,可以从中一窥操作系统的面目。

一、多任务机制其实在单一CPU 的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。

但由于CPU执行速度非常快,加上任务切换十分频繁并且切换的很快,所以我们感觉好像有很多任务同时在运行一样。

这就是所谓的多任务机制。

实时系统的特征是延时可预测,能够在一个规定的时间内(通常是 ms 级别的)对某些信号做出反应。

二、任务的状态任务有下面的特性:任务并不是随时都可以运行的,而一个已经运行的任务并不能保证一直占有 CPU 直到运行完。

一般有就绪态,运行态,挂起态等。

运行态:一个运行态的任务是一个正在使用 CPU 的任务。

任何时刻有且只有一个运行着的任务。

就绪态:一个就绪态任务是可运行的,等待占有 CPU 的任务释放 CPU。

挂起态:某些条件不满足而挂起不能运行的状态。

三、如何转化为就绪态INT32U OSRdyTbl; /* 就绪任务表 */上面定义一个 32 位变量,每一位代表一个任务,0 表示挂起状态,1 表示就绪状态。

它记录了各任务的就绪与否状态,称它为就绪表。

OSRdyTbl 定义为 32 位变量,对应32 个任务。

当然,定义为 64 位的话,便最多能支持 64 个任务。

这样,可以定义两个宏,实现把任务的状态变为就绪或挂起态。

/* 在就绪表中登记就绪任务 */#define OSSetPrioRdy(prio) { OSRdyTbl |= 0x01时钟节拍,通常由定时器产生一个固定周期的中断来充当。

freertos原理、架构

freertos原理、架构

freertos原理、架构
FreeRTOS是一个开源的实时操作系统内核,它提供了一种多任务处理的机制,可以在嵌入式系统中运行。

它的原理和架构可以从以下几个方面来介绍:
1. 内核原理:
FreeRTOS的内核原理基于优先级抢占式调度。

它使用任务控制块(TCB)来管理任务的状态、优先级、堆栈指针等信息。

通过任务切换机制,可以实现多个任务之间的并发执行。

FreeRTOS还使用了轻量级的信号量、消息队列和互斥量等机制来实现任务间的同步与通信。

2. 架构:
FreeRTOS的架构包括内核、任务管理、时间管理、内存管理、中断处理等模块。

内核模块负责任务调度和切换,任务管理模块负责任务的创建、删除和切换,时间管理模块提供了定时器和延时函数,内存管理模块提供了动态内存分配和释放的功能,中断处理模块负责处理系统中断。

3. 内核组件:
FreeRTOS的内核组件包括任务管理、时间管理、内存管理、队列和信号量等。

任务管理模块包括任务的创建、删除、挂起和恢
复等功能;时间管理模块包括定时器、延时函数等;内存管理模块
包括动态内存分配和释放;队列和信号量用于任务间的通信和同步。

4. 可移植性:
FreeRTOS的架构设计具有高度的可移植性,可以方便地移
植到不同的处理器架构和开发环境中。

它提供了通用的接口和适配层,使得开发人员可以很容易地将FreeRTOS移植到各种嵌入式系统中。

总的来说,FreeRTOS的原理和架构是基于优先级抢占式调度的
实时操作系统内核,提供了任务管理、时间管理、内存管理、中断
处理等模块,具有高度的可移植性,适用于各种嵌入式系统的开发。

嵌入式实时操作系统简介

嵌入式实时操作系统简介

嵌入式实时操作系统简介嵌入式实时操作系统简介一:引言嵌入式实时操作系统(RTOS)是一类特殊的操作系统,用于控制和管理嵌入式系统中的实时任务。

本文将介绍嵌入式实时操作系统的基本概念、特点和应用领域。

二:嵌入式实时操作系统的定义1. 实时操作系统的概念实时操作系统是一种能够处理实时任务的操作系统。

实时任务是指必须在严格的时间约束内完成的任务,例如航空航天、工业自动化和医疗设备等领域的应用。

2. 嵌入式实时操作系统的特点嵌入式实时操作系统相比于通用操作系统具有以下特点:- 实时性:能够满足严格的时间要求,保证实时任务的及时响应。

- 可靠性:具备高可用性和容错能力,能够保证系统的稳定运行。

- 精简性:占用资源少,适应嵌入式系统的有限硬件资源。

- 可定制性:能够根据具体应用需求进行定制和优化。

三:嵌入式实时操作系统的体系结构1. 内核嵌入式实时操作系统的核心部分,负责任务和资源管理、中断处理和调度算法等。

- 任务管理:包括任务的创建、删除、挂起和恢复等。

- 资源管理:包括内存、文件系统、网络资源等的管理。

- 中断处理:负责中断的响应和处理。

- 调度算法:根据任务的优先级和调度策略进行任务的调度。

2. 设备管理嵌入式实时操作系统需要与各种外设进行通信和交互,设备管理模块负责管理设备驱动、中断处理和设备的抽象接口等。

3. 系统服务提供一系列系统服务,例如时钟管理、内存管理和文件系统等,以支持应用程序的运行。

四:嵌入式实时操作系统的应用领域嵌入式实时操作系统广泛应用于以下领域:1. 工业自动化:用于控制和监控工业设备和生产过程。

2. 航空航天:用于飞行控制、导航和通信系统。

3. 交通运输:用于车辆控制和交通管理。

4. 医疗设备:用于医疗仪器和设备控制和数据处理。

附件:本文档附带示例代码和案例分析供参考。

注释:1. 实时任务:Real-Time Task,简称RTT。

2. 嵌入式系统:Embedded System,简称ES。

ARM的十一种嵌入式操作系统

ARM的十一种嵌入式操作系统

ARM的十一种嵌入式操作系统ARM的十一种嵌入式操作系统嵌入式LINUX嵌入式Linux是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。

Linux做嵌入式的优势,首先,Linux是开放源代码;其次,Linux的内核小、效率高,可以定制,其系统内核最小只有约134KB;第三,Linux是免费的OS,Linux还有着嵌入式操作系统所需要的很多特色,突出的就是Linux适应于多种CPU和多种硬件平台而且性能稳定,裁剪性很好,开发和使用都很容易。

同时,Linux内核的结构在网络方面是非常完整的,Linux对网络中最常用的TCP/IP协议有最完备的支持。

提供了包括十兆、百兆、千兆的以太网络,以及无线网络,TokenRing(令牌环网)、光纤甚至卫星的支持。

移植步骤:1.Bootloader的移植;2.嵌入式Linux操作系统内核的移植;3.嵌入式Linux操作系统根文件系统的创建;4.电路板上外设Linux驱动程序的编写。

WinCEWinCE是微软公司嵌入式、移动计算平台的基础,它是一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操作系统,它是精简的Windows95,WinCE的图形用户界面相当出色。

WinCE是从整体上为有限资源的平台设计的多线程、完整优先权、多任务的操作系统。

它的模块化设计允许它对于从掌上电脑到专用的工业控制器的用户电子设备进行定制。

操作系统的基本内核需要至少200K的ROM。

一般来说,一个WinCE系统包括四层结构:应用程序、WinCE内核映像、板级支持包(BSP)、硬件平台。

而基本软件平台则主要由WinCE系统内核映像(OSImage)和板卡支持包(BSP)两部分组成。

因为WinCE系统是一个软硬件紧密结合的系统,因此即使CPU处理器相同,但是如果开发板上的外围硬件不相同,这个时候还是需要修改BSP来完成一个新的BSP.因此换句话说,就是WinCE的移植过程主要是改写BSP的过程。

嵌入式操作系统原理

嵌入式操作系统原理

嵌入式操作系统原理
嵌入式操作系统是一种专为嵌入式系统设计的操作系统。

它为嵌入式系统的硬件和软件提供了一个抽象层,使得开发者可以使用标准化的接口和工具进行开发。

嵌入式操作系统具有实时性、可扩展性和可靠性等特点,它负责管理系统的硬件和软件资源,提供系统级的服务,例如任务调度、内存管理、设备驱动程序等。

嵌入式操作系统的原理主要包括以下几个方面:
1. 任务调度:嵌入式操作系统通过任务调度器管理系统的运行。

它按照优先级、时间片轮转等策略对任务进行调度,使得系统能够高效地利用系统资源。

2. 内存管理:嵌入式操作系统提供了内存管理机制,使得开发者可以合理地分配和释放内存资源。

内存管理机制包括内存分区、内存映射、内存保护等。

3. 设备驱动程序:嵌入式操作系统通过设备驱动程序与硬件设备进行交互。

设备驱动程序是操作系统的一部分,它提供了对硬件设备的抽象接口,使得应用程序可以方便地使用硬件设备。

4. 系统初始化:嵌入式操作系统负责系统的初始化工作,包括启动引导、硬件初始化、系统配置等。

系统初始化是系统运行的前提条件。

5. 系统集成与测试:嵌入式操作系统提供了一系列的工具和接口,用于系统的集成与测试。

通过这些工具和接口,开发者可以方便地对系统进行集成和测试,确保系统的稳定性和可靠性。

嵌入式操作系统原理

嵌入式操作系统原理

嵌入式操作系统原理一、嵌入式操作系统的概念嵌入式操作系统是一种运行在嵌入式系统上的操作系统,其主要功能是管理和控制硬件资源,提供给应用程序一个良好的运行环境。

嵌入式操作系统通常包含任务调度、内存管理、设备驱动、文件系统等功能模块,以提供各种系统服务。

与一般计算机操作系统相比,嵌入式操作系统有着更高的实时性和可靠性需求。

二、嵌入式操作系统的特点1.高度实时性:嵌入式设备通常需要对外部环境做出及时响应,因此嵌入式操作系统需要具备高度实时性,能够准确响应和处理各种事件。

2.可嵌入性:嵌入式操作系统需要能够方便地移植到不同的硬件平台上,因此具备可嵌入性非常重要。

3.低功耗:嵌入式设备通常具有较低的功耗要求,嵌入式操作系统需要通过各种优化手段来降低系统的功耗。

4.小尺寸:嵌入式设备通常具有较小的存储容量,嵌入式操作系统需要具备小尺寸的特点,以节约存储空间。

三、嵌入式操作系统的功能模块1.任务调度:嵌入式操作系统需要具备任务调度的功能,能够合理分配系统资源,保证系统的实时性和可靠性。

常见的任务调度算法有优先级调度、轮询调度和抢占式调度等。

2.内存管理:嵌入式操作系统需要具备内存管理的功能,能够有效地管理系统的内存资源,包括动态内存分配和回收、内存保护和内存映射等。

3.设备驱动:嵌入式操作系统需要具备设备驱动的功能,能够管理和控制各种外部设备,包括传感器、执行器、通信接口等。

4.文件系统:嵌入式操作系统通常会包含文件系统的功能,能够提供对外部存储设备的读写访问,方便应用程序管理数据和配置文件。

5.网络支持:嵌入式操作系统通常需要具备网络支持的功能,能够提供网络通信的能力,包括TCP/IP协议栈、网络接口驱动等。

四、嵌入式操作系统的工作原理1.初始化:系统启动时,嵌入式操作系统会对硬件进行初始化,并设置系统的各种参数和配置,准备好系统运行的环境。

2.任务调度:嵌入式操作系统会根据任务的优先级和调度算法,决定将哪个任务分配给CPU执行,并根据实时性要求进行任务切换和调度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一种裸奔多任务模型一个网友的总结:stateMachine + timerTick + queue。

在RTOS环境下的多任务模型:任务通常阻塞在一个OS调用上(比如从消息队列取数据)。

外部如果想让该任务运转,就要向消息队列发送消息。

任务收到消息时,根据当前状态,决定如何处理消息。

这就是状态机。

任务将消息队列中的消息处理完毕后,重新进入阻塞状态。

任务在处理中,有时要延时一段时间,然后才继续工作:为了充分使用CPU,可以通过OS调用让其它任务去工作。

OS通常会提供一个taskDelay调用。

当任务调用taskDelay时,即进入阻塞状态,直到超时,才重新进入可工作状态(就绪状态)。

下面说说裸奔环境下的多任务模型:裸奔也可以多任务,但调度是由用户自主控制。

在RTOS环境下,一般提供抢占式调度。

在裸奔时,一般是任务在处理告一段落后,主动结束处理。

RTOS环境下的任务,一般处于一个while(1)循环中。

while(1){从消息队列接收消息。

如果没有,将阻塞。

处理消息。

}裸奔下的任务,一般采用查询方式:{查询是否有待处理的事件。

如果没有,返回。

如果有,根据任务的当前状态,进行处理。

处理完毕后,可能返回,也可能将待处理事件全部处理完毕后再返回。

}裸奔任务其实也处于一个while(1)循环中,只不过这个循环在任务外部。

main(){A_taskInit(); //任务的初始化B_taskInit();...while(1){A_taskProc(); //任务的处理B_taskProc();}}状态机既适用于OS环境,也适用于裸奔环境。

但在裸奔环境下,状态可能被切分得更细。

例如后面讲的如何在裸奔环境实现taskDelay()。

消息队列既适用于OS环境,也适用于裸奔环境。

在OS环境下,消息队列机制由OS提供。

在裸奔环境下,消息队列要自己来实现。

如果对队列的概念不清楚,可参考《数据结构》教材。

这个队列机制,可做成通用模块,在不同的程序中复用。

消息队列用于缓冲事件。

事件不知道什么时候会到来,也不能保证来了就能迅速得到处理。

使用消息队列,可以保证每个事件都被处理到,以及处理顺序。

一般在两种情况下会用到消息队列:存储外部事件:外部事件由中断收集,然后存储到队列。

串口接收程序中的接收循环缓冲区,可理解为消息队列。

任务间通讯:一个任务给其它任务发送消息。

timerTick,就是系统中的时钟基准。

OS中总是有一个这样的基准。

在裸奔时,我们要用一个定时器(或RTC或watchdog)来建立这个时间基准。

一个tick间隔可以设置为10ms(典型RTOS的缺省设置)。

让定时器10ms中断一次,中断发生时给tickNum++。

以前,我在定时器中断中设置1S标志、200ms标志等等。

时间相关的任务根据这些标志判断是否要执行。

近来,一般让任务直接去察看tickNum。

两次相减来判断定时是否到达。

也可以在系统中建立一个通用定时器任务,管理与不同任务相关的多个定时器;在定时到达时,由定时器任务去调用相应的callback。

系统时钟基准是所谓“零耗时裸奔”的基础。

timerTick的分辨率,决定了只适于于较大的时间延时。

在做时序时的小延时,用传统方法好了。

OS中的taskDelay()在裸奔环境下的一种实现:OS环境:void xxxTask(void){while(1){//waitEvent//do step_1taskDelay(TIME_OUT_TICK_NUM);//do step_2}}裸奔环境:void xxxTask(void)static unsigned int taskStat = STA T_GENERAL; //任务状态变量static timer_t startTick;timer_t currTick;if (taskStat == STA T_GENERAL){//check event//if no eventreturn;//do step_1startTick = sysGetTick(); //sysGetTick()就是察看系统时间taskStat = STAT_WAIT;return;}else if (taskStat == STAT_WAIT){currTick = sysGetTick(); //sysGetTick()就是察看系统时间if ((currTick - startTick) >= TIME_OUT_TICK_NUM){//do step_2taskStat = STA T_GENERAL;return;}elsereturn;}}老生常谈---一种裸奔多任务模型ourdev_629752P0O6JH.txt(文件大小:4K)(原文件名:老生常谈---一种裸奔多任务模型.txt)C51多任务编程思想ourdev_629753EW A0LM.pdf(文件大小:143K)(原文件名:C51多任务编程思想.pdf)基于51单片机的C语言多任务操作完美版ourdev_629754PETS4B.rar(文件大小:3K)(原文件名:基于51单片机的C语言多任务操作完美版.rar)Easy51RTOS的原理//Easy51RTOS操作系统头文件#include "os_cfg.h"#include "functns.h" //常用一些功能函数unsigned char TempBuffer[6]; //显示温度字符串unsigned char str2[12]={' ',' ',' ',0,0,0,0,0,0,0xdf,0x43,0}; //任务0:测温度送显void task0(void){temp=ReadTemperature();IntToStr(temp,TempBuffer);str2[3]=TempBuffer[0];str2[4]=TempBuffer[1];str2[5]=TempBuffer[2];str2[6]=TempBuffer[3];str2[7]=TempBuffer[4];str2[8]=TempBuffer[5];GotoXY(0,1);Print(str2);delay_nms(300);}//任务1:键盘扫描,LCD显示void task1(void){if(CHANGE==0) //判断change温度键是否按下{set_temp=key_set(); //设定需要更改的温度值if(set_temp<temp){fengshan(); //设定的温度<实际温度,则打开电机风扇}else if(set_temp>temp){dianlu(); //若大于,则打开电炉(这里用LED模拟一下) }}}//任务2void task2(){}//任务3void task3() {}//任务4void task4(void) {}//任务5void task5(void) {}//任务6void task6() {}//任务7void task7(){}//main主函数void main(void){OS_InitTimer0();EA=1;LCD_Init();LCD_w_data(1,1,Temp_Str);LCD_w_data(2,1,Key_Str);while(1){if (OS_Delay[0]==0){task0();OS_Delay[0]=100;} //温度测量,每秒1次if (OS_Delay[1]==0){task1();OS_Delay[1]=10;} //键盘扫描,键值存储if (OS_Delay[2]==0){task2();OS_Delay[2]=100;} //读出存储的键值,LCD显示 if (OS_Delay[3]==0){task3();OS_Delay[3]=50;}if (OS_Delay[4]==0){task4();OS_Delay[4]=100;}if (OS_Delay[5]==0){task5();OS_Delay[5]=60;}if (OS_Delay[6]==0){task6();OS_Delay[6]=70;}if (OS_Delay[7]==0){task7();OS_Delay[7]=80;}Delay(50);//Taskturn;}}//定时中断服务void OS_Timer0(void) interrupt 1 using 2{uchar i;//CRY_OSC,TIME_PER_SEC在easycfg.h中配置TH0 = 255-CRY_OSC/TIME_PER_SEC/12/256;TL0 = 255-CRY_OSC/TIME_PER_SEC/12%256;//每节拍对任务延时变量减1 ,减至 0 后,任务就绪。

for(i=0;i<MAX_TASK;i++){if(OS_Delay[i]!=0) OS_Delay[i]--;}//Runing(On);}//和传统的前后感觉基本上是一样的…//唯一的优点呢,是感觉OS_Delay[n]数组起到了分配各Easy51RTOS的原理ourdev_629755MEIQGP.txt(文件大小:3K)(原文件名:Easy51RTOS的原理.txt)基于51单片机的C语言多任务操作完美版/*1.本程序不使用任何汇编指令2.由定时器T0产生中断,切换进程3.由于中断或调用子程序,要把PC堆栈,故可以以SP为基址的地方找到PC4.中断或子程序返回,要把SP出栈给PC,故可以操作SP改变程序入口5.本程序经调试运行电路图已上传6.程序编译是会有一个警告提示,为正常现象,因为保存R0-R7时,重新定义地址,出现地址覆盖的警告提示。

7.用户以此模板写程序只需写用户的进程子程序和用户初始化子程序,并把各进程参数放在规定地方,各程序放在规定地方就可以;所有的任务调度已处理好。

*///头文件#include<reg52.h>//#include<absacc.h>//#include<intrins.h>//宏定义#define uchar unsigned char#define uint unsigned int#define TN 65436//进程1,2,3执行时间之比为 T1:T2:T3 (时间单位us)#define TN1 55536 //1个进程循环周期内进程1执行的时间T1us TN1=(65536-T1)#define TN2 55536 //1个进程循环周期内进程2执行的时间T2us TN2=(65536-T1)#define TN3 55536 //1个进程循环周期内进程3执行的时间T3us TN3=(65536-T1)//#define N1 4 // 进程1的延时参数#define N2 4 // 进程2的延时参数#define N3 4 // 进程3的延时参数idata uchar temp[8] _at_ 0x00; //R0--R7uchar tempbf1[8]; //用于保存R0--R7 进程1uchar tempbf2[8]; //用于保存R0--R7 进程2uchar tempbf3[8]; //用于保存R0--R7 进程3//定义全局变量uint address1,address2,address3;uchar test1_1=0,test2_1=0,test3_1=0,PID=1;//各进程的标志位,是否为第一次执行,0第一次,非0非第一次;PID进程号;uint ac1,ac2,ac3; //, PC_Next; 各进程的初始地址寄存器.//test1 的参数由于进程切换时没有保存普通变量,//所以各进程的普通参数需要定义成全局变量.uint m1,i1,j1,k1;uchar table1[4];//在此加入用户进程1参数//test2 的参数int m2,i2,j2,k2;uchar table2[4];//在此加入用户进程2参数//test3 的参数int m3,i3,j3,k3;uchar table3[4];//在此加入用户进程1参数//声明//unsigned int Get_Next_PC(void);//调用子程序,获取PCvoid chushihua(void); //初始化函数void yonghuchushihua(void); //用户初始化函数void test1(void); //进程一void test2(void);void test3(void);//main函数void main(void){// PC_Next=Get_Next_PC();chushihua();ac1=(unsigned int)(test1); //获取进程1的入口地址ac2=(unsigned int)(test2); //获取进程2的入口地址ac3=(unsigned int)(test3); //获取进程3的入口地址yonghuchushihua();TR0=1;while(1);}//初始化时钟void chushihua(void){TMOD=0x01; //EA=1;ET0=1;TH0=TN/256;TL0=TN%256;}//中断处理,进程调度void time0() interrupt 1 using 1{ uchar ib;TR0=0;//进程顺序分配PID++;if(PID==4){PID=1;}//进程调度switch(PID){case 1:{if(test3_1!=0) //第一次否?{ //保存现场,还回地址address3=*((unsigned char *)(SP-4)); //PC的高字节address3 <<= 8;address3+=*((unsigned char *)(SP-5)); //PC的低字节 table3[0]=*((unsigned char *)(SP)); //现场保护table3[1]=*((unsigned char *)(SP-1)); //现场保护table3[2]=*((unsigned char *)(SP-2)); //现场保护table3[3]=*((unsigned char *)(SP-3)); //现场保护for(ib=0;ib<=7;ib++) //保护R0--R7{tempbf3[ib]=temp[ib];}}if(test1_1==0) //第一次执行{ //执行新进程,恢复现场test1_1=1;*((unsigned char *)(SP-4))=ac1>>8; //PC的高字节*((unsigned char *)(SP-5))=ac1 & 0x00ff; //PC的低字节}else //非第一次执行{ //执行新进程,恢复现场*((unsigned char *)(SP-4))=address1>>8; //PC的高字节*((unsigned char *)(SP-5))=address1 & 0x00ff; //PC的低字节*((unsigned char *)(SP))=table1[0]; //现场恢复*((unsigned char *)(SP-1))=table1[1]; //现场恢复*((unsigned char *)(SP-2))=table1[2]; //现场恢复*((unsigned char *)(SP-3))=table1[3]; //现场恢复for(ib=0;ib<=7;ib++) //恢复R0--R7{temp[ib]=tempbf1[ib];}}TH0=TN1/256;TL0=TN1%256;TR0=1;}break;case 2:{if(test1_1!=0) //第一次否?{ //保存现场,还回地址,否address1=*((unsigned char *)(SP-4)); //PC的高字节address1 <<= 8;address1+=*((unsigned char *)(SP-5)); //PC的低字节table1[0]=*((unsigned char *)(SP)); //现场保护table1[1]=*((unsigned char *)(SP-1)); //现场保护table1[2]=*((unsigned char *)(SP-2)); //现场保护table1[3]=*((unsigned char *)(SP-3)); //现场保护for(ib=0;ib<=7;ib++) //保护R0--R7{tempbf1[ib]=temp[ib];}}if(test2_1==0) //第一次{ //执行进程2,恢复现场test2_1=1;*((unsigned char *)(SP-4))=ac2>>8; //PC的高字节*((unsigned char *)(SP-5))=ac2 & 0x00ff; //PC的低字节}else //非第一次{ //执行进程2,恢复现场*((unsigned char *)(SP-4))=address2>>8; //PC的高字节*((unsigned char *)(SP-5))=address2 & 0x00ff; //PC的低字节*((unsigned char *)(SP))=table2[0]; //现场恢复*((unsigned char *)(SP-1))=table2[1]; //现场恢复*((unsigned char *)(SP-2))=table2[2]; //现场恢复*((unsigned char *)(SP-3))=table2[3]; //现场恢复for(ib=0;ib<=7;ib++) //恢复R0--R7{temp[ib]=tempbf2[ib];}}TH0=TN2/256;TL0=TN2%256;TR0=1;}break;case 3:{if(test2_1!=0){ //保存现场,还回地址address2=*((unsigned char *)(SP-4)); //PC的高字节address2 <<= 8;address2+=*((unsigned char *)(SP-5)); //PC的低字节table2[0]=*((unsigned char *)(SP)); //现场保护table2[1]=*((unsigned char *)(SP-1)); //现场保护table2[2]=*((unsigned char *)(SP-2)); //现场保护table2[3]=*((unsigned char *)(SP-3)); //现场保护for(ib=0;ib<=7;ib++) //保护R0--R7{tempbf2[ib]=temp[ib];}}if(test3_1==0){ //执行进程3test3_1=1;*((unsigned char *)(SP-4))=ac3>>8; //PC的高字节*((unsigned char *)(SP-5))=ac3 & 0x00ff; //PC的低字节}else{ //执行进程3,恢复现场*((unsigned char *)(SP-4))=address3>>8; //PC的高字节*((unsigned char *)(SP-5))=address3 & 0x00ff; //PC的低字节*((unsigned char *)(SP))=table3[0]; //现场恢复*((unsigned char *)(SP-1))=table3[1]; //现场恢复*((unsigned char *)(SP-2))=table3[2]; //现场恢复*((unsigned char *)(SP-3))=table3[3]; //现场恢复for(ib=0;ib<=7;ib++) //恢复R0--R7{temp[ib]=tempbf3[ib];}}TH0=TN3/256;TL0=TN3%256;TR0=1;}break;default:TH0=TN/256;TL0=TN%256;TR0=1;break;}}//以下部分是需要按用户要求添加的部分void yonghuchushihua(void) //用户初始化函数{//加入用户初始化函数}//进程一 P1演示二进制加法死循环void test1(void){while(1) //用户可以删除while(1)循环中的全部内容(演示用)安排用户进程 {for(i1=0;i1<256;i1++){for(k1=0;k1<=N1;k1++){for(j1=0;j1<=20;j1++)for(m1=0;m1<=113;m1++);} // 约1ms*T1/T1+T2+T3P1=i1;//P2=0x0;}}}//进程二P2演示二进制加法死循环void test2(void){while(1) //用户可以删除while(1)循环中的全部内容(演示用)安排用户进程 {for(i2=0;i2<256;i2++){for(k2=0;k2<=N2;k2++){for(j2=0;j2<=20;j2++)for(m2=0;m2<=113;m2++);}P2=i2;}}}//进程三 P0口演示二进制加法死循环进程3的延时参数void test3(void){while(1) //用户可以删除while(1)循环中的全部内容(演示用)安排用户进程 {for(i3=0;i3<256;i3++){for(k3=0;k3<=N3;k3++){for(j3=0;j3<=20;j3++)for(m3=0;m3<=113;m3++);}P0=i3;}}}/* //获取下一条语句地址:PCunsigned int Get_Next_PC(void){unsigned int address;address=*((unsigned char *)SP);address <<= 8;address+=*((unsigned char *)(SP-1));return address+4;}*/。

相关文档
最新文档