嵌入式操作系统内核原理和开发(多线程轮转)

上一篇 / 下一篇  2012-06-12 09:48:56 / 个人分类:杂谈

 之前我们也谈到了线程创建,基本上简单的系统就可以跑起来了,但是还没有到多线程运行的地步。所以,我们下面试图所要做的工作就是创建更多的线程,让更多的线程运行起来。为了做好这一点,首先我们需要对task_init重新修整一下,
51Testing软件测试网s"J{J*pPZ

void task_init(int index, UINT32 data[], int size, void (*func)())51Testing软件测试网\`.t*j)U'wP
{
Fl LCB'|0        UINT32 unit = size;

W o&A{"vQh051Testing软件测试网~Wi$V*M%S5}:s

        memset((void*)data, 0, size * sizeof(UINT32));
'O"p#b!C2J7sX&A1?7Lk$@0        data[unit -1] = (UINT32) func;
"Oq,BY`0        data[unit -2] = 0;51Testing软件测试网:Uoq8tO
        data[unit -3] = 0;51Testing软件测试网i4`[3Z[-P4^tx:Y
        data[unit -4] = 0;
Wt,bd m-B0        data[unit -5] = 0;51Testing软件测试网+NT^4M'C1R+S$A
        data[unit -6] = 0;51Testing软件测试网4}z9qr k&C r$b?
        data[unit -7] = 0;51Testing软件测试网*q[pv&l"p8I
        data[unit -8] = 0;51Testing软件测试网]1~e"^'sD8n
        data[unit -9] = 0;51Testing软件测试网wI;z R&wkXQ'Lx
        data[unit -10] = (UINT32) &data[unit - 9];
\go h9I7E0        new[index] = (UINT32) &data[unit -10];
g)jSa,CZf!x5?0}

O@ uj0P*UI.\s0
51Testing软件测试网j*w6c[;@ Zl&x

  这是一个创建线程的函数,有堆栈、大小、函数入口。那么,我们的函数什么时候创建呢,其实就是在系统的开始位置就可以,51Testing软件测试网zBoAj b-e

51Testing软件测试网5NAh?Q)}

void set_all_task()51Testing软件测试网%yQ_C]*_V
{
(@'W-~(g~%Pr"E0        int index;
51Testing软件测试网6eYu8pb8m

51Testing软件测试网B,bo(^2jhl

        for(index = 0; index < THREAD_MAX_NUMBER; index ++)51Testing软件测试网#bmT2a?\/H5g1I
            task_init(index, task_stack[index], STACK_LENGTH, hello);
YK8Q;b-I'Z(V7e0}

P4R+wlY1T6@&_j0
51Testing软件测试网|9f?(JN,a V

  既然任务创建没有问题,那么下面就会涉及到简单轮转的问题。其实我们的方法特别简单,就是根据current_thread_id叠加,每一个thread都有自己的运转机会。代码如下所示,51Testing软件测试网.B F!g/`'?3x

51Testing软件测试网U/[ B9ZT&i]4X*m

void signal_handler(int m)51Testing软件测试网6f2m&v'e(o
{51Testing软件测试网%HH?cB+_)B
        current_thread_id = current_thread_id % THREAD_MAX_NUMBER;
51Testing软件测试网3\3S3MG;W*aB[

51Testing软件测试网4bNK6s M1u3s

        if(0 == quit[current_thread_id])51Testing软件测试网z@+@,c(^hD? @
        {
mP URsu0            swap(&old, &new[current_thread_id]);
le'x]3E$`2r`0        }

x-]8O Toj pdn051Testing软件测试网r'E7[.F f1l"B

        printf("count = %d in main!\n\n",  count ++);
2O2P#TeHi'[ t7S0_ ~?0        current_thread_id ++;
x+sq[!N%K"y%\0}

;W+d YL P c^G:`D0

E y t,\ lkTO0  当然,为了要实现真正的多线程运行,我们还要保证线程始终在运行。要达到这一点也不是很复杂,只需要把子函数设计为while(1)即可,

p,t wE4F*E\:X{051Testing软件测试网!F'^%GVs7~7?

void hello()51Testing软件测试网f1Xci$@
{
s s \ `F.x,t0     while(1) {51Testing软件测试网]{ M Z!O8zrb
            printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);51Testing软件测试网RW F2s)f4F
            swap(&new[current_thread_id], &old);

N^E i0w x?051Testing软件测试网{aq:T{E

            printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
)k}@w#t _0            swap(&new[current_thread_id], &old);
s!C8r!{0I2W9|j3c0        }
xv?v9P3q0}

}#W8nv2Bo`*v051Testing软件测试网*B!OgZ)bih(n

基本上要做到以上几点就可以实现了,最后给出完整的代码,大家可以在linux系统好好试试这个代码。

1G`4m[x#N6b#n051Testing软件测试网rE_5d;e wEh(O-[

j@NK ny\OZ5k0

?0rG%_A3K0#include <stdio.h>
m.PI ]!I)BKe-t0#include <time.h>
;S/r3I$Vz0#include <stdlib.h>
7J6I'}l0R EO3|P0#include <signal.h>51Testing软件测试网 U"H"Ie(|x
#include <assert.h>
{}&\:l"v0#include <sys/time.h>

w&m&zyf2c }^e(`051Testing软件测试网/mD a1P7^ n*^t

#define UINT32 unsigned   int51Testing软件测试网 VKQv1M
#define STACK_LENGTH      512
ncmXu1W3\0#define THREAD_MAX_NUMBER 10
51Testing软件测试网-o%~1DW ? ^,o

1muxG+G'nc0struct itimerval oldtv;
$Bxdv/h }U0UINT32 old   = 0;
m1jl@@#w-ta0UINT32 count = 0;51Testing软件测试网V;H'y0\HQ
UINT32 task_stack[THREAD_MAX_NUMBER][STACK_LENGTH] = {0};
S d Y7LGF0UINT32 new[THREAD_MAX_NUMBER]  = {0};
,|?-d-l3n!U0UINT32 quit[THREAD_MAX_NUMBER] = {0};
HfHn0g iPz0UINT32 current_thread_id = 0;
51Testing软件测试网C X?lr%O&c4ZQ |P

51Testing软件测试网.~#mXn[ ZT5m ]&C

void set_timer()
z_(~.E'e"h%p0{51Testing软件测试网^JCHUH&V/NU
        struct itimerval itv;51Testing软件测试网u^Bg0UY
        itv.it_interval.tv_sec = 1;
0w?t`,mg0        itv.it_interval.tv_usec = 0;
Xwd5bN0        itv.it_value.tv_sec = 1;
!d,bt9E l4[V\0        itv.it_value.tv_usec = 0;51Testing软件测试网"Up\`/rt2yKiY8k
        setitimer(ITIMER_REAL, &itv, &oldtv);
\ xC"]3~v-Q$Y0}
51Testing软件测试网/D*HMY1~5w+cS

51Testing软件测试网f$V8z.q _?2AX

void swap(UINT32* prev, UINT32* next)51Testing软件测试网H`3z.Px3]0d
{
8z h G idT6E*d6_dH0    __asm("push %%eax\n\t"
zcxi+Z0          "push %%ebx\n\t"
WG-[ L ~||&~0          "push %%ecx\n\t"51Testing软件测试网 o;y*o?&o{
          "push %%edx\n\t"
9@i [4}CPn1]({L0          "push %%esi\n\t"
U*fa T)C r$R0          "push %%edi\n\t"51Testing软件测试网3t U MO+zY
          "push %%ebp\n\t"51Testing软件测试网'`g!]5sIp
          "push %%esp\n\t"51Testing软件测试网*Y!I6r3C4a(u
          "lea 0x8(%%ebp), %%eax\n\t"51Testing软件测试网 m+|3FuNt6Yb9z(k
          "mov (%%eax), %%eax\n\t"
/~"Knk1Oi0          "mov %%esp, (%%eax)\n\t"
51Testing软件测试网5[ \ mM0? f;W8[

51Testing软件测试网*H.sM4uL4e\A)m+z

          "lea 0xc(%%ebp), %%eax\n\t"
Gu0K&_&N4b0          "mov (%%eax), %%eax\n\t"
6jf)o%b qm0          "mov (%%eax), %%esp\n\t"
3~YI z'kfx0          "pop %%esp\n\t"
^/q Z Id.D/GW'MA0          "pop %%ebp\n\t"
~p@n8j0?%Y0          "pop %%edi\n\t"51Testing软件测试网k4Y1vz@\ F
          "pop %%esi\n\t"51Testing软件测试网ruOC^i!g
          "pop %%edx\n\t"51Testing软件测试网;TIF1q nlk*Y$L/y
          "pop %%ecx\n\t"
a2nA PS+i;oX%e1D2^"R0          "pop %%ebx\n\t"
;KGTLAMxV%^0          "pop %%eax\n\t"
|5A4Z(u i3H5A2@0Q8T0          ::);
)q3@qS6s xG8n0}

-_ L P4w r:L051Testing软件测试网5D0Fe!G"@p

void hello()
!X:s*p%u*Oh(Pse0{
,WP/@ {2z-k8e9[0     while(1) {
!h7g B7^'P \;`T0            printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);51Testing软件测试网~0Zn3w%B4Nn:]K
            swap(&new[current_thread_id], &old);
51Testing软件测试网$bg Iu"R6[-d$S:{

51Testing软件测试网4F$Z4b@g

            printf("id = %i, count = %d in thread!\n",current_thread_id,  count ++);
G n!o;Np.YtzjM^0            swap(&new[current_thread_id], &old);
B3o] V8g$M&aQ0        }51Testing软件测试网IK s4e.y wP
}
51Testing软件测试网+b&]ZE R*A+v+l

\G'u@2R[0void task_init(int index, UINT32 data[], int size, void (*func)())51Testing软件测试网PmF^7QH
{51Testing软件测试网-[ Q'W)u%t8a(k
        UINT32 unit = size;

6wDP3^"b1X#@/A051Testing软件测试网U|(Pdc%in3^

        memset((void*)data, 0, size * sizeof(UINT32));
y#C*^%b?Y@0        data[unit -1] = (UINT32) func;
'{N R(W$I4tF0@.t ~0        data[unit -2] = 0;
g,m,ZY ANT0        data[unit -3] = 0;51Testing软件测试网 C-N1`b t2{RH3K-i
        data[unit -4] = 0;
/Au&U&nMC0        data[unit -5] = 0;
BdC$Qf[2x:njf0        data[unit -6] = 0;51Testing软件测试网C(b F @ ZV*WW6Zi
        data[unit -7] = 0;
'G*C[2f @;RH0        data[unit -8] = 0;51Testing软件测试网.Z&?$tD8l| |
        data[unit -9] = 0;
`?zk6u.sv+d0        data[unit -10] = (UINT32) &data[unit - 9];51Testing软件测试网6Q4x.lZj-L:Xm
        new[index] = (UINT32) &data[unit -10];51Testing软件测试网K \wE"[xN3pU
}
51Testing软件测试网Dv9@3~uMO_&H0[u

2R#N`PN/q5nz h8G#d v0void signal_handler(int m)51Testing软件测试网rD~,L^1F C9m
{
+c(m `(B~(M7QAV2?0        current_thread_id = current_thread_id % THREAD_MAX_NUMBER;
51Testing软件测试网WR5m}F(N6w

iP]J9so0        if(0 == quit[current_thread_id])
+M3B2H7Ml]H0TZ0        {51Testing软件测试网:O yF#TX
            swap(&old, &new[current_thread_id]);
IR7@%VN*G:D r0        }

\t.JC"j9Uo9A051Testing软件测试网z#V4l2ij9P&}

        printf("count = %d in main!\n\n",  count ++);
T2p Q8i`5V{nR0        current_thread_id ++;
3^cc.o3C |c0}

L9n"ui~ p051Testing软件测试网-Ojs&Nm

void set_all_task()
?n\d)J zte0{
~B0V*A-emLI0        int index;
51Testing软件测试网H%KA:V:w4a0{

hk)e;t(EK:Dt0        for(index = 0; index < THREAD_MAX_NUMBER; index ++)51Testing软件测试网C2Wz.N!kx L1Y v
            task_init(index, task_stack[index], STACK_LENGTH, hello);51Testing软件测试网qf)oD7n
}

9KJ KH`051Testing软件测试网9H}R$`1V

int main()
2X|}{Cxl0{
7l jZ(Y@/{|'J;F0        char val;
51Testing软件测试网6J;R5h5_:r(u"u:s

UmK+t9pJi c v)o0        set_all_task();
g6w}*w!A0        set_timer();51Testing软件测试网_u.J4Pi
        signal(SIGALRM, signal_handler);

"|Kh9lwKA051Testing软件测试网#k)C'U/V7g+`#J9k

        while(1)
@\H5r3{0        {51Testing软件测试网(R'b o:iX#jG-]
            scanf("%c", &val);51Testing软件测试网"Je#^1q1F{n}F
        }

z?5yA]#V051Testing软件测试网 XG0e!Uumk `.P

        exit(0);51Testing软件测试网F-e2k!A8I#GS9@
        return 1;
+Tl;Ki0g7R0}

tqs0iU0

相关链接:

jbP1j-w'Rr Y0aYh0

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

a2Qo;Q}]0

嵌入式操作系统内核原理和开发(cpu的那些事)51Testing软件测试网1bF:NBq+J H

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

4\Z^;S2}A3o{0

嵌入式操作系统内核原理和开发(地址空间)51Testing软件测试网gE"Q!p6q

嵌入式操作系统内核原理和开发(系统中断仿真)51Testing软件测试网"H6jA%g4bYl2T

嵌入式操作系统内核原理和开发(线程切换)

kZG$n }1s'O0

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

x/X$x l^CYy+V0

TAG:

 

评分:0

我来说两句

Open Toolbar