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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
, ?3 D9 |5 e5 X
内核版本2.6.30
% @7 l. t: g  t9 C$ j1 e2 Y$ F9 @1 H# B* Z1 [7 x4 C1 Q) F
CPU:S3C2440- G3 g! R5 t+ O% @9 n8 D: o

& ?* G9 p" t- T5 d7 J. h
& u( |  Z* ~. A7 ]  @8 i0 b" _" V4 y( M' z4 z
本文主要说明节拍定时器是如何添加到内核中的,不对定时器实现进行说明。
' a3 y7 p$ [4 ?6 N2 T
! U5 n9 a# V  J- F5 Q. h0 ?& {+ z6 d6 l" P0 t( E
9 t3 u7 p9 j, x( n2 d
ARM 平台的节拍定时器对象使用sys_timer来表示,该结构体位于arch/arm/include/asm/mach/time.h。
: N3 f$ A: y6 U6 r6 N
2 J6 g# F+ [5 A# W; p3 L) N1 }/*
+ f- V& K9 ?, @" y! ]& z * This is our kernel timer structure.5 d/ i. M5 U* i4 z
*
( {( M! H7 P  p2 R * - init
1 A3 j6 J& H7 \1 ?. a& r) Z *   Initialise the kernels jiffy timer source, claim interrupt1 d' B9 H7 c4 v  |/ S
*   using setup_irq.  This is called early on during initialisation
# Z' U- i- H: q# P9 Y" r *   while interrupts are still disabled on the local CPU.
% ]! j1 X4 r/ Q7 k% r  O * - suspend2 M; W- ?2 ^, V# v! A/ i$ b, r
*   Suspend the kernel jiffy timer source, if necessary.  This% x2 Y. E7 P% G4 t. ?
*   is called with interrupts disabled, after all normal devices
- E$ V; [$ `1 }% n6 `  e7 y1 D *   have been suspended.  If no action is required, set this to
1 w. [/ i) i# v0 |4 C4 ^ *   NULL.
2 l! j: v9 h7 l& W8 P8 z" Y * - resume. r  I/ e7 S8 T8 k0 I4 t- o6 e
*   Resume the kernel jiffy timer source, if necessary.  This  y/ Y$ N1 Q$ R8 ?2 y0 M
*   is called with interrupts disabled before any normal devices
7 I( i. [5 H( y$ I3 o$ b- @3 G *   are resumed.  If no action is required, set this to NULL.$ F$ \3 j( g4 N& J3 o
* - offset: {( T; n& a! P! g8 B9 h$ @5 N+ z( o
*   Return the timer offset in microseconds since the last timer) w2 K/ {' r  ~/ P# D% W( q/ ]
*   interrupt.  Note: this must take account of any unprocessed
* G- l9 D% ]9 `1 N *   timer interrupt which may be pending.
, L( q1 z6 J3 v, v */
$ j; w7 |% f! y! pstruct sys_timer {7 P* i7 L0 g/ Y
        struct sys_device        dev;; c2 F( j/ e) \; h% v
        void                        (*init)(void);! q+ Z( ~( Q1 m, x
        void                        (*suspend)(void);# d  J. \: d6 l* v  ^4 a& _
        void                        (*resume)(void);
5 D  w7 S% y9 z  |#ifndef CONFIG_GENERIC_TIME
1 h! I, O3 N7 L/ P7 n        unsigned long                (*offset)(void);
1 Q, B0 Z! p1 x. V% d% ?8 ?3 E) Z#endif
, u& U7 q- H% L/ C7 L) l};2 y. f2 {3 E# N

% C# Z0 L/ v' [6 A( [- G/ U- tS3C2440的sys_timer的定义在linux/arch/arm/plat-s3c24xx/time.c中,给出的三个方法也在该文件中定义。
( b" ?, B5 W# U: Sstruct sys_timer s3c24xx_timer = {
: z. I# {0 _* ^    .init        = s3c2410_timer_init,
8 K( i4 u( v- w" ^    .offset        = s3c2410_gettimeoffset,
# X8 _% g$ Z; Q! M    .resume        = s3c2410_timer_setup8 M, ?7 U# o$ |
};
4 P% \8 ]; D* @$ W
6 C8 s- a5 i3 w) f0 G" l( l. ^0 J如何将该定时器告知内核呢?
/ U) z9 ?& ^5 |+ k- T' x在linux/arch/arm/mach-s3c2440/mach-smdk2440.c的最后使用了宏
7 V+ k, e  w9 A' R" B  L
4 O+ G8 Z: f4 t) J+ M  s& xMACHINE_START(S3C2440, "SMDK2440")
0 ~+ ^7 s% P: }  Q  r        /* Maintainer: Ben Dooks <ben@fluff.org> */
1 D$ s6 n: ]. |& E) I        .phys_io        = S3C2410_PA_UART,
* |" G" p$ x) G8 ?        .io_pg_offst        = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
' a9 n1 ?& X" k! m. R        .boot_params        = S3C2410_SDRAM_PA + 0x100,! X) D7 e5 B4 r, x" V9 _" ~

% _, h, e% x6 s- T        .init_irq        = s3c24xx_init_irq,. F+ J7 a: k' d9 z4 t% A
        .map_io                = smdk2440_map_io,% A2 Z! z* z7 Z( n
        .init_machine        = smdk2440_machine_init,% g* I; b0 V! |: f
        .timer                = &s3c24xx_timer,$ b' W6 b! u# r/ D
MACHINE_END5 ^% N( `& T9 H
& k. b& k/ b  I# t7 l
该宏用于初始化结构体struct machine_desc,结构体成员如下:6 S, [" I# B' w  U4 d" L* h
struct machine_desc {$ y) c: L3 E9 e/ i1 `6 S# f4 K7 X0 T/ d' ~
        /*
9 |  g! v7 P: ]4 m         * Note! The first four elements are used
8 H/ p  h, t3 O+ Q4 J- ]         * by assembler code in head.S, head-common.S
3 j, X  `& U. \% K* Z  K         */
* D! y; ?2 S4 _. ~: b        unsigned int                nr;                /* architecture number        */
8 Y# R( i/ s7 ]9 M        unsigned int                phys_io;        /* start of physical io        */. A/ y+ i, R5 e' l
        unsigned int                io_pg_offst;        /* byte offset for io 2 C6 d3 b* c  U& E6 t3 S1 d8 `
                                                 * page tabe entry        */
; g% p# o7 S% \: k3 E
2 n9 V: }7 }' f; K+ D4 K        const char                *name;                /* architecture name        */
- Z6 s, G1 v" F5 M        unsigned long                boot_params;        /* tagged list                */
' ~  K  Y7 P/ f$ Y5 x' ? " ^+ G- \+ j0 G
        unsigned int                video_start;        /* start of video RAM        */# L: d: j+ ~" T7 C
        unsigned int                video_end;        /* end of video RAM        */
1 h1 T! f0 u  A4 l! N
6 V5 d; _( W/ q$ K; A- x        unsigned int                reserve_lp0 :1;        /* never has lp0        */
, _7 V9 z, q3 K; F6 a* l        unsigned int                reserve_lp1 :1;        /* never has lp1        */
% d/ ?4 S, U$ l& w# E        unsigned int                reserve_lp2 :1;        /* never has lp2        */
. }" B) F% {$ @' i        unsigned int                soft_reboot :1;        /* soft reboot                */
; K. R& j- |: `* Q4 b! _$ d) r5 B, b        void                        (*fixup)(struct machine_desc *,% ]  L7 u) O; O* ]
                                         struct tag *, char **,
3 ^% d, W- w8 j6 ?. r                                         struct meminfo *);( o0 y& j5 ?7 P7 y, A
        void                        (*map_io)(void);/* IO mapping function        */1 G& R9 H6 K3 G
        void                        (*init_irq)(void);( J5 t7 g+ O6 _1 ]' M. M2 F! z- {
        struct sys_timer        *timer;                /* system tick timer        */: ?, b" U+ q' [" F
        void                        (*init_machine)(void);0 e; a3 h" E5 T1 q
};
* \8 |8 e/ `& o" E
# w  t6 x, i% v, \6 Z% L在这里我们看到了timer指针。通过该宏将timer指针指向了s3c24xx_timer。: t. U8 k8 q& t) s  [! A
接着,再看linux/arch/arm/kernel/setup.c中的setup_arch函数,该函数中执行了下面这话:
# Q) `. ]1 [8 m# \6 O8 e3 ]
5 H* {- U  u& t! f5 v" [    system_timer = mdesc->timer;# a" t& n6 V/ _* P  z( V3 U+ H9 F
" s1 p6 j  }1 c4 P- x1 s
mdesc->timer即为上面宏所给出的s3c24xx_timer,而system_timer为全局变量。通过该全局变量就可使用节拍定时器。2 _  W; c. p( }/ D1 |: m
; ~  C9 M$ `: Z0 u  i+ j, X" M" J, H
最后,我们看下节拍定时器的init方法何时被调用,调用顺序如下:
* c0 x' I( a- O" q& N
5 ?( a6 h8 S3 h" X* I9 ]start_kernel ()-->  time_init()  --> system_timer->init()% C) ~. d+ y3 }: q

0 v5 }& ^# k" [& f) J/ c/ mtime_init  -函数位于linux/arch/arm/kernel/time.c。
) I$ |% ]: V' s/ w
- J8 D2 Q+ X0 T. ?* h( v* `! H& b
1 D! ^+ F) Y) E0 D
& n2 ~, v+ b9 }3 ^: _. {8 D) f
  H6 x/ s( v: W1 N3 P) A8 O8 [5 l. x8 |% a6 w( h/ ?8 ]/ o
+ h) N, e  m' _
5 _- ]( t* G$ 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 19:06 , Processed in 0.171875 second(s), 24 queries , Gzip On.

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

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

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