嵌入式操作系统内核原理和开发(任务创建和堆栈溢出检查)

上一篇 / 下一篇  2012-06-11 10:15:05 / 个人分类:Linux

虽然写操作系统的博客要比写普通的技术点要麻烦一些,但是心中还是挺开心的。一方面,通过几行代码就可以说明一些问题,把理论实践化,这本身就很具有挑战性;另外一方面还锻炼自己的沟通能力,让更多的人明白你的想法,认可你的想法。

#s*j4JZ/C0   其实,通过上面一篇博客,我们就已经清楚任务的创建是怎么一回事,但是我们还是愿意就这个问题讲得更细一点,说得更多一点。系统本身是多线程的,那说明 所有线程的地址空间都是共享的。由于资源都是操作系统本身提供的,所以线程本身的要求就很低,函数名、堆栈、入口点、堆栈大小、优先级,大体上也就是这么 多。至于这个堆栈是哪里的内存,其实已经不太重要了。为了简单起见,我们对原来的初始化函数 稍微修改了一下,

3L"GH(hs7QZ)n,_p0
51Testing软件测试网7k nA n0Rq3`/Ka~,^

void task_init()51Testing软件测试网X)yl,ib:K_)]+yj
{
G_e(z-N AK%~ E.x0 UINT32 unit = STACK_LENGTH;

|7B7}&Yu0

@&oqb.RASR0 memset((void*)data, 0, STACK_LENGTH * sizeof(UINT32));51Testing软件测试网6?2^Bl)@
 data[unit -1] = (UINT32) hello;
0cK.mK,F"D0 data[unit -2] = 0;
2n@ Y(zCn6L!}:q7c0 data[unit -3] = 0;
[O7g*}/i6A'}0 data[unit -4] = 0;51Testing软件测试网5N,|D$s ^ h#ie)[2Y
 data[unit -5] = 0;
~'g ^-m-ni;?0 data[unit -6] = 0;
2n1Ua8o.r4ef0 data[unit -7] = 0;
+_[ Ng*\FH7em0 data[unit -8] = 0;51Testing软件测试网2ge:i1L-XzCG|Z
 data[unit -9] = 0;51Testing软件测试网~5x#tJO5d2\
 data[unit -10] = (UINT32) &data[unit - 9];
@"x:I`*V Q'Q3h0 new = (UINT32) &data[unit -10];
{!yfe[)@5G)q0}

|l(zlq3DV0n0
51Testing软件测试网1SY{3s^^1|g

  上面的操作比较简陋,只是对堆栈进行了设置。这是线程初始化的时候必须要做的一步。当然,这里的hello就是我们的函数入口点。因为这里用SIGALRM代替的时钟中断是没有办法做到抢占的,所以我们可以人为多设置一些调度点,比如象这样,

#ikb]!c w*]0
void hello()51Testing软件测试网1n7\3a3h6` W
{
"@c|/FoA!k0 printf("count = %d in sub!\n", count ++);
.E nB*s+k#g+waP&x9G0 swap(&new, &old);51Testing软件测试网[ h2RP8e}
 printf("count = %d in sub!\n", count ++);51Testing软件测试网G3i0F We6S \
 swap(&new, &old);
Z_#A t4B+pb3r v+VP0 printf("count = %d in sub!\n", count ++);51Testing软件测试网*ZUtGF(j%_+c
 swap(&new, &old);51Testing软件测试网/G+~E qR c
 printf("count = %d in sub!\n", count ++);
0D RZ'bYXD0 swap(&new, &old);51Testing软件测试网(u4pjK6t-O
 printf("count = %d in sub!\n", count ++);
%Uj(z?~c3Y0 quit = 1;
5acK'X3j2K%x3I0 swap(&new, &old);
KMnQB#Q!e0}

%Ny)~dl.p/R0  在编写程序的时候,最恐怖的事情就是堆栈溢出了。但是在操作系统中,我们完全可以自己判断当前的堆栈是否已经溢出。因为我们知道,在线程调度的时候,保存的堆栈esp永远指向最低的那个地址。51Testing软件测试网a aI e'lk7[-@ }

YTJh#b5OF J N0int check_stack_overflow(unsigned int base, unsigned int current)51Testing软件测试网]"xbe1xp:?ETp
{
C/y ^-IW0    assert(0 != base && 0 != current);
51Testing软件测试网e:K"X[)~A7x2x

51Testing软件测试网,c b9J1[*y5BX:G&M

    return (current < base) ? 1 :0;
/o3oD&G6L"}-}.V0}

T#u6t x3I#Y0

9Uq:n1q&y AR [0  当然,这些说的都是线程调度的事,你也可以编写输入输出命令,实现对嵌入式操作系统的某种控制。要打印什么,设置什么,保存什么,都可以通过你的输入命令来解析执行,这些都是和signal处理是分开来的。后面这部分还要详细讨论,这里可以稍微添加一下,

6[,|b"fB#]3r0

1TB8G#cJM:e#JRm6U4w0int main()51Testing软件测试网f7[I:[.l!I9h `
{
\9{l@EV/Nu UK0 char val;

$y8Gf!E4ZV051Testing软件测试网1Lx9`+Zit)]D'f[

 task_init();
%A+d+gt,lcP0 set_timer();51Testing软件测试网3v9\ P Q5~x$|
 signal(SIGALRM, signal_handler);
51Testing软件测试网B;L)c N D9J

7cG t3nfx0 while(1)
,?%FV$~Q9JT*Q0 {51Testing软件测试网/i#V z1q4~-u5BT*S
     scanf("%c", &val);51Testing软件测试网rCC Fp*C
 }

+N d4BNO"O9J0

G Y6u/_6js+Iv@`0 exit(0);
7t3}*Os+N,G0s0 return 1;
+Z)vuK0LE9u?'^&d+{m&z0}

0u J3Ngua*Q H@0

*?#L)z!nq&mZ0最后,还是老规矩,附上详细的代码。虽然这一过程有点繁琐和冗余,但是至少看上去更完整一些。51Testing软件测试网Y~}V~*]$`

]K{@*e c+p{.KK0

H\.}q H0
51Testing软件测试网'[m~ A8m;IM

#include <stdio.h>
)K,s(Ch4U0#include <time.h>
+} q;@L/OJ0#include <stdlib.h>
b j,du+}G0#include <signal.h>51Testing软件测试网0XQ2T8p$E
#include <assert.h>
O9Gj E'xN0#include <sys/time.h>
51Testing软件测试网&V K_3h8w4k

/]B d MZ0#define UINT32 unsigned int51Testing软件测试网JT:\lJ~fb
#define STACK_LENGTH  512
51Testing软件测试网B/d Y(z@S8Y

51Testing软件测试网-Wa0n_pu)S5R

static struct itimerval oldtv;
0_)H&bt)T.|7x D D0UINT32 ld = 0;
5ocP$fo:kv _S0UINT32 new = 0;
7R8A5f [7}5iq#A ['O#?0UINT32 count = 0;51Testing软件测试网4DUK)v m,?0A {
UINT32 data[STACK_LENGTH] = {0};
q1M"x ^d6J2l o\,Z0UINT32 quit = 0;
51Testing软件测试网m(]8V9h e'K7AF

51Testing软件测试网!tIF:G.whKgW

void set_timer()51Testing软件测试网N5ZZ0r PH
{
`_ b-o P5i t0 struct itimerval itv;
b2Ep(T-e_ B0 itv.it_interval.tv_sec = 1;
{)DKhlTA I0 itv.it_interval.tv_usec = 0;51Testing软件测试网8kRP0~'@7`g+G C+?}
 itv.it_value.tv_sec = 1;51Testing软件测试网%Kz7z#f)shY
 itv.it_value.tv_usec = 0;
uU&H2i"c bPh0 setitimer(ITIMER_REAL, &itv, &oldtv);51Testing软件测试网rr&vP }C)I#c(`/L
}

$o$eY3T C*}051Testing软件测试网/I8c`6{Ik

void swap(UINT32* prev, UINT32* next)51Testing软件测试网`:me@;P,g#h$o V
{51Testing软件测试网4r-s(O5Hh8p3o
    __asm("push %%eax\n\t"51Testing软件测试网d;Svi1h)_b0cJ
          "push %%ebx\n\t"51Testing软件测试网;W;`y!vLTT K4r
          "push %%ecx\n\t"51Testing软件测试网 c%[kKR^
          "push %%edx\n\t"
I hA"u#e)c5R(]0C0          "push %%esi\n\t"51Testing软件测试网0N.`(yW1r{)O
          "push %%edi\n\t"
#X,x3^MDY(Y1x0          "push %%ebp\n\t"51Testing软件测试网gsD Mm&R'z
          "push %%esp\n\t"51Testing软件测试网 Hi3{O!ch{
   &nbsp; &nbsp; "lea 0x8(%%ebp), %%eax\n\t"51Testing软件测试网3Y'V'tv!w1P
   &nbsp; &nbsp; "mov (%%eax), %%eax\n\t"
"i"`kFi2\"R"K0   &nbsp; &nbsp; "mov %%esp, (%%eax)\n\t"
51Testing软件测试网1_ r |s:?E*o7u*y

51Testing软件测试网 D8I$Ee"O:c6V/n'F2B0b

   &nbsp; &nbsp; "lea 0xc(%%ebp), %%eax\n\t"
gRa d4~S_0   &nbsp; &nbsp; "mov (%%eax), %%eax\n\t"51Testing软件测试网(k4S.Yk R)TM
   &nbsp; &nbsp; "mov (%%eax), %%esp\n\t"
;a"s a ia$|Z A[7\\J0          "pop %%esp\n\t"51Testing软件测试网2KH!c.??-R ?/uU|D CH
          "pop %%ebp\n\t"
1l)K:Q_$`xfQ oGGl|0          "pop %%edi\n\t"
a)_U/D5n.R7m)nr.B0          "pop %%esi\n\t"51Testing软件测试网E`5pvp-y5TS
          "pop %%edx\n\t"
5g `,O1KGn,U0          "pop %%ecx\n\t"51Testing软件测试网O"bjJ}
          "pop %%ebx\n\t"
o+MR7^T0          "pop %%eax\n\t"
na dkq UZN0          ::);
.Gpp7a(B@%g7C0}
51Testing软件测试网 Ls%d.c1C(h2`

/u-H%}:[z nL\+^:UG0void hello()
7bZI ^+p)?-g0{
,zont1M0 printf("count = %d in sub!\n", count ++);
!yv3y2G!K-d C2Sh0 swap(&new, &old);
V^or7R1Vm#A0 printf("count = %d in sub!\n", count ++);
0p;_Rfd\2sJ7{ J0 swap(&new, &old);51Testing软件测试网5DZX7gSs+i
 printf("count = %d in sub!\n", count ++);
lC%cU0v5B H0 swap(&new, &old);51Testing软件测试网4d-krmH
 printf("count = %d in sub!\n", count ++);51Testing软件测试网C7y(Tj-fv
 swap(&new, &old);
s2s_ z(iZnl0 printf("count = %d in sub!\n", count ++);51Testing软件测试网0CQ9Z#T/Q
 quit = 1;51Testing软件测试网%rO.X+u)h-tL
 swap(&new, &old);51Testing软件测试网mq ?,x#E a(iT
}

'v(KzJ"i7m8q051Testing软件测试网xV*L)Z'z^zl5O mo

void task_init()51Testing软件测试网F1x!p_V S/T o
{51Testing软件测试网~D9~;u6z1I }/S"J
 UINT32 unit = STACK_LENGTH;
51Testing软件测试网N2~vN,mQi

51Testing软件测试网,qpQ{+C,^E

 memset((void*)data, 0, STACK_LENGTH * sizeof(UINT32));51Testing软件测试网;[ZBeL[
 data[unit -1] = (UINT32) hello;51Testing软件测试网k;UI T6t8~(E5_/j
 data[unit -2] = 0;51Testing软件测试网UnJWG E_9{%ow
 data[unit -3] = 0;51Testing软件测试网'~/g5Ky1C h5C6p
 data[unit -4] = 0;
YDRqN Ha#` ~0 data[unit -5] = 0;51Testing软件测试网cio7B~y6[XL!Aigx
 data[unit -6] = 0;
B{8Y*L)y/{pQ"d0 data[unit -7] = 0;51Testing软件测试网7U/H f\+DH
 data[unit -8] = 0;51Testing软件测试网W~.Us!vA
 data[unit -9] = 0;
-e*Wm:J ca1E\._0d0 data[unit -10] = (UINT32) &data[unit - 9];51Testing软件测试网R$w'?Y^,U%{3XI5M
 new = (UINT32) &data[unit -10];
3a MY,q}%P1w AO#N0}

2xr/V1x/_0

SB,Yp^ ?0int check_stack_overflow(unsigned int base, unsigned int current)
~~Qsi0{51Testing软件测试网a%m9O I v AE ww
    assert(0 != base && 0 != current);

}7eT E)B2{:TA%G8A0

a5W#MBa0    return (current < base) ? 1 :0;51Testing软件测试网y(Oc]-TW)PBYr7?)|
}

%h/p7ih&?;tyz3Z4p*|051Testing软件测试网@g.@D`f!M6ol.T

void signal_handler(int m)
E9]{ h!QE:D~p0{
\,G+\o1O z$z3w"s0 if(0 == quit) 
b R {;Evr+R0 {51Testing软件测试网3r/Z3^{"A fn!@'I
        swap(&old, &new);
8\;~%S5~2Vc R0     assert(0 == check_stack_overflow(data,new));51Testing软件测试网 xb;g a6uU8k
     return;
~%@2B$Uvq0 }

1Xh4VRF)c,Y]U0

DX.N*SH2Zw4T0   printf("count = %d in main!\n", count ++);51Testing软件测试网 qP s3M&_~6S
}
51Testing软件测试网P(c%V!Z\&?0]['b

51Testing软件测试网(N6C?)d G

int main()51Testing软件测试网W'q&p\ sch @WG e
{
"I;p?^2o%E7pW$G0 char val;
51Testing软件测试网C p1Hsak#i9p s

"V*|{-c5k8Jn.i0 task_init();
wXL#Pf {Rmz0 set_timer();51Testing软件测试网:_O-k-oE C'w
 signal(SIGALRM, signal_handler);

or-s,xB J ei051Testing软件测试网#a Zh.`\4r @KM

 while(1)51Testing软件测试网%s6F-@ JGh @&Z/k
 {51Testing软件测试网1PfwT'_^1}:J
     scanf("%c", &val);
eh5Q-x7J/z+k`,z}0~0 }
51Testing软件测试网+hwS*f;m

51Testing软件测试网 l\$u OK

 exit(0);51Testing软件测试网_;@ G-n*{"Um Nt
 return 1;
%W9i%r}t0}

SD;a(j;IN9Z0

相关链接:

X4W0F+b{0

嵌入式操作系统内核原理和开发(开篇)

K-xq|YoU` b0

嵌入式操作系统内核原理和开发(cpu的那些事)

bF{*y8ND*tx0

嵌入式操作系统内核原理和开发(中断)

f;x1lY@0

嵌入式操作系统内核原理和开发(地址空间)

2A/S;m |_0G0

嵌入式操作系统内核原理和开发(系统中断仿真)

,{:V ah,X| lk(a0

嵌入式操作系统内核原理和开发(线程切换)51Testing软件测试网~/lJ+wH AN


TAG:

 

评分:0

我来说两句

Open Toolbar