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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
6 Z- d# b! @7 u' ~1 C
内核版本2.6.30
3 n- M4 {9 n+ V8 ]/ R* n1 U4 x0 A
CPU:S3C2440
8 |+ e! \8 [) V: q
8 X) y- j. d+ |0 f: w. K. P( ^+ W) h( ~: B" G
/ ~: e6 t& [6 b; e7 y  m
本文主要说明节拍定时器是如何添加到内核中的,不对定时器实现进行说明。4 c( Q- Z: n0 J# G
$ I1 ]. X' ]  r/ I# o2 [
3 ]( J: K4 m: ^( `+ y) O; ?

( {4 R0 P  L% t5 r* y) cARM 平台的节拍定时器对象使用sys_timer来表示,该结构体位于arch/arm/include/asm/mach/time.h。: U  f+ t$ s) U9 k7 W
5 X' g' R& h- x$ s$ T0 V
/*
% W* x  V3 x; l2 Z; J% K$ ?4 u * This is our kernel timer structure.8 Y6 g# K( ^1 R
*
; g  T/ R3 L  U) c! m+ ] * - init
+ h5 l/ ?. k6 A, e6 a5 `8 R *   Initialise the kernels jiffy timer source, claim interrupt
. o6 |: {& ^( w2 h  Q *   using setup_irq.  This is called early on during initialisation- g2 H1 a( q" R* Q! Q; Q
*   while interrupts are still disabled on the local CPU.
5 h( k3 m. I- B8 T$ t, U5 o4 @ * - suspend
; `# b) ?6 t  Z *   Suspend the kernel jiffy timer source, if necessary.  This: T$ i3 ^  p/ K& [4 s7 Q1 M3 k
*   is called with interrupts disabled, after all normal devices1 p3 [! Z, P0 k
*   have been suspended.  If no action is required, set this to; G6 {5 H  l8 t2 C& w+ ?. \
*   NULL.) `2 s) _$ m* B  J5 `0 R+ k; w/ N
* - resume
4 W" r- L  |) Z *   Resume the kernel jiffy timer source, if necessary.  This3 j1 ^1 w6 n! I+ O( p/ e# {
*   is called with interrupts disabled before any normal devices
" A" W7 m% B5 F* S5 ?8 e9 Z4 z! [ *   are resumed.  If no action is required, set this to NULL.
1 r( q- R: E; y* q, B/ n: w" A * - offset
. L8 V, d$ U9 L/ r, e *   Return the timer offset in microseconds since the last timer
, {! U3 W* I" L6 n$ @1 ^. q) K1 A& I *   interrupt.  Note: this must take account of any unprocessed
4 `: ~5 l2 T6 p# I  f3 J+ l *   timer interrupt which may be pending.
1 f4 x! l! d- E& e  Y' \8 Y */
( g% y- v4 x6 o/ N9 m" E& }; cstruct sys_timer {' ?6 l, r- h9 {, k, j% E8 Q- y
        struct sys_device        dev;
& t, G' z# T0 @) p* c+ F6 p& A        void                        (*init)(void);
& u5 l$ P8 a# u8 U9 s! w+ A2 E6 H        void                        (*suspend)(void);
7 v% Q, m# M  a( O5 U: y        void                        (*resume)(void);
) d% O( g0 v2 a5 z# T#ifndef CONFIG_GENERIC_TIME; d% l$ T) y; e: q) D; @/ r8 ]
        unsigned long                (*offset)(void);% z% v2 a+ N) G7 W9 P$ j8 }
#endif* [- a2 u& o8 p
};
  a3 |) @4 X& {9 O: |# @: @. i/ d: L4 e$ R
S3C2440的sys_timer的定义在linux/arch/arm/plat-s3c24xx/time.c中,给出的三个方法也在该文件中定义。# W" L6 c/ ~2 |. b5 h
struct sys_timer s3c24xx_timer = {/ |8 H3 H. j9 h) o
    .init        = s3c2410_timer_init," `  J, X/ s+ R- ]( [" D" s  H: O0 u
    .offset        = s3c2410_gettimeoffset,; V1 h1 e0 t! u) E, A
    .resume        = s3c2410_timer_setup* ]* `3 R% v# }
};
) \( S$ a8 o8 g# {7 b1 B0 m+ [; o& e$ i! R
如何将该定时器告知内核呢?7 l( @2 \1 S. u$ [# v% Q
在linux/arch/arm/mach-s3c2440/mach-smdk2440.c的最后使用了宏
' n  a/ s1 H  {6 T3 w" x- Z9 L' @4 \8 v/ ?
MACHINE_START(S3C2440, "SMDK2440")
, K$ s" J2 P2 {! q) \        /* Maintainer: Ben Dooks <ben@fluff.org> */  E* R. E# ~/ G$ _8 D/ z: d
        .phys_io        = S3C2410_PA_UART,# E8 j0 R( V! K
        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,7 }) `1 x7 x+ J9 T: t& [. m1 M/ _, t1 O
        .boot_params        = S3C2410_SDRAM_PA + 0x100,
8 r; I+ Y$ w7 C& F  K( ]9 s $ C# g/ L  M* y, |9 Y# `" S, q
        .init_irq        = s3c24xx_init_irq,
( r4 ?( Y+ j6 ^8 @0 {7 A% a) p        .map_io                = smdk2440_map_io,. h" Q* K' ^/ w6 V8 Z, d
        .init_machine        = smdk2440_machine_init,' v, Z4 B3 X3 H# z) A! D# \: i3 F
        .timer                = &s3c24xx_timer,
" T& Y: d% s8 UMACHINE_END
$ {3 N0 _: b2 N. d
  `0 o9 ^( T* I; q; ^" M该宏用于初始化结构体struct machine_desc,结构体成员如下:
) s% g4 Z; H3 B3 pstruct machine_desc {3 C2 J! w- y) N$ P2 @
        /*
  N6 L0 N7 X( |/ A         * Note! The first four elements are used
% ?, w$ I) B3 i8 M/ b( {" y         * by assembler code in head.S, head-common.S
/ I- Q+ X9 \/ T, D6 F! K( w         */. X6 T* Q; a( G6 W% I  N
        unsigned int                nr;                /* architecture number        */
9 ?8 O6 s$ o' D        unsigned int                phys_io;        /* start of physical io        */
6 |  Z2 n! R5 R, {8 z. z        unsigned int                io_pg_offst;        /* byte offset for io
& O- Z! \: h: T& y                                                 * page tabe entry        */
4 l- g0 H) ]7 O7 A ) u' B, Z( E# v
        const char                *name;                /* architecture name        */2 p' |  Z3 a/ G, a7 @0 [7 w5 {* F! @
        unsigned long                boot_params;        /* tagged list                */
' O2 @% s" ^. S0 m( u+ {( v ! c: h1 h! S3 i+ j8 R- a' g
        unsigned int                video_start;        /* start of video RAM        */% W6 U0 I# J+ S" X3 W( _
        unsigned int                video_end;        /* end of video RAM        */3 ]4 b2 ~' I* x; q5 W1 G
( m# r- f3 Y+ Y1 w
        unsigned int                reserve_lp0 :1;        /* never has lp0        */* k" v2 c$ |7 Y$ E7 u. [2 ]( c
        unsigned int                reserve_lp1 :1;        /* never has lp1        */. R! U) Q: I# x  K
        unsigned int                reserve_lp2 :1;        /* never has lp2        */4 T: d+ |! _7 A' E
        unsigned int                soft_reboot :1;        /* soft reboot                */  o, W- P* f* x! \
        void                        (*fixup)(struct machine_desc *,/ }$ G. \) e1 M; K! ^1 |
                                         struct tag *, char **," l, \, m5 W0 L9 q& D5 j
                                         struct meminfo *);* o( b$ H* _6 I1 x/ ^; e5 s) P- J
        void                        (*map_io)(void);/* IO mapping function        */1 Y5 V, @( _- @
        void                        (*init_irq)(void);
) {4 }; @1 Q' J$ i2 L2 L        struct sys_timer        *timer;                /* system tick timer        */
3 `- G5 b) `7 d        void                        (*init_machine)(void);
* Z# M6 b6 ^+ ]) b5 W% L};
7 `7 i( U7 s1 j# }( Y3 ?" y3 j% v7 a, V% g  Q8 i
在这里我们看到了timer指针。通过该宏将timer指针指向了s3c24xx_timer。, U4 ?3 f! z! l
接着,再看linux/arch/arm/kernel/setup.c中的setup_arch函数,该函数中执行了下面这话:
! Y2 m9 K' t* h, w3 Y4 I: K( h7 g2 C5 s: q# \* p( T  N
    system_timer = mdesc->timer;9 d4 Z/ [# m$ Y0 J  _8 V

9 x( R# Y7 k( c6 A: |mdesc->timer即为上面宏所给出的s3c24xx_timer,而system_timer为全局变量。通过该全局变量就可使用节拍定时器。
" ~7 \4 L! F0 W
8 j3 z* e: V% y4 y" p最后,我们看下节拍定时器的init方法何时被调用,调用顺序如下:5 C/ f* q& P6 w; l8 Z7 {* w# `
3 l, O& _& ~, x$ i
start_kernel ()-->  time_init()  --> system_timer->init()4 Y/ z  w0 v7 S7 C. X7 |7 g: c
4 i2 K. J+ D0 _! Z
time_init  -函数位于linux/arch/arm/kernel/time.c。6 K9 T' W4 ~1 Y$ V

" S& m' ]* L) I0 T# Y  c3 X9 W: ~8 p  \& t+ l, D# h

  y( Q6 M: J0 w9 ~7 C# O/ X0 W* Y' K1 w. w" R0 O" F
+ w7 Q% X. X  @' I6 a
, n  n% |1 r1 o% F
$ K& d7 B7 K' y- c! \, q) |0 g
  • 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 17:55 , Processed in 0.171875 second(s), 23 queries , Gzip On.

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

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

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