找回密码
 注册
关于网站域名变更的通知
查看: 189|回复: 1
打印 上一主题 下一主题

了解一下Linux系统的节拍定时器吧(system tick timer)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-6-12 11:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

. d/ B- x0 R# u4 U$ P内核版本2.6.30
! z2 ^; d2 X/ \; X  g
' o/ U: ?; B3 y# i% K# p+ Z7 \6 _CPU:S3C2440
) q5 s- W$ Q7 n2 @) u+ b7 S; ^) l" G* x6 k1 [0 p) g& g9 e

- x, H  S! f& G- h" t
2 P0 A/ J( A, T6 m本文主要说明节拍定时器是如何添加到内核中的,不对定时器实现进行说明。$ ~4 @- B# H  @0 P
: ^. k, b. l& W! Y4 B5 \
  K% S; l# q( a( v; G9 w  f
. ^; ^4 K# D1 ]- T. Y5 B1 @
ARM 平台的节拍定时器对象使用sys_timer来表示,该结构体位于arch/arm/include/asm/mach/time.h。
# u) F3 `0 |  P/ Z8 n3 b. D
" W* K; k4 m& W" Q/*
5 p( a" W- U5 O * This is our kernel timer structure.
' J$ b4 F0 o" ?3 V. A *& w# f+ W7 e1 t
* - init/ I8 `" C9 Z' Z, n0 u
*   Initialise the kernels jiffy timer source, claim interrupt
$ h1 Q  A8 o7 c1 G# r5 c# R/ F *   using setup_irq.  This is called early on during initialisation
8 C6 C. e1 _: _  G8 b% P5 T *   while interrupts are still disabled on the local CPU.
0 g0 k0 Z) s6 y0 ^+ X( l * - suspend
2 @# T' T0 \+ e! o0 n3 ~& E' H* [ *   Suspend the kernel jiffy timer source, if necessary.  This
( J* z+ t1 ^+ l% q# d$ i *   is called with interrupts disabled, after all normal devices3 ]+ U- b# @# G3 w" ]4 h
*   have been suspended.  If no action is required, set this to
( s$ B% o! R9 O/ |" i- s5 S6 T. j *   NULL.
) `  q8 d( D3 B2 Q5 j2 } * - resume% Z. w! w$ d! }- v3 ]% C/ X5 n) c
*   Resume the kernel jiffy timer source, if necessary.  This
' E+ }# j3 c6 J, G5 F *   is called with interrupts disabled before any normal devices" Y3 J) f" J! ?4 c: q: k. i
*   are resumed.  If no action is required, set this to NULL.% ]9 q- D) e1 o! d+ L8 X
* - offset  X5 E: Q# q; V* t# }  o0 E
*   Return the timer offset in microseconds since the last timer2 p' x# R8 ^, X! I( a
*   interrupt.  Note: this must take account of any unprocessed3 @: ~5 w! }+ Y4 W' z
*   timer interrupt which may be pending.' D  M0 P% {  b# m: ?* P
*/
+ y" u* {0 f1 `$ U8 d; fstruct sys_timer {( A+ k0 I* C0 n) s
        struct sys_device        dev;
2 ^* [4 U% w% \        void                        (*init)(void);
6 S. s' w7 ~0 {; o        void                        (*suspend)(void);
& Y  v2 @, Y' W% ?$ X" f! U        void                        (*resume)(void);& C8 C& ^' [- w, m
#ifndef CONFIG_GENERIC_TIME4 n) A: A6 d& |% ^/ J$ u7 m! N
        unsigned long                (*offset)(void);0 r0 j+ ?- `1 ~( S. A
#endif# M! z- m) U' C1 _' h
};1 @; ]! w, m3 z. z  \

3 S+ P2 c8 i8 [S3C2440的sys_timer的定义在linux/arch/arm/plat-s3c24xx/time.c中,给出的三个方法也在该文件中定义。
% r& p% O2 k  w9 a  h4 Q% \7 istruct sys_timer s3c24xx_timer = {
' A# K, D# \0 s2 N# |- T& j6 t, S    .init        = s3c2410_timer_init,+ O' e" `  X; e+ r+ d
    .offset        = s3c2410_gettimeoffset,1 U+ b0 O- m  n" A, d, {/ u
    .resume        = s3c2410_timer_setup
8 U- t% D6 u% I6 f* `- r};; v: Q: S4 [% _1 o) B6 J
4 P1 c1 r1 q8 T% A5 u
如何将该定时器告知内核呢?
; M! h0 s+ g; j+ U% w4 E( ~在linux/arch/arm/mach-s3c2440/mach-smdk2440.c的最后使用了宏/ U1 F  |/ ]& a- s; G4 G# T
8 g2 R7 U  g( Q* Q# a7 Q3 w. P+ z
MACHINE_START(S3C2440, "SMDK2440")9 [1 x6 y, S7 x& w  i7 l' [5 T
        /* Maintainer: Ben Dooks <ben@fluff.org> */
1 O: L( v: [. m        .phys_io        = S3C2410_PA_UART,2 V# q; P: d8 ~# d, c- f
        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,' w) D/ n' j. t# T. O
        .boot_params        = S3C2410_SDRAM_PA + 0x100,* n" C/ w$ Y( v: o7 ?
. C2 S& R- R' X9 J
        .init_irq        = s3c24xx_init_irq,
8 f: \4 I+ [2 Y9 l% H7 z9 G        .map_io                = smdk2440_map_io,2 b" T. |7 X' \# M4 r
        .init_machine        = smdk2440_machine_init,7 J. r+ S! ]* a) ~
        .timer                = &s3c24xx_timer,/ l; i% y& Y# W4 _
MACHINE_END
1 v9 `0 h; T2 ]- [8 Y: u& J0 D- I$ l# G5 x: R6 o* D
该宏用于初始化结构体struct machine_desc,结构体成员如下:6 F# m) @6 L7 P" P' D( ~& K' e
struct machine_desc {
: {. V' u8 B* `+ P        /*
* N, H5 x' s! q2 {. N/ {! I7 R8 N         * Note! The first four elements are used1 R! M$ Y2 U: i" m# w  R
         * by assembler code in head.S, head-common.S# p9 H( |: ]3 D5 |. U
         */
# Q9 d+ }9 L, s9 y        unsigned int                nr;                /* architecture number        */! S4 A- q1 W8 f  [
        unsigned int                phys_io;        /* start of physical io        */
9 f/ W! b- Q8 c" _/ e2 A        unsigned int                io_pg_offst;        /* byte offset for io $ Q) Q/ s- P7 s1 D& k
                                                 * page tabe entry        */
5 k* l! c7 p/ J3 P- K$ R   [: S% F' J0 H6 s
        const char                *name;                /* architecture name        */
9 g* g9 j1 s- q/ D. v' I        unsigned long                boot_params;        /* tagged list                */$ t$ t* Z5 Z& G/ @% e8 \/ L/ z

! n& E/ i6 x- N' q        unsigned int                video_start;        /* start of video RAM        */% s* n( U4 s" H
        unsigned int                video_end;        /* end of video RAM        */
0 x/ X0 X, t$ K- R
+ i( k# J0 ~! M9 g1 Y1 A8 D& x        unsigned int                reserve_lp0 :1;        /* never has lp0        */
8 [$ @9 _- d9 ^; D        unsigned int                reserve_lp1 :1;        /* never has lp1        */% {  d& s1 b* U( D
        unsigned int                reserve_lp2 :1;        /* never has lp2        */
/ f3 u) w/ y( X5 E$ Y9 {1 w9 g        unsigned int                soft_reboot :1;        /* soft reboot                */
  M7 Q" z) e& S8 G! `) W; P        void                        (*fixup)(struct machine_desc *,5 D4 O- @& V6 ^$ E
                                         struct tag *, char **,: ?5 M; _. g' r0 g: S4 c
                                         struct meminfo *);1 p7 b# l# i2 e9 B3 P& X0 c
        void                        (*map_io)(void);/* IO mapping function        */, V* Q9 K1 E7 _" d" ^5 F+ v
        void                        (*init_irq)(void);
4 C) \5 Z+ L! x- M  }, p* c* t3 G' S        struct sys_timer        *timer;                /* system tick timer        */
, s, @7 X/ B0 V3 y) q5 h        void                        (*init_machine)(void);
7 l- E8 M+ F3 [/ ~5 I' s};
" {: v7 p3 w0 u, i; ]
* H* s- s+ n% N在这里我们看到了timer指针。通过该宏将timer指针指向了s3c24xx_timer。2 J4 [3 |) d5 B, J
接着,再看linux/arch/arm/kernel/setup.c中的setup_arch函数,该函数中执行了下面这话:
* v- t( K9 ~& C, d
$ }0 t2 M" q3 ]8 Y" a& S    system_timer = mdesc->timer;1 d" d' l4 I  B. ~
! y, T' }9 Q$ \; l1 a0 e
mdesc->timer即为上面宏所给出的s3c24xx_timer,而system_timer为全局变量。通过该全局变量就可使用节拍定时器。
) }# I# w8 T/ \+ I, Q/ E6 ~3 o3 y! u& v* d
最后,我们看下节拍定时器的init方法何时被调用,调用顺序如下:+ R" y( C8 J, K. `2 C
/ F2 d) M( b4 R- L; D4 B
start_kernel ()-->  time_init()  --> system_timer->init()6 V1 J! y- A( m' t8 ]& d9 I
5 d2 q9 t# \9 @' M# o5 u
time_init  -函数位于linux/arch/arm/kernel/time.c。: j  X  A0 ?1 g. p

7 u0 V4 H7 C; X5 R! R- s: W8 |  B* m( Z7 Z5 ?8 x. a
! e7 b5 t/ b! B% M
7 a, c% p4 W4 z8 y; Q, b

4 r& K6 o/ r7 G$ H$ g" ]3 D) S. p% Y! ~" M- n

1 ^) W' \% S7 G  R3 C  V
  • TA的每日心情
    慵懒
    2020-6-13 15:46
  • 签到天数: 1 天

    [LV.1]初来乍到

    2#
    发表于 2020-6-12 13:13 | 只看该作者
    节拍定时器
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-25 20:05 , Processed in 0.156250 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

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