实验一 2013、7、13
按照实验步骤,一步一步的来。程序运行正常。
接下来开始分析代码。
main函数在usermain.c中,在usermain.c中有一个全局变量initctsk,其具体的声明方式为
static T_CTSK initcstk;
其中T_CTSK为一个结构体,其具体的定义为:
typedef struct t_ctsk {
void *
exinf; /*
Extended information,32bit */
unsigned
long tskatr; /*
Task attribute,32bit */
void
(*task)();
/* Task startup address */
signed
int itskpri; /*
Priority at task startup */
signed
long stksz; /*
User stack size (byte) */
unsigned
char dsname[8];
/* Object name */
void
* bufptr;
/* User buffer */
} T_CTSK;
主函数代码如下:
EXPORT INT main( void )
{
/*
Initialize bsp sequence */
bsp_init();//
/*
Start uT/Kernel and Never return*/
initctsk.exinf = NULL;
initctsk.tskatr = TA_HLNG | TA_RNG0 | TA_DSNAME;
initctsk.task = (FP)&inittask;
initctsk.itskpri
= (MAX_PRI-2);
initctsk.stksz = 512;
strcpy(initctsk.dsname,
"inittsk");
initctsk.bufptr = NULL;
tk_sta_sys((T_CTSK
*)&initctsk);
return
0;
}
bsp_init()的具体实现先不管。在它之后的代码中,是对initctsk结构体的各项数据初始化数据,其中initctsk.task = (FP)&inittask对任务函数的地址进行赋值。然后通过tk_sta_sys()函数启动内核。
然后观察inittask函数,
EXPORT void inittask(W stacd,VP exinf)
{
usermain();
tk_ext_sys();
}
tk_ext_sys()为系统管理状态管理函数中的退出内核的系统函数。
接下来关注usermain. C函数:
EXPORT INT usermain( void )
{
ER
ercd;
ercd=TaskSample();
tm_putstring((UB*)"Push any key to shutdown the micro
Tenux.\n");
tm_getchar(-1);
return 0;
}
Usermain中调用了TaskSample()函数,TaskSample函数在文件taskSample中,再去看看tasksample函数,此函数分别通过tk_cre-tsk建立了三个任务,这三个任务的ID分别作为静态变量存在于文件TaskSample.c中。三个任务的属性分别为:TA_HLNG|TA_RNG0,通过查询内核规范得知,TA_HLNG:表示任务由高级语言编写。TA_RNG0:任务运行在保护级别0.
三个任务建立完成后,通过tk_sta_tsk()函数启动了任务B。结合这张图来理解程序
在试验程序中,一共有四个任务,分别为inittask,taskSampleA,taskSampleB,taskSampleC。
在main函数中,完成了对inittask的初始化并运行。
而其他三个任务的初始化分别在taskSample函数中。四个任务的优先级顺序为TaskA,TaskB,TaskC(以下简称A,B,C),inittask。
TaskSample函数完成了对任务A,B,C的初始化以及建立这三个任务。此时三个任务都处于dormant状态,当tk_sta_tsk(TaskID_B,5)函数执行后,B任务由DORMANT状态进入READY状态,再进一步进入RUNNING状态,
观察任务B的代码,任务B先启动了任务C,但是由于任务C的优先级不如任务B,任务C也只是从DORMANT进入了READY的状态。
之后任务B中开始了任务A,由于任务A的优先级是高于任务B的,所以任务B退出running,进入ready,任务A由dormant进入ready,再进入running。
在任务A中输出了一条A要睡觉的信息后,就通过tk_slp_tsk(1000)进入了wait,此时任务B和C均处于ready状态,但是由于B的优先级高于C,所以开始继续运行B任务,此时B任务进入了running,直至运行至getch()函数,等待用户的输入,输入回车,任务B继续运行,输出一条要睡觉的信息后,进入了wait状态,而此时任务A和任务B均处于wait状态,只有优先级最低的任务C处于READY状态,所以任务C由此而运行。
此时,我已经大致了解了任务直接从建立到运行各个状态的转换。
如果在任务B中输入字符e,
如果在任务B中输入字符e,任务B通过tk_ter_tsk()函数执行termin ate操作,将处于ready或wait状态的任务A和B分别退出原来的状态,进入了dormant状态,之后再通过tk_del_tsk()函数,将任务A和任务B分别进入了NON-EXISTENT状态,也就是删除了任务。之后再通过tk_exd_tsk()函数,直接从running状态进入了NON-EXISTENT状态。
至此我已大致认识了不同任务之间的切换和,任务的建立以及任务的删除的相关基本操作。
以上是我结合悠龙提供的内核规范、讲义、实验教程分析的这个程序,不足和错误的地方请多多指教。