⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os.txt

📁 本文面向首次接触uC/OS-II的程序员
💻 TXT
📖 第 1 页 / 共 4 页
字号:


个人空间 发短消息 加为好友 当前离线  1# 大 中 小 发表于 2008-11-6 14:42  只看该作者 
[原创]uc/OS-II内核小析
一个月前才开始看操作系统。; F% e9 `/ z2 N# y8 m! l. S
在广州书城五楼买到邵贝贝翻译的《uc/OS-II》第二版,花了我75大洋。
  _. R4 ` t  U; g5 W1 y心疼啊,所以要好好的看才行。6 D! S  c' n, I# W0 u
最近有些收获想发给同志们一起分享,不算成熟,望见谅。
9 I5 X" p+ N$ K0 {( z$ Y5 |2 `+ s9 K1 i6 f/ M3 D
原书第三章《内核结构》。
" F. b; x  k6 h' F! P第73页——章3.00    临界段就不必多说了,用三种不同方式关中断进入临界区。2 d8 U; L' B4 i  }
第76页——章3.01    任务,任务也很简单。
/ L% N  {# c( P9 O0 [8 {       任务是一个无限循环;
0 p" x" v+ r W       任务完成,可以将其删除;$ ~' o" Q: m6 R6 J
       每一个任务都有5种状态——睡眠、就绪、运行、等待、中断服务
" X7 S5 Z8 W; w0 z, I0 _) Z; K7 h+ Z! K: b$ U
第80页——章3.03    任务控制块
% l8 \/ V3 E, W每一个任务有一个任务控制块来保存其各种状态,以便于在各个状态之间切换。
8 y3 ]/ e! Z7 _" w+ |( W4 uOS_STK   OSTCBStkPtr——系统任务控制块,堆栈指针——当前任务的堆栈栈顶。
7 W1 r" d/ l: x ( O! _: B$ o  E1 d  ]( m4 [
Struct os_tcb  OSTCBNext——双向链表的后向指针。
7 w) |+ X) s( sStruct os_tcb  OSTCBPrev——双向链表的前向指针。1 I" j: L* \, r# N" O+ A! h

, `( L' ~- A' [INT16U  OSTCBDly——把任务延时若干时钟节拍,允许最大延时数。
) b4 {, R/ d( q! l' q% fINT8U  OSTCBStat——如果这个变量值==OS_STAT_READY时,任务进入就绪态。
/ L+ b% U( H5 ~1 {INT8  OSTCBPrio——任务的优先级,优先级越高,数值愈小。3 a, }9 z+ f* B; M V8 R1 d
2 y" F  Y8 q- y, F
INT8U  OSTCBX——priority0x07        : t  @$ _ Z! _2 q" g' B
INT8U  OSTCBY——priority>>3
' U- w! n) g+ t  q2 kINT8U  OSTCBBitX——OSMapTbl[priority0x07]
$ f/ \+ k7 u' `" h0 N# TINT8U  OSTCBBitY——OSMapTbl[priority>>3]9 q2 }+ J4 ]$ T6 k
加速进入就绪态算法,这个算法在下一个帖子再做讨论,用存储空间换取执行时间,很妙
) M3 G3 g; R* \ W( D- e 6 y$ E, V* F0 i, E1 v* y/ M: N! u  d; \% m
以上的数据结构是必有的,以下的可以根据用户自定义的功能在代码中有条件编译。8 }0 F. F9 T' a
{+ K+ H% _9 j8 ^( z2 C
Void--OSTCBExtPtr0 O6 d+ \5 Z) i1 ^( G+ c! `+ ~( I
OS_STK--OSTCBStkBottom
: C* Z! \. k4 t" @ c7 K' CINT32U--OSTCBStkSize4 ^3 r# Z2 a' f2 c4 M
INT16U--OSTCBOpt p  l  Q4 o, r0 D! E
INT16U--OSTCBId
/ G  s- P; }7 Z/ {4 ?- M. L" dOS_EVENT--OSTCBEventPtr/ G) G  M1 @$ \5 Q
Void-- OSTCBMsg
. g4 I; k4 G s) e" l& U! wOS_FLAG_NODE--OSTCBFlagNode
( i. E' Q' d, C8 M$ V2 d ?OS_FLAG--OSTCBFlagsRdy4 H4 ~5 o1 q5 h+ v0 ^- d
BOOLEAN--OSTCBDelReq, k( [8 V$ f5 j" d+ ^; S6 }
}
; w1 n- K/ {+ ]1 |5 X/ A% [" w提示:在任务控制块的结构中存在着很多条件编译语句,这些语句的存在使得我们可以对ucos操作系统的功能做出裁剪的同时,大大减少系统对RAM的占用量,因为如果我们没有选择某项功能,就不会让与之相连的某些变量在预编译时有效,也就不会占用宝贵的RAM。这一点也很巧妙,有时候我真的很佩服作者的创造性思维。5 A. N3 `. x- R  F4 o0 x+ _' c

8 p# ?' y5 i! L! P) x7 m/ L# z 
) R1 @3 V) I  L. A3 O系统可以执行的最大任务数量,用OS_MAX_TASKS这个宏来定义。当这个宏定义好之后,系统给用户程序分配的任务控制块的数量也就定下来了。适当的设置这个数值,可以有效减少实际的RAM消耗。
  k. z) m' o* I' l
' U; S: n1 z" J ; g" P1 D# E$ |+ x8 a
所有的用户任务控制块,都会放在一个数组当中。这个数组就是OSTCBTbl[]。操作系统本身还会有自己的任务,数量为OS_N_SYS_TASKS个,通常是一个空闲任务,和一个统计CPU使用率的任务。因此OS_N_SYS_TASKS通常为2。' S1 p8 x* g) a

n- ~* F# D! ]$ Y' f# t6 p9 ^( Y 
% a, N/ q9 J8 [. ?- h- D m" {# Y$ k. b& c, I
初始化时,系统会将所有的OS_MAX_TASKS+OS_N_SYS_TASKS个任务控制块链接成一个单向空任务链表,由空任务指针OSTCBFreeList来指向这个空链表。当某一个任务被“建立”时,这个任务就占用了空链表指向的这个空任务块。接着指针OSTCBFreeList会指向链表中的下一个空任务块。,以此类推,不断建立任务,就可以占满所有的任务控制块。一旦某个任务被删除,它所占用的任务控制块就会被退还给控制块数组。空指针就会指向这个空闲的控制块。. h q! {! B! s1 V4 _  x
这个方法也很巧妙,真的很值得我们细细体会,好好学习,呵呵。
1 s4 y8 s, ~# }" i' Z" P" r# z; S7 ?1 h  F$ E% S' J Y$ I8 i

9 B  k; L" Q: x* V1 m( E接下来就是建立任务时,空闲指针指定任务要用的控制块。这个控制块要经过初始化才能使用。因此作者设计了一个任务控制块的初始化函数OS_TCBInit()。这个函数专门负责初始化控制块。在这里就不具体说了,过程很严谨,也考虑到了条件编译的情况。% }% l! S  i. H' J
初始化函数OS_TCBInit()中值得注意的是一个参量:prio——任务的优先级。这个参量在后面的就绪表中的使用,我个人觉得是这一个月来的学习当中遇到的最为巧妙也是最为精彩的一个。 
UID116517 帖子18 精华0 积分227 阅读权限100 在线时间6 小时 注册时间2008-10-30 最后登录2008-11-17 查看详细资料
 引用 使用道具 报告 评分 回复 TOP 
 

Merphy 
开发助工



个人空间 发短消息 加为好友 当前离线  2# 大 中 小 发表于 2008-11-6 14:48  只看该作者 
写给各位同道
希望大家能自己先看看书,我在帖子中都加上了明确的页数。6 A! t4 w/ _3 D  d3 {, n
而不要回复那些诸如“看看”“学习学习”之类的没有意义的语句。
; C. ^) @/ }' _" k, @9 j我希望看到的是你们对于这个操作系统的自己的看法和见解
# t  U% G. F% g9 T6 k8 p这样我们的技术论坛才不会变成水池,谢谢 
UID116517 帖子18 精华0 积分227 阅读权限100 在线时间6 小时 注册时间2008-10-30 最后登录2008-11-17 查看详细资料
 引用 使用道具 报告 评分 回复 TOP 
 

Merphy 
开发助工



个人空间 发短消息 加为好友 当前离线  3# 大 中 小 发表于 2008-11-6 15:04  只看该作者 
就绪表
邵贝贝翻译的《uc/OS-II》第二版
9 t7 J3 H: n" \& ~' ]) S第88页——章3.04    就绪表
: B& c) Q: {& K9 f6 z前面说过了,任务有五种状态,而且Labrosse先生将他的操作系统设计成具有可抢占的系统。
3 x/ x$ ]) r" X! i" ]7 f因此优先级就显得非常重要。他在设计这个功能时很是花了一番功夫。
, ~$ C  K: M' ^  _他设计了一个重要参数:prio
) Y, d6 c# A. M/ p2 K) @8 |* J同时还设计了一个变量OSRdyGrp,一个位表格OSRdyTbl[8],一个优先级判定表OSUnMapTbl[256]
; G$ |$ c. Z# W* j2 r+ [; @他用这些东西实现了反映每一个就绪任务,并且找到优先级最高的那个就绪任务。很富有创造性,衷心佩服。% B; P+ C& ~* N# K+ B
# h3 T6 Y! y/ p& M9 y5 U- M. W
在任务控制块的讨论中我们应当注意到
5 i- F' @- Y) o7 p2 T" SINT8U--OSTCBStat——如果这个变量值==OS_STAT_READY时,任务进入就绪态。- J5 M: ?  t; ?0 k
那么就绪的任务要怎么样被操作系统察觉呢?* t" j& K8 S5 T9 u3 W
答案就是:就绪表。7 ~1 T8 r, Q9 T. J
就绪表分为两个部分,. {* R6 ^  Q+ I8 K
一个是八位的变量OSRdyGrp
$ M" R; v4 \& }  @一个是数组OSRdyTbl[]。
( F% w8 ^( Z1 E# L利用到的参量为任务的优先级变量INT8U. E$ k$ N4 ]4 }) j) u+ T/ o% n
prio0 w. P+ l# x/ a1 ?1 o
现在的ucos设计为只能管理64个任务。因此数组OSRdyTbl[]至多有8个元素。这两个部分的对应图如下:& R. [' n& |- t8 l
 
UID116517 帖子18 精华0 积分227 阅读权限100 在线时间6 小时 注册时间2008-10-30 最后登录2008-11-17 查看详细资料
 引用 使用道具 报告 评分 回复 TOP 
 

Merphy 
开发助工



个人空间 发短消息 加为好友 当前离线  4# 大 中 小 发表于 2008-11-6 15:05  只看该作者 
对应图
对应图如下
附件
 对应图.JPG (32.2 KB) 
2008-11-6 15:05 

 
 
UID116517 帖子18 精华0 积分227 阅读权限100 在线时间6 小时 注册时间2008-10-30 最后登录2008-11-17 查看详细资料
 引用 使用道具 报告 评分 回复 TOP 
 

Merphy 
开发助工



个人空间 发短消息 加为好友 当前离线  5# 大 中 小 发表于 2008-11-6 15:11  只看该作者 
操作原则:- M# L! O0 x) E4 V7 V
每八个任务分为一组,占用一个数组元素,每个任务就绪标志就占用一位。共8*8=64个任务。每个任务有唯一的从0到63范围内的优先级值。, d# f; r  u, ]7 D0 h. S9 Z, s3 ^
OSRdyTbl[0]à OSRdyGrp.0 
+ N' M7 I1 G5 k9 |6 e9 ?OSRdyTbl[0]中任何一位为1,则OSRdyGrp.0=1;# w+ P) h: t0 C/ i  K
OSRdyTbl[1]à OSRdyGrp.1 
5 E% X9 E) u1 WOSRdyTbl[1]中任何一位为1,则OSRdyGrp.1=1;8 q* J; ]  p% W
OSRdyTbl[2]à OSRdyGrp.2 7 c$ j6 V0 B0 H
OSRdyTbl[2]中任何一位为1,则OSRdyGrp.2=1;
9 e+ U+ D/ L! [* s6 B6 gOSRdyTbl[3]à OSRdyGrp.3 " M: h8 k2 A4 J5 a. H4 u
OSRdyTbl[3]中任何一位为1,则OSRdyGrp.3=1;2 j0 I8 V' F* n$ J
OSRdyTbl[4]à OSRdyGrp.4 
7 K0 ]! l( l, K( _( E$ fOSRdyTbl[4]中任何一位为1,则OSRdyGrp.4=1;; D. @) W3 \0 ^4 ?
OSRdyTbl[5]à OSRdyGrp.5   J3 j# a% E8 B0 D
OSRdyTbl[5]中任何一位为1,则OSRdyGrp.5=1;
& ]; ~/ n! s& u, F9 z* J  BOSRdyTbl[6]à OSRdyGrp.6 
) q& `, v4 c" s* Z1 ?OSRdyTbl[6]中任何一位为1,则OSRdyGrp.6=1;& U1 H% n% f1 C9 g/ b
OSRdyTbl[7]à OSRdyGrp.7 ' n; U" D- l9 P/ r0 n
OSRdyTbl[7]中任何一位为1,则OSRdyGrp.7=1;
5 h- e; l6 `; f8 i% l/ S, {1 P8 \) A  \' [) C3 z4 J5 p; P
为实现这个对应规则,作者定义了一个常量数组
3 I* L0 n2 i$ Q, V: \* C% jOSMapTbl[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}! H0 I' }: q3 s; ~
有了 OSRdyGrp! Z% ]: A: w9 S' [
  OSRdyTbl[8]
: Z- V$ {; ~! y% Z  OSMapTbl[8]" [6 H' u- O( @0 D7 t
以及 prio4 k( n8 l8 B; g  D
使用一个语句就可实现这个对应规则:OSRdyGrp | =OSMapTbl[prio>>3];; u. y( R# R1 Q  P% l
解释:9 l6 Y- C5 m. T3 `( y
(1)prio>>3 ——优先级右移3位,相当于除以8,除以8之后就可以得到prio在数组元素的位置了! [" c; r% |6 H* g
(2)OSMapTbl[prio>>3]就可以得到OSRdyGrp所需的掩码值. n% E: c& x' j1 E# W3 W0 {  y
(3)OSRdyGrp | OSMapTbl[prio>>3]就可以得到新的就绪任务的组。注意是相或|而不是相与。相与之后就会让之前的所有就绪状态失去。/ {( I' Q- K7 Z4 b) O1 f+ N1 p
这样就确定了任务的优先级在表中的元素位置。2 U1 ?2 s6 `- }; J
使用这一个语句可以得到某个任务优先级所在数组元素的具体哪一位:! S0 j1 \! v+ d" b( ]% _% E
OSRdyTbl[prio>>3] | =OSMapTbl[prio&0x07];) }2 s2 |% y1 X
解释:
' ^. K" e3 e! ?( f(1)OSRdyTbl[prio>>3]得到该任务在就绪表的元素位
$ a! U  k3 S9 [4 H- Q3 n(2)prio&0x07之后得到prio的最低的三位,即prio在数组元素中的具体哪一位
% s$ H9 p4 {  y(3)OSMapTbl[prio&0x07]得到该位的掩码
# g- Y: W2 r( |4 m, N; w(4)将就绪表中的OSRdyTbl[prio>>3]与掩码相或之后就可以得到所在的准确位置。相当于把这个数组看成了由二进制位组成的一个二维表格。- V! @4 f' }0 E9 l1 @; Y9 `8 }
总结,使一个任务进入就绪态,就是让该任务的优先级变量prio在就绪表中置1。在就绪表中置1有两项工作内容,一个工作是在8位无符号整型变量OSRdyGrp的相应位置1;另一个工作是在数组OSRdyTbl[8]中准确位子置1。用下面两个式子就可以完成:% R! f) c. T' {
OSRdyGrp | =OSMapTbl[prio>>3];
; q' d1 A) i! XOSRdyTbl[prio>>3] | =OSMapTbl[prio&0x07];
: l- P) O! g! s% o9 `7 e/ Q 
UID116517 帖子18 精华0 积分227 阅读权限100 在线时间6 小时 注册时间2008-10-30 最后登录2008-11-17 查看详细资料
 引用 使用道具 报告 评分 回复 TOP 
 

Merphy 
开发助工



个人空间 发短消息 加为好友 当前离线  6# 大 中 小 发表于 2008-11-6 15:19  只看该作者 
由此可以推论,让任务脱离就绪态,就是让相应的位清零。而与置位不同,由于OSRdyGrp与OSRdyTbl[]的特殊关系,需要只有当OSRdyTbl[x]=0x00时才将OSRdyGrp的相应位清零。* `& Y4 Z8 C& ~6 k
所以应当先从简单的入手:
% a. \6 x6 l8 o* z2 a+ M3 JOSRdyTbl[prio>>3] & = ~ OSMapTbl[prio&0x07];$ @/ {& T0 _) Y4 D
此时还不能将OSRdyGrp的相应位清零,只有当这个数组元素为0x00,才能将其清零。因此要加上一个判断条件:
# T* Q5 P+ Z# ^  E! D  W+ R/ _If ( (OSRdyTbl[prio>>3] & = ~ OSMapTbl[prio&0x07]) = = 0x00 ),只有当这个条件满足之后才能将相应位清零:OSRdyGrp & = ~ OSMapTbl[prio>>3];9 t5 w6 C7 M8 c8 l0 {3 X3 x

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -