找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 5972|回复: 0

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
* U3 u. Y# F5 u( ?2 ]
  e* m5 L* U% G
1. Why need this mechanism% a$ z8 o# Q9 K; A8 C# d7 f
7 _! r7 V, J! |. s% }
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

4 I; V( E: O. Y7 b+ F3 R$ p" Z) a  r$ f: ~8 j
2. How to improve it?
+ c: U3 ^0 E4 w0 u5 n
+ Q1 |! W8 F# a2 w* p; ^  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
- n: }" n; K; P; `+ s  N- Y- D  _  V/ ]; [8 F
//header file
/ o2 w/ _$ w2 w. h8 \  n& m/////////////////////////////////////////////////
8 R- n' y; |6 \# y#ifndef
* H1 t* N$ I& s: rOEM_TIMER_SERVICE__H

3 g" O1 S& s, S- a2 u$ p#define0 D2 i9 q" h5 x2 _$ n( u
OEM_TIMER_SERVIEC__H
  E- p( T  ~. v5 v

. E4 c/ ?7 f  d# N. ^; F* L9 Q2 G, ~7 ~% ]4 d) h
void add_timer(unsigned short
6 R, ^! \0 ?- u- L1 c9 ]jiffies,void (*callback)());

) y, j4 O, Y- i. y- Z8 n; \: i3 z
void do_timer(void);. y' Q0 Y* e0 @6 i
  t+ Z( g6 o/ J. |9 P9 ^
#endif
! B3 }( l6 e$ m& A, ]# A/////////////////////////////////////////////////% Y4 d; E; Z1 e. U& N5 q
/////////////////////////////////////////////////
6 c9 C4 ?6 K& o+ j& J8 _//impl file3 m( r& P/ M3 V1 ]5 H' Z
#include <stdio.h>
' ~7 m2 L1 k. S$ R* s2 r" U2 b#include "OEMTimerService.H"
0 d9 Y; [! m# V  V) ~3 H: e- F8 `3 L' O, d5 l
1 K% l1 a' `4 t) f+ F
#define
$ }; k  k, v8 |" n( W2 K( FTIMER_REQUESTS
3 r1 x$ x- r2 d7 ]0x30
  B; a4 \+ p" a* H4 r
% d6 i0 ?9 p$ ^+ K) d
struct timer_list
: t7 d% l( e5 E3 H' T{1 `( p5 |4 j9 F9 D$ }  u7 b

$ A3 v7 |) v2 d  nstruct timer_list *next;
& K. L9 {8 v" b( N) ?& G

1 Z9 l3 e; _( G; }unsigned short jiffies;

4 r0 k+ s7 u" F$ h7 o0 L* k) Y5 R0 C2 A9 p* o) Y
void (*callback)(void);
# @/ S  d2 p2 z2 F! A
};
+ R: t& g; J6 C7 I& _
! s6 [; _% [4 O+ ^# B9 L
) E6 v2 M( P' J8 Q+ a6 w5 _* [struct timer_list timer_list[TIMER_REQUESTS] = {NULL};5 I. d/ P0 b7 L
- n, }% r( }; u; [% H2 J7 T
struct timer_list *timer_header = NULL;& x7 g( K- [  T6 h! K) d+ t4 h

0 v0 ~" k$ z5 e+ O3 j9 Q- q  ~5 k
void add_timer(unsigned short
+ z% w# T) q4 e5 N, I- C+ l6 Ajiffies,void (*callback)())

+ f$ Q' e0 M8 O4 R- K0 S8 y{) n  w- h+ C1 a$ J- a2 V, v0 Z  x+ p

& @5 n4 c9 e4 E# g/ cstruct timer_list *ptmp;

: _" j" h  ^4 K( w* h3 ~
2 S2 c- H% M* J& Y" k$ a6 @7 ]: u7 p& g
if(!callback)
8 W* ~# u; L. h1 ?9 w

2 T$ E7 C4 R/ q, [' X, z* ~return ;

7 S# P# r9 E9 ?
- g+ B7 U7 V# z; D+ C

  }9 N0 i; u4 s7 I5 ~& V6 Z8 s" k5 @+ G9 t# q/ {
EA = 0;

* {" q! w' B7 V' a& C( J7 n
7 b6 V- J4 ~" U; F% H. U( c8 d  n: x. L8 p( H3 v
if(jiffies <= 0)

# C4 [) f& O4 V. y
+ O6 m  p# y9 o' D! H% d(*callback)();
7 a- |; V" \7 t
: d/ ?( D% J# J' m! |: S

0 S( k$ a4 ~4 ^2 [+ }- ]  Q* d+ G; k  ?+ l9 L! @: [. B: p+ H
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
( p5 l0 H* e9 H) {; ~/ J7 ]' L
0 b) v+ e( S4 k7 g8 j, ^
if(ptmp->callback == NULL)
9 I2 ^  B' P, Y5 Y( ^
0 w) Q& B2 ^9 Y8 |, V. ]  }
break;

0 Y- o1 S9 `' g8 ]" {
6 \$ T( U7 a4 @  L) l# H/ y- H# m: \* L+ t

$ g% X7 K% I  w/ s4 C' pif(ptmp >= timer_list + TIMER_REQUESTS)

3 x; T  D. v% n" D7 k7 |; q) t9 P9 T4 P, F; N
{
" l1 r6 c% M9 l0 z
2 I& r2 A3 l1 l
goto EXIT;
# e; r6 C2 K# ]6 L7 A: S. X
% \" y+ ^6 `* Y3 Z; g5 F/ E3 R
}
$ ~7 D7 j! v  d% a

, V' I+ r6 x; r( C
7 H- k5 Y! }1 U3 a6 R& cptmp->jiffies = jiffies;

$ J# Z& Q1 y7 T" C9 i, B/ W; g6 }9 S& Y' t9 u$ C9 f0 P
ptmp->callback = callback;
' [8 |. D+ }, L5 l1 \$ C8 C
& d0 G* x* {, ]
5 U* N0 j+ o  @/ N9 `
. r; k' U0 g& q/ l# e/ p7 X2 y6 c2 i
ptmp->next = timer_header;

# {! L1 r. P5 e" H5 G' m4 D' [! e
8 W4 H' @8 A) |  Xtimer_header = ptmp;
' B! V3 Q5 ~! N& z/ d1 `/ w2 l: [

) F2 M3 f# M- }) f' n) X" H4 E9 L: l: j# w; l  z7 z( k
//add bellow code to fix linux on timer’s bugs ++

" W" W7 O- F% l% W  [, C
' _" e5 @  B! `8 T, F4 N: P/ aif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

) ]4 N3 O2 Z& E, `6 p2 \
0 _- B; u' T* o; u+ s{
7 h9 W  ]0 v" X; v/ L8 ?/ d6 w5 ]: x
; ~2 K, }9 n$ ~8 `/ Y# M
ptmp->next->jiffies -= ptmp->jiffies;
/ b3 r7 ]* Z1 N5 r
8 X  f! j0 x- l2 D' s& Q5 Z
}//end ++

- z7 K' x. |4 D6 O* r. ^% h6 @! g; j. U: w( P# Q: D- t6 A8 ?$ G5 U
else
) ]8 Q$ x7 A5 X) y& k# M# g9 E+ c: {
$ K; B" m" a- c
{

3 C9 ~7 w: Q$ L8 _) d; v- E1 V! W: b1 |, x9 U2 Z- H
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
. S$ }5 G9 \( o3 y- c
% F1 [, i% Q# F  W9 q% q

% L+ Q1 y4 K1 ]8 |1 a/ n# I6 K{

' n9 U0 M$ j% C6 v* C! e; u9 ~% p, F- P: p" N6 a( D
ptmp->jiffies -= ptmp->next->jiffies;

- u" @! g7 l  U
+ X' C5 n. E7 C4 Icallback = ptmp->callback;

, Z& Z! w% m' t& S
4 n8 q" X+ Z8 dptmp->callback = ptmp->next->callback;
, v5 F% D% {& _# \2 v
9 m2 J$ X" T5 z5 E6 l1 J7 ?
ptmp->next->callback = callback;
1 x& L) f% t' n( `, d

! k- U+ c3 `3 }8 `  _  Wjiffies = ptmp->jiffies;
# }: v5 a( \. t) o

1 R6 Z/ G2 ?( d1 xptmp->jiffies = ptmp->next->jiffies;
1 Y& S* Z/ R7 _- B, ^# r
  d& _  O- d; s+ A- I( G. }
ptmp->next->jiffies = jiffies;

: J4 a8 D% w7 e8 L8 C7 W+ {% j6 t& O8 B
ptmp = ptmp->next;
& @+ R: F4 V8 x' s

. v" a+ I. T0 o  j7 X- A" L}

* I: Z; D; o3 F5 M# K% i9 B2 n- `# u; S  N- b
}

! o  ~# e. x1 w- p
, J* H" R' C. Y  y4 F) U) gEXIT:
3 e' s3 S2 E( m8 j# A% G8 d- J
( e$ M# [0 ?' S$ V/ p* wEA = 1;
8 J- F* f$ W. T% _
7 l+ M+ \9 S8 n! N
return;
6 r' B4 e; T6 W
}3 Z) j/ X2 c4 G8 ~  w
2 _* L% a3 p1 O& K# C+ @. s
void do_timer(void)
9 o3 d$ f. \0 f5 N" y+ @. H  t{- U" n4 Z% Y7 @/ K4 B7 L- |' Y6 X

2 q1 @7 l8 ]; B
; t  o. b7 X1 h9 Y- wwhile((timer_header != NULL)

$ g* I! T, o# P1 c2 r* l
7 h$ Y; j2 U! M/ J6 h9 l0 s
' e" P* N) Z) Z1 m) a# z&&(timer_header->callback != NULL)

1 N3 ?( I3 W) B% {8 y0 r) W8 F* z/ E+ h2 y6 C; \- Z

' b/ E8 z8 E& K$ a&&(--timer_header->jiffies <= 0))

5 ]* A  l/ a3 u; t; k1 T% }3 U& O8 X: f0 W
{
4 z* V6 i. R; f$ F9 t

4 Q" d- g1 X' F0 Yvoid (*callback_fptr)(void);
5 X4 }8 z- b3 k& p* h
' ?' ~& Y' g3 U9 n" ?

4 }, z4 H2 H6 k) |3 |callback_fptr = timer_header->callback;
8 |) d( ?& t+ _) S5 t- f2 ~. p& P  X

! E, ]0 V4 A9 J8 Ptimer_header->callback = NULL;
- R3 j- A9 x& j4 \. b, o

4 W/ n" `1 K9 w  H" Q& F" Etimer_header = timer_header->next;

( `  p* Y" V1 M- b, A' ?- i- J* A$ V
(*callback_fptr)();

9 q7 H) s* j7 c) Y3 Z4 n; d9 I2 k( O2 ]* Y4 f1 a( S5 j3 ?/ v, }
}
# G& H4 Z# I& G% @$ A( e
& |/ u' M" B9 M8 D9 [4 j4 y0 h

" P6 F: q2 K( u+ W5 @) y8 Z1 J}+ A& @& ?$ q7 ]* t6 G4 W0 V
///////////////////////////////////////////////////+ a' {5 }9 Z# u; [) Z% a
' X" j; V: R+ U' R! D: ?

+ j) e9 ?  O+ ~7 |$ ]2 I上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!9 B/ t% [  J- N5 ^$ g

, @* Q/ ?, h2 b% p: T" S野人献曝,博君一笑
/ C# }$ s6 b, Z- e  ]0 s
: Y: Q: u; P% j2 P( o' }Peter8 t' V/ J- a% I3 I3 B+ ]+ V
  ' \5 F0 C; O+ n

' O# R; H5 ]- `5 r2 d& `$ X[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-9-4 15:50 , Processed in 0.051256 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表