首 页 用户登录 | ![]() |
|||
|
|||
按字母检索 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
按声母检索 | A | B | C | D | E | F | G | H | J | K | L | M | N | O | P | Q | R | S | T | W | X | Y | Z | 数字 | 符号 |
|
![]() |
您的位置: 5VAR论文频道 → 论文中心 → 理工论文 → 电子通信 |
|
|||||
setjmp构建简单协作式多任务系统 | |||||
收集整理:佚名 来源:本站整理 时间:2009-01-10 23:57:37 点击数:[] ![]() |
|||||
[本篇论文由上帝论文网为您收集整理,上帝论文网http://paper.5var.com将为您整理更多优秀的免费论文,谢谢您的支持] 关键词:协作式多任务 C语言 setjmp 引言 本文介绍的是利用标准C语言setjmp库函数实现的具备此特点的协作式多任务系统。从本质上讲,实时多任务操作系统应该具备按照优先级抢占调度的内核。然而,在实际应用中,抢中式的多任务某种程序上带来了用户程序设计时数据保护的困难,并且,具备抢占功能的多任务内核设计时困难也比较多,这会增加操作系统自身的代码,也使它在小资源单片机系统中应用较少;而协作多任务系统的调度只在用户指定的时机发生,这会大大简化内核和用户系统的设计,尤其本文实现的系统通过条件查询来放弃CPU,既符合传统单片机程序设计的思维,又带来了多任务、模块化、可重入的编程便利。 Setjmp是标准C语言库函数的组成部分,它可以实现程序执行中的远程转操作。具体来说,它可以在一个函数中使用setjmp来初始化一个全局标号,然后只要该函数未曾返回,那么在其它任何地方都可以通过longjmp调用来跳转到setjmp的下一条语句执行。实际上,setjmp函数将发生调用处的局部环境保存在一个jmp_buf的结构当中,只要主调函数中对应的内存未曾释放(函数返回时局部内存就失效了),那么在调用longjmp的时候就可以根据已保存的jmp_buf参数恢复到setjmp的地方执行。我们的系统中就是分析了setjmp标准库函数的特点,以简单的方式实现了协作式多任务。 1 演示程序 为了便于理解,首先给出多任务演示程序的源代码。这个程序演示了协作式多任务切换、任务的动态生成、多任务共用代码等功能,一共使用了init_coos初始化根任务(也就是C语言main函数)、creat_task创建新任务和WAITFOR查询条件这3个基本的系统调用。由于面向嵌入式系统,因而程序不会中止并且运行中也没有进行任何输出,需要借助适合的调试工具来理解多任务系统的运行。 example.c文件清单: #include<stdlib.h> #include“co-os.h” void tskfunc1(int argc,void *argv); void tskfunc2(int argc,void *argv); void subfunc(void); volatile int comt,test; int main(void){ int i; init_coos(400); creat_tsk(tskfunc1,12,NULL,400); creat_tsk(tskfunc2,0,NULL,400); i=0; while(1){ WAITFOR(comt= =8); while(i++<comt)test=i; comt++; } } void tskfunc1(int argc,void *argv){ int i; static int creat=0; if(!creat){ creat_tsk(tskfunc1,9,NULL,400); creat=1; } i=0; while(1){ WAITFOR(comt>argc); test=0x55; /*使用函数调用在子程序中测试WAITFOR*/ subfunc(); while(i++<comt)test=i^0xAA; } } void tskfunc2(int argc,void *argv){ while(1){ WAITFOR(++comt>15); comt=0; } } void subfunc(void){ int i; WAITFOR(comt<5); for(i=0;i<++)test=0x10*i; } 2 内核构成 内核包括一个供外部用户程序包含的头文件(co-os.h)和具体实现的源文件(co-os.c),它们提供了演示程序中用到的3个系统调用。 内核的实现代码假定了CPU堆栈是向下增长的,并且通过宏来直接操作堆栈指针。以下代码在Microsoft VC6 for x86、Borland C++ Builder 5.5、SDS CrossCode7.0 for 68K和GCC3.2 for AVR四种平台中测试过,只需在co-os.h头文件中定义相应的平台类型即可顺利编译。 (1)co-os.h文件清单 #include<setjmp.h> /*选择X86_VC6,X86_BC5,AVR_GCC或M68H_SDS.*/ #define X86_VC6 #define MAX_TSK 10 typedef struct { void (*entry)(int argc,void *argv); jmp_buf env; int argc; void *argv; }TVB; extern TCB tcb[MAX_TSK]; extern int task_num,tskid; void init_coos(int mainstk); int creat_tsk(void(*entry)(int argc,void *argv),int argc,void *argv,int stksize); #define WAITFOR(condition)do{ setjmp(tcb[tskid].env); if(!(condition)){ tskid++; if(tskid>=task_num)tskid=0; longijmp(tcb[tskid].env,1); } }while(0) (2)co-os.c文件清单 #include "co-os.h" #if defined(X86_VC6)defined(X86_BC5) #define SAVE_SP(p) _asm mov p,esp #define RESTORE_SP(p) _asm mov esp,p #elif defined(AVR_GCC) #include<io.h> #define SAVE_SP(p) p=(int*)SP #define RESTORE_SP(p) SP=(int)p #elif defined(M68K_SDS) #define SAVE_SP(p) asm("MOVE.L A7,{"#p"}") #define RESTORE_SP(p) asm("MOVE.L {"#p"},A7") #endif TCB tcb[MAX_TSK]; Int task_num=1; Int tskid; Static int stktop,oldsp; Void init_coos(int mainstk){ SAVE_SP(stktop); stktop=stktop+sizeof(void(*)(void))/sizeof(int) -(mainstk+sizeof(int)-1)/sizeof(int); } int creat_tsk(void(*entry)(int argc,void *argv), int argc,void *argv,int stksize){ if(task_num>=MAX_TSK)terurn-1; SAVE_SP(olds Tags: |
提供人:佚名 | |
【返回上一页】【打 印】【关闭窗口】 |
![]() |
5VAR论文频道 |
![]() |
5VAR论文频道 |
![]() |
关于本站 -
网站帮助 -
广告合作 -
下载声明 -
网站地图
Copyright © 2006-2033 5Var.Com. All Rights Reserved . |