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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
1 W2 q' p7 v/ c9 G! S
内核版本2.6.30
; o* V9 q0 p; f2 _! f+ J! ?; B+ q- G
CPU:S3C2440
) b1 m7 s& s4 E- o
7 {4 j4 Q6 o9 Z% g. ?( |$ u: E5 c6 y' t( q
7 X* ^0 _, f9 d) s9 m- y0 H
本文主要说明节拍定时器是如何添加到内核中的,不对定时器实现进行说明。+ R) ?( |4 j" v$ _! ~
- {8 p2 L: b- k$ n

4 |& m; W5 G" r
6 P5 C4 H1 q. |ARM 平台的节拍定时器对象使用sys_timer来表示,该结构体位于arch/arm/include/asm/mach/time.h。2 @  t3 J6 ~' G

4 F- j/ h8 `# m' W- t/*0 @* q) x( @6 ]6 n, ?  R
* This is our kernel timer structure.
# ~" u) I: c# m/ H3 s4 G, P *% ^% C: {/ L6 j
* - init; ~" Y) E- ~1 k; p2 Z) ^7 z
*   Initialise the kernels jiffy timer source, claim interrupt
$ I" r* \$ r2 g7 O *   using setup_irq.  This is called early on during initialisation
! ?  y4 a2 P# h, K3 W *   while interrupts are still disabled on the local CPU.1 I( y" K: ~  ?$ S/ P& p2 x4 W
* - suspend( x, b$ |* Z2 J1 _9 X" I
*   Suspend the kernel jiffy timer source, if necessary.  This
6 o/ L) w5 p" h. V *   is called with interrupts disabled, after all normal devices
; f4 z( C% T9 D* z( r+ V4 D *   have been suspended.  If no action is required, set this to1 u. x3 n: X5 U" D0 u
*   NULL.
$ \# ?+ R8 F7 z/ R * - resume
8 N2 ]# O/ |! `0 \, ^; Z7 h *   Resume the kernel jiffy timer source, if necessary.  This7 @; m" L( a" `5 X* e, [9 g: M
*   is called with interrupts disabled before any normal devices
+ H: i/ N' h; |% f7 w4 u *   are resumed.  If no action is required, set this to NULL.$ z+ M1 I& z3 V8 O! L6 O
* - offset4 k$ b$ o0 q# x( I& k
*   Return the timer offset in microseconds since the last timer' W. X' ^, {) R: _: B
*   interrupt.  Note: this must take account of any unprocessed; L. \" G9 G% z( N
*   timer interrupt which may be pending.$ h+ b0 H) r. t  c/ q
*/
6 T1 A- c3 M4 r! A" o  [: U  Tstruct sys_timer {# x( N4 C5 p% e$ \
        struct sys_device        dev;& |" z/ ]  {( U' M  x# e- G7 j5 \
        void                        (*init)(void);
& w' I1 c, v! }3 _$ n- i- B  J        void                        (*suspend)(void);! a1 Q4 ^0 i2 S; D& i5 P2 E4 s
        void                        (*resume)(void);" g) X, r3 {6 C2 l3 C
#ifndef CONFIG_GENERIC_TIME" j9 Y) y- E4 @% W# |$ c
        unsigned long                (*offset)(void);3 K7 I* M$ D# M: H
#endif' S# P: X" k6 V4 |3 p$ J5 }" P1 m1 h
};
7 m1 r( G# k! m/ ^7 h8 ]9 E1 @. D% z, L% u, y
S3C2440的sys_timer的定义在linux/arch/arm/plat-s3c24xx/time.c中,给出的三个方法也在该文件中定义。
1 {/ F8 `( k' \& Gstruct sys_timer s3c24xx_timer = {  ]0 f- T' r& d$ c. s
    .init        = s3c2410_timer_init,
9 A! f0 ], Y6 y/ f    .offset        = s3c2410_gettimeoffset,
+ `8 I1 k2 I: s  Z9 f    .resume        = s3c2410_timer_setup3 m2 \5 H. V; C
};
% e2 {* h2 X" k1 _" }
# Q, W9 W4 p. `如何将该定时器告知内核呢?
) U7 |& E; v3 c在linux/arch/arm/mach-s3c2440/mach-smdk2440.c的最后使用了宏' Q: U* O2 ?2 [9 C! ~' L

8 p& O2 w: V' j1 \' c- v& b9 ZMACHINE_START(S3C2440, "SMDK2440"); `% }' D. Y1 T7 T9 O  ^
        /* Maintainer: Ben Dooks <ben@fluff.org> */
( t5 V/ Q. {8 P! W        .phys_io        = S3C2410_PA_UART,# S! [8 J: F/ {0 y$ ?* V
        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
" e) ]* r+ l  |- A+ K        .boot_params        = S3C2410_SDRAM_PA + 0x100,
% W. j- [+ T$ O8 e% N
7 U7 y. ^- m, r1 e; z' U        .init_irq        = s3c24xx_init_irq,
- v: b! Z) W. F2 B1 N- t0 P        .map_io                = smdk2440_map_io,
: o% S/ X) {$ M( y. {" I. e$ t        .init_machine        = smdk2440_machine_init,
$ I* X. g( `' z! F, o; D        .timer                = &s3c24xx_timer,
/ u4 \* V/ F& ]MACHINE_END4 M7 u8 T) K1 C

: h# R; v* g! ?- M' ^6 n2 r' L( ]该宏用于初始化结构体struct machine_desc,结构体成员如下:5 E$ X1 K! k0 M7 r
struct machine_desc {8 O# M. @) u+ z9 T+ n: A  N
        /*
# p3 \7 F+ S" ^) c& w% P2 e; m         * Note! The first four elements are used
. Y8 u. {$ q/ C" ]         * by assembler code in head.S, head-common.S9 |/ V+ V2 n3 g0 Q
         */
; D* d1 l; `5 ?* _        unsigned int                nr;                /* architecture number        */# e( P- }& C$ p, E: E" A2 Z; o. q
        unsigned int                phys_io;        /* start of physical io        *// b- F( |$ d0 t; ~& X  a! u
        unsigned int                io_pg_offst;        /* byte offset for io $ Z9 Z+ o% D! k) Q( }
                                                 * page tabe entry        */: |; c# i$ `0 V% ?
4 s# N( M( G+ p3 @- G, R
        const char                *name;                /* architecture name        */
0 K2 A% O1 I& L9 [! p        unsigned long                boot_params;        /* tagged list                */& L! l1 N8 K% @! Z; G, a

7 t+ d$ m8 {7 g3 d* T& B1 i        unsigned int                video_start;        /* start of video RAM        */
5 i# r7 e5 |) l; L        unsigned int                video_end;        /* end of video RAM        */
% B) v* N! {9 k- Z+ ?0 E 7 T3 D8 m6 Q1 w2 i
        unsigned int                reserve_lp0 :1;        /* never has lp0        */8 v! ]0 G  V* D7 [' ], A4 n4 @! f
        unsigned int                reserve_lp1 :1;        /* never has lp1        */
1 a( J8 |3 I7 Y, i) C: K+ v9 J        unsigned int                reserve_lp2 :1;        /* never has lp2        */
+ z% Y3 i9 j. }1 e1 f$ W! i$ U        unsigned int                soft_reboot :1;        /* soft reboot                */
! R  y1 I: H  ], _8 j        void                        (*fixup)(struct machine_desc *,# |; P6 O, }% K6 J! ]/ T
                                         struct tag *, char **,0 W- B: j7 j- ~' O7 J! a
                                         struct meminfo *);
8 h3 `  r, b# f  B9 d        void                        (*map_io)(void);/* IO mapping function        */& I/ A' E: t* k- j4 A1 z6 y3 g
        void                        (*init_irq)(void);
& K- `+ L' X/ s' H        struct sys_timer        *timer;                /* system tick timer        */7 @) ]+ s. U2 _5 T% i
        void                        (*init_machine)(void);2 D+ v+ S" A4 g
};
6 E; C2 l. Q4 E
9 K4 N6 a7 \# Y, J' @在这里我们看到了timer指针。通过该宏将timer指针指向了s3c24xx_timer。
; b) U- s/ C$ d$ b# F- @, X8 f接着,再看linux/arch/arm/kernel/setup.c中的setup_arch函数,该函数中执行了下面这话:
5 F9 I/ x- K" p  `! d: N7 I# o2 b, r8 H% Z2 ?5 @  _7 W: [
    system_timer = mdesc->timer;
, X* S% {$ S; A2 B: A
8 C0 W7 {4 T' c; H' x) a. g+ W& Ymdesc->timer即为上面宏所给出的s3c24xx_timer,而system_timer为全局变量。通过该全局变量就可使用节拍定时器。# O# u4 s6 B* k

2 T  K: d$ D& t- L最后,我们看下节拍定时器的init方法何时被调用,调用顺序如下:
6 _4 b. g+ p, `9 r& Z3 K3 \5 p/ e/ e7 l# `
start_kernel ()-->  time_init()  --> system_timer->init()
$ N# U8 d- V9 {0 x, h) l" S8 e4 L$ M7 f" T2 ?) P
time_init  -函数位于linux/arch/arm/kernel/time.c。9 `# x, ]# B% K2 Y
5 r) d" p) k/ J
: y4 c6 }* t5 c
7 F6 y$ v1 m9 m

. I6 m! r, u' J7 G5 G% F8 D( H5 o4 I: J0 ?: N
+ h# i; ^- W7 O3 @
, S3 j, o* H( Y1 x$ j: e
  • TA的每日心情
    慵懒
    2020-6-13 15:46
  • 签到天数: 1 天

    [LV.1]初来乍到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-10-27 03:11 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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