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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
6 R3 c/ X' `( }: O6 F+ G$ X8 ?. r
内核版本2.6.30/ x/ R( R: Z/ N: Z

0 s, f# }9 X+ w+ @& I0 ECPU:S3C2440
* \* V' v  S  f2 S% I+ w+ b% P/ x: V% l! F# k; B
! Q4 Q1 C. ^! w
% l9 H: G7 i. W7 w5 u6 B+ r! ^. K! @" U
本文主要说明节拍定时器是如何添加到内核中的,不对定时器实现进行说明。' i) F; K% l& W
2 y" m- {. Z( [; H  {- v

( U/ m  Z: f8 D5 S& }/ y! H5 @' y) f' ~0 l$ t- ?
ARM 平台的节拍定时器对象使用sys_timer来表示,该结构体位于arch/arm/include/asm/mach/time.h。$ B4 c9 ^/ u; k* y9 u. l

! C3 @! |$ G: y+ @, l) E/*
4 e# L  D4 w3 s! R" w/ X! k * This is our kernel timer structure.
( Z. Y1 v- G4 A0 A0 L# U *
* L# Z% \  F2 u3 i2 m * - init* U4 I% g0 k6 o, k& j. N& E) P
*   Initialise the kernels jiffy timer source, claim interrupt
# F& {$ J. f/ c4 X: S4 r, u *   using setup_irq.  This is called early on during initialisation
: \% e  Z$ z1 c" d* j *   while interrupts are still disabled on the local CPU.- L: u/ i: o: a, V' i( ?2 b+ N
* - suspend
1 _# o, {- ~! u4 w *   Suspend the kernel jiffy timer source, if necessary.  This
1 n" w( t' J! m6 s *   is called with interrupts disabled, after all normal devices- G( V* O/ |7 B- P6 O
*   have been suspended.  If no action is required, set this to! T  F" t, a" i8 R; `
*   NULL.1 `8 s" }" R8 U; i% p2 o6 }
* - resume1 ]5 H) E+ P% w! i2 a, u% v) G% V
*   Resume the kernel jiffy timer source, if necessary.  This
0 Z+ l! F- K9 z  g *   is called with interrupts disabled before any normal devices
4 y- U; u  S. D *   are resumed.  If no action is required, set this to NULL.8 ]( r# @3 V: r8 _; ~- Q7 d
* - offset: y2 j) P% t, m5 o' K* t; `
*   Return the timer offset in microseconds since the last timer1 t0 ?  g  [9 `( d$ I+ Y; M5 V; d$ {
*   interrupt.  Note: this must take account of any unprocessed
& _# i: {2 F' N! s; t  p *   timer interrupt which may be pending.  V, U6 i' Q" w8 K- ~
*/
/ V8 z5 a/ P) H# X+ Hstruct sys_timer {
, {2 L+ B6 C# z  l& f  X        struct sys_device        dev;% R( P, M, u. C1 |
        void                        (*init)(void);
5 @- B4 k' ]6 F3 R        void                        (*suspend)(void);& S8 x) A/ j# z( D( k3 A) z
        void                        (*resume)(void);1 P! M  K* o( c4 a1 V
#ifndef CONFIG_GENERIC_TIME
, K  h6 P9 B6 z) z4 Y/ u        unsigned long                (*offset)(void);  F+ E" \' m+ ^9 i8 L7 `8 t7 B
#endif
) s4 M9 {& Z; ]};
9 p* }2 R' U9 x: o# K* z! g. X/ ~) t2 K
S3C2440的sys_timer的定义在linux/arch/arm/plat-s3c24xx/time.c中,给出的三个方法也在该文件中定义。4 e3 j0 C$ B% A9 m# g
struct sys_timer s3c24xx_timer = {
5 l7 A5 T* S2 X* y; \    .init        = s3c2410_timer_init,
) k# E% x; ]  g" _7 u1 U' u' B    .offset        = s3c2410_gettimeoffset,
7 K& I3 F, @5 E5 a2 Y1 L2 r5 l- T    .resume        = s3c2410_timer_setup
( s/ u6 M6 N/ k7 t};6 Q9 h" x0 T  D9 {, ^! s" b

5 `6 F2 P4 ^4 N% n# s$ I9 o4 y' B( k如何将该定时器告知内核呢?
% j# _6 o7 |- l在linux/arch/arm/mach-s3c2440/mach-smdk2440.c的最后使用了宏
4 l+ J1 ^6 Y- w2 L( X4 p  y1 }: H3 J+ O3 u7 K9 s
MACHINE_START(S3C2440, "SMDK2440")
& \3 v3 I- F+ E4 Y; B+ B: I0 ~        /* Maintainer: Ben Dooks <ben@fluff.org> *// F4 F7 n/ y( m$ W+ d* B- f, k9 G3 e
        .phys_io        = S3C2410_PA_UART,
1 r! v' r  a% O* p        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,' |7 s& v' ~0 j5 H! b8 t
        .boot_params        = S3C2410_SDRAM_PA + 0x100,) T1 \# I& p7 w2 ~

0 b7 w" ~4 d' }8 k7 i/ e        .init_irq        = s3c24xx_init_irq,# v# q, i- o8 L7 k4 l: h) u, u
        .map_io                = smdk2440_map_io,
( @5 Q5 V1 b6 @; l+ x2 R        .init_machine        = smdk2440_machine_init,
6 |/ x. j3 j9 T! n+ F, ]/ n' R5 b        .timer                = &s3c24xx_timer,8 {+ w# Z, A7 S# r# x8 U
MACHINE_END
! l8 V  q( U# P+ e1 H% O. P1 ?2 [7 i4 }
该宏用于初始化结构体struct machine_desc,结构体成员如下:
$ k: f/ i+ h; n  f5 T+ _' tstruct machine_desc {" k! l4 \( h+ F/ r
        /*
0 w  b, w0 x+ `% j; P2 P  J* l+ I; X         * Note! The first four elements are used' M# U! V1 P/ ^( `3 _
         * by assembler code in head.S, head-common.S3 y% ]; K% _7 _) ?7 }- p
         */
1 c; U+ G% |- J; |4 X        unsigned int                nr;                /* architecture number        */
* Z( v  n: A% L* i5 {        unsigned int                phys_io;        /* start of physical io        */
' s8 L: K$ [% T: [5 @& l$ J        unsigned int                io_pg_offst;        /* byte offset for io
: K- }! G' _, A: {: H4 y# t                                                 * page tabe entry        */
7 [( Z) [" L% f+ _. T) R) x+ F . J& y& f4 ~+ |
        const char                *name;                /* architecture name        */. Z) V- j4 K; E: n3 `6 B9 F
        unsigned long                boot_params;        /* tagged list                */
- n! E' }9 A9 j% u
. ?) W8 L8 P5 I0 d        unsigned int                video_start;        /* start of video RAM        */
& V* @, ^8 }0 u9 P        unsigned int                video_end;        /* end of video RAM        */
( \9 W) d, K1 I# |3 ?: t/ @  T% @) f
1 B5 I* I0 V) o        unsigned int                reserve_lp0 :1;        /* never has lp0        */
( d6 X% X, c% s  P; Z1 }        unsigned int                reserve_lp1 :1;        /* never has lp1        */: U9 N  R+ a; }: v2 a
        unsigned int                reserve_lp2 :1;        /* never has lp2        */1 k2 b* ^, v1 R- \
        unsigned int                soft_reboot :1;        /* soft reboot                */. p6 N8 P( H2 X5 k2 [
        void                        (*fixup)(struct machine_desc *,
& P  k/ g- H1 O: Z9 G6 X: s                                         struct tag *, char **,
/ i0 p9 S% s7 {1 F                                         struct meminfo *);' d  c) V! j6 x5 }( |1 C
        void                        (*map_io)(void);/* IO mapping function        */+ T! H, j  Z! v& Q. q* Y# t
        void                        (*init_irq)(void);, x) \6 x/ \2 l) N
        struct sys_timer        *timer;                /* system tick timer        */' v1 K$ c8 `3 \+ I8 F  r* j/ h3 _
        void                        (*init_machine)(void);
) d6 `& ~4 m6 e2 m/ t  E) {};& B4 W! h; |9 r6 t* P( ^; Y, W

; @, _0 y6 h! l: g7 T在这里我们看到了timer指针。通过该宏将timer指针指向了s3c24xx_timer。2 q0 Z# y5 {# a6 m3 g! x
接着,再看linux/arch/arm/kernel/setup.c中的setup_arch函数,该函数中执行了下面这话:- b5 e2 r5 I. p# a& \5 U5 x

5 s1 f. a! X' i    system_timer = mdesc->timer;
; z1 ]4 K! `2 z  j) l2 y$ d. w! ]6 v5 p# ^0 ?% P$ c; M% k
mdesc->timer即为上面宏所给出的s3c24xx_timer,而system_timer为全局变量。通过该全局变量就可使用节拍定时器。
1 v8 b! t9 X, s: d; w0 g, C$ i6 U% K3 J+ c/ Y6 O; `+ @
最后,我们看下节拍定时器的init方法何时被调用,调用顺序如下:
! |. L- f& X6 J4 m: ~
$ ]5 p0 F5 j3 g  C  d! O: _+ e7 H" cstart_kernel ()-->  time_init()  --> system_timer->init()6 i9 N, P$ _% w* z7 ^) |

( R) R" S5 J3 L7 x) E9 Dtime_init  -函数位于linux/arch/arm/kernel/time.c。! l" G, H1 Z1 @& q5 p9 E

, r  @4 ~1 N, p% _) |' ]
7 D, `% V- U* J: N3 r# j# c  n! ~6 \) H4 B; m0 b
7 w6 W+ J( B5 V

, t4 A: e3 c* v9 w5 ~8 [2 `0 @2 r& q. F* N- q
" L* M! B# O  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-6-30 00:55 , Processed in 0.078125 second(s), 23 queries , Gzip On.

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

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

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