Timer Programming in Linux Embedded System Lab. II
Embedded System Lab. II 1
(event-driven) (time-driven) time-driven eventdriven Embedded System Lab. II 2
RTC(Real Time Clock) RTC CPU RTC xtime RTC /dev/rtc RTC Embedded System Lab. II 3
PIT(Programmable Interrupt Timer) ( ) PIT PIT ( ) (tick) tick tick 100Hz(10ms) IRQ0 () Embedded System Lab. II 4
(Tick Rate) HZ preprocessor HZ <arm/param.h> // arm #define HZ 100 Architecture 100HZ ( ) Embedded System Lab. II 5
(HZ) alpha arm cris h8300 i386 ia64 m68k m68knommu mips mips64 parisc ppc ppc64 s390 sh sparc sparc64 um v850 x86-64 1024 100 100 100 1000 32 or 1024 100 50,100, or 1000 100 100 100 or 1000 100 1000 100 100 100 100 100 24, 100, or 122 1000 Embedded System Lab. II 6
HZ HZ ( tick) poll(), select() HZ Embedded System Lab. II 7
jiffies jiffies 0 jiffies jiffies <linux/jiffies.h> extern unsigned long volatile jiffies Jiffies/HZ seconds = system uptime 1 jiffies = 1/HZ jiffies (second * HZ) jiffies (jiffies / HZ) Embedded System Lab. II 8
Jiffies overflow 32 jiffies 100 HZ 497 overflow 1000 HZ 49.7 overflow 64 jiffies overflow 64 ALPHA 5 2.6 jiffies unsigned long u64 extern u64 jiffies_64; (linker scripts) jiffies jiffies_64 overlay Embedded System Lab. II 9
Jiffies wraparound (tick) 1 0 4 <linux/jiffies.h> #define time_after(unknown, known) ((long)(known) (long)(unknown) < 0) #define time_before(unknown, known) ((long)(unknown) (long)(known) < 0) #define time_after_eq(unknown, known) ((long)(unknown) (long)(known) >= 0) #define time_before_eq(unknown, known) ((long)(known) (long)(unknown) >= 0) // 0.5 unsigned long timeout = jiffies + HZ/2; If (timeout < jiffies) { /* not time out*/ else { /*time out*/ // 0.5 unsigned long timeout = jiffies + HZ/2; If ( time_after(jiffies, timeout) ) { /* not time out*/ else { /*time out*/ Embedded System Lab. II 10
xtime_lock Jiffies_64 xtime do_timer() xtime_lock Embedded System Lab. II 11
do_timer() Jiffies_64 1 xtime_lock 32 scheduler_tick() xtime (load average) Embedded System Lab. II 12
/* */ /* */ void do_timer(struct pt_regs* regs) { jiffies_64++; update_process_times(user_mode(regs)); /* */ update_times(); user_mode() regs 1, 0 return update_process_times() Embedded System Lab. II 13
xtime xtime_lock seq xtime write_seqlock(&xtime_lock); /* xtime */ write_sequnlock(&xtime_lock); xtime do { unsigned long lost; seq = read_seqbegin (&xtime_lock); usec = timer->get_offset(); lost = jiffies wall_jiffies; if (lost) usec += lost * (1000000 / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); while (read_seqretry(&xtime_lock, seq)); Embedded System Lab. II 14
(wall time) <kernel/time.c> struct timespec xtime; timespec <linux/time.h> struct timespec { time_t tv_sec; // long tv_nsec; // ; xtime.tv_sec 1970 1 1(UTC) - (epoch : ) xtime.v_nsec Embedded System Lab. II 15
gettimeofday() sys_gettimeofday() time() time() gettimeofday() C ftime(), ctime() asmlinkage long sys_gettimeofday(struct timeval* tv, struct timezone* tz) { if (likely(tv!= NULL)) { struct timeval ktv;` do_gettimeofday(&ktv); if (copy_to_user(tz, &sys_tz, sizeof(ktv))) return -EFAULT if (unlikely(tz!= NULL)) { if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) return -EFAULT return 0; tv NULL _do_gettimeofday() xtime. tz NULL (zone) return time zone return EFAULT return 0 return. Embedded System Lab. II 16
( ) ( ), Embedded System Lab. II 17
struct timer_list <linux/timer.h> struct timer_list { struct list_head entry; // unsigned long expires; //, jiffy spinlock_t lock; // void (*function)(unsigned long); // unsignde long data; // struct tvec_t_base_s* base; // jiffies timer->expires timer- >function jiffy current value + the amount of the desired delay Embedded System Lab. II 18
<linux/timer.h> kernel/timer.c // void init_timer(struct timer_list *timer); // void add_timer(struct timer_list *timer); // int mod_timer(struct timer_list *timer, unsigned long expires); // () // int del_timer(struct timer_list *timer); // int del_timer_sync(struct timer_list *timer); Embedded System Lab. II 19
mod_timer() SMP CPU del_timer(my_timer); my_timer->expires = jiffies + new_delay add_timer(my_timer); del_timer(&mytimer); x_release_resources(); SMP del_timer_sync() timerlist_lock spin lock Embedded System Lab. II 20
5 struct timer_vec_root { tvecs int index; struct list_head vec[256]; tv1; struct timer_vec { int index; struct list_head vec[64]; tv2, tv3, tv4, tv5; tv1 tv2 tv3 tv4 tv5 Embedded System Lab. II 21
Bottom-Half Lock busy unsigned long delay = jiffies + 2*HZ; /* two seconds */ while (time_before(jiffies, delay)) ; while (time_before(jiffies, delay)) cond_resched( ); <linux/delay.h> void udelay(unsigned long usecs); /* microsecond delay */ void mdelay(unsigned long msecs); /* millisecond delay */ Embedded System Lab. II 22
Schedule_timeout(). timeout = 2*HZ; set_current_state(tast_interruptible); timeout = schedule_timeout(timeout);. schedule_timeout(timeout) { struct timer_list timer; expire = timeout + jiffies; init_timer(&timer); timer.expires = expire; timer.data = (unsigned long)current; timer.function = process_timeout; add_timer(&timer); schedule(); del_timer_sync(&timer); timeout = expire - jiffies; return (timeout < 0? 0 : timeout); void process_timeout(unsigned long data){ wake_up_process((struct task_struct *)data); Embedded System Lab. II 23
time(), ftime(), gettimeofday() time() 1970 1 1 ftime() timeb gettimeofday() ftime() timeval timezone Embedded System Lab. II 24
PXA In up PIT time_init() IRQ0 static struct irq0 = { timer_interrupt, SA_INTERRUPT, 0, time, NULL, NULL timer_interrupt() -> do_timer_interrupt() -> do_timer() BHs TIMER_BH TQUEUE_BH(tq_timer ) ARM(PXA255 CPU) setup_timer() -> pxa_timer_interrupt() -> do_timer() -> update_process_times() -> timer_bh() -> update_times() -> run_timer_list() Embedded System Lab. II 25
setup_timer (void) extern inline void setup_timer (void) { gettimeoffset = pxa_gettimeoffset; set_rtc = pxa_set_rtc; xtime.tv_sec = pxa_get_rtc_time(); timer_irq.handler = pxa_timer_interrupt; OSMR0 = 0; /* set initial match at 0 */ OSSR = 0xf; /* clear status on all timers */ setup_arm_irq(irq_ost0, &timer_irq); OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ OSCR = 0; /* initialize free-running timer, force first match */ Embedded System Lab. II 26
static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { long flags; int next_match; do_profile(regs); do { do_leds(); do_set_rtc(); save_flags_cli( flags ); do_timer(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); restore_flags( flags ); while( (signed long)(next_match - OSCR) <= 0 ); void do_timer(struct pt_regs *regs) { (*(unsigned long *)&jiffies)++; #ifndef CONFIG_SMP /* SMP process accounting uses the local APIC timer */ update_process_times(user_mode(regs)); #endif mark_bh(timer_bh); if (TQ_ACTIVE(tq_timer)) mark_bh(tqueue_bh); void timer_bh(void) { update_times(); run_timer_list(); Embedded System Lab. II 27
pxa_timer_interrupt() static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { long flags; int next_match; do_profile(regs); /* Loop until we get ahead of the free running timer. * This ensures an exact clock tick count and time acuracy. * IRQs are disabled inside the loop to ensure coherence between * lost_ticks (updated in do_timer()) and the match reg value, so we * can use do_gettimeofday() from interrupt handlers. */ do { do_leds(); do_set_rtc(); save_flags_cli( flags ); do_timer(regs); OSSR = OSSR_M0; /* Clear match on timer 0 */ next_match = (OSMR0 += LATCH); restore_flags( flags ); while( (signed long)(next_match - OSCR) <= 0 ); Embedded System Lab. II 28
do_timer(struct pt_regs *regs) void do_timer(struct pt_regs *regs) { (*(unsigned long *)&jiffies)++; #ifndef CONFIG_SMP /* SMP process accounting uses the local APIC timer */ update_process_times(user_mode(regs)); #endif mark_bh(timer_bh); if (TQ_ACTIVE(tq_timer)) mark_bh(tqueue_bh); Embedded System Lab. II 29
update_process_times() void update_process_times(int user_tick) { struct task_struct *p = current; int cpu = smp_processor_id(), system = user_tick ^ 1; update_one_process(p, user_tick, system, cpu); if (p->pid) { if (--p->counter <= 0) { p->counter = 0; p->need_resched = 1; if (p->nice > 0) kstat.per_cpu_nice[cpu] += user_tick; else kstat.per_cpu_user[cpu] += user_tick; kstat.per_cpu_system[cpu] += system; else if (local_bh_count(cpu) local_irq_count(cpu) > 1) kstat.per_cpu_system[cpu] += system; Embedded System Lab. II 30
timer_bh(void) void timer_bh(void) { update_times(); run_timer_list(); Embedded System Lab. II 31
void update_times(void) static inline void update_times(void) { unsigned long ticks; /* * update_times() is run from the raw timer_bh handler so we * just know that the irqs are locally enabled and so we don't * need to save/restore the flags of the local CPU here. -arca */ write_lock_irq(&xtime_lock); ticks = jiffies - wall_jiffies; if (ticks) { wall_jiffies += ticks; update_wall_time(ticks); write_unlock_irq(&xtime_lock); calc_load(ticks); Embedded System Lab. II 32
update_wall_time(unsigned long ticks) static void update_wall_time(unsigned long ticks) { do { ticks--; update_wall_time_one_tick(); while (ticks); if (xtime.tv_usec >= 1000000) { xtime.tv_usec -= 1000000; xtime.tv_sec++; second_overflow(); Embedded System Lab. II 33
run_timer_list(void) (1) static inline void run_timer_list(void) { spin_lock_irq(&timerlist_lock); while ((long)(jiffies - timer_jiffies) >= 0) { LIST_HEAD(queued); struct list_head *head, *curr; if (!tv1.index) { int n = 1; do { cascade_timers(tvecs[n]); while (tvecs[n]->index == 1 && ++n < NOOF_TVECS); run_timer_list_running = &queued; Embedded System Lab. II 34
run_timer_list(void) (2) repeat: head = tv1.vec + tv1.index; curr = head->next; if (curr!= head) { struct timer_list *timer; void (*fn)(unsigned long); unsigned long data; timer = list_entry(curr, struct timer_list, list); fn = timer->function; data= timer->data; detach_timer(timer); timer->list.next = timer->list.prev = NULL; timer_enter(timer); spin_unlock_irq(&timerlist_lock); fn(data); spin_lock_irq(&timerlist_lock); timer_exit(); goto repeat; Embedded System Lab. II 35
run_timer_list(void) (3) run_timer_list_running = NULL; ++timer_jiffies; tv1.index = (tv1.index + 1) & TVR_MASK; curr = queued.next; while (curr!= &queued) { struct timer_list *timer; timer = list_entry(curr, struct timer_list, list); curr = curr->next; internal_add_timer(timer); spin_unlock_irq(&timerlist_lock); Embedded System Lab. II 36
Timer (mytimer.c) Embedded System Lab. II 37
/* global variables */ static struct timer_list s_mytimer; static struct mytimer_data s_mytimer_data; /* function prototypes */ static void mytimer_proc(unsigned long ptr); static void add_mytimer(void); void del_mytimer(void); /* Module startup/cleanup */ int init_module(void){ printk("loading Timer\n"); s_mytimer_data.m_times = 0; s_mytimer_data.m_endtimes = 5; add_mytimer(); Timer return 0; Embedded System Lab. II 38
void cleanup_module(void) { del_mytimer(); Timer printk("unloading Timer\n"); void mytimer_proc(unsigned long ptr) { struct mytimer_data *pdata = (struct mytimer_data *) ptr; ++pdata->m_times; printk("timer called %d/%d\n", pdata->m_times, pdata->m_endtimes); if (pdata->m_times < pdata->m_endtimes) add_mytimer(); Timer Embedded System Lab. II 39
void add_mytimer(void) { init_timer(&s_mytimer); Timer s_mytimer.function = mytimer_proc; s_mytimer.data = (unsigned long) &s_mytimer_data; s_mytimer.expires = jiffies + HZ * 5; /* 5 seconds */ add_timer(&s_mytimer); Timer void del_mytimer(void) { del_timer(&s_mytimer); Embedded System Lab. II 40
Embedded System Lab. II 41
PCFR (Power Manager General Configuration Register) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 Reserved FP FS OPDE [0x 40F0 001C] OPDE [0] 3.6864MHz oscillator power-down enable. FP [1] Float PCMCIA controls during Sleep Mode. FS [2] Float Static Chip Selects during Sleep Mode. Address : 0x40F0001C Embedded System Lab. II 42
PXA255 Processor Clock CCLKCFG cp14 c6.1 : turbo OSCC, OON 1 0 1 CCCR 0 Embedded System Lab. II 43
Core PLL Output Frequencies L M Turbo Mode Frequency (MHz) for Values N and Core Clock Configuration Register (CCCR[15:0]) Programming for Values of N : 1.00 (Run) 1.50 2.00 3.00 PXbus Frequency MEM, LCD Frequency (MHz) SDRAM max Freq 27 1 99.5 @1.0 V 199.1 @1.0 V 298.6 @1.1 v 50 99.5 99.5 36 1 132.7 @1.0 V 66 132.7 66 27 2 199.1 @1.0 V 298.6 @1.1 v 398.1 @1.3 V 99.5 99.5 99.5 36 2 265.4 @1.1 V 132.7 132.7 66 45 2 331.8 @1.3 V 165.9 165.9 83 27 4 398.1 @1.3 V 196 99.5 99.5 Embedded System Lab. II 44
Core Clock Configuration Register(CCCR) (1) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0001 0010 0001 Reserved N M L N[9:7] Run Mode Frequency Turbo Mode Frequency Turbo Mode Freq. = Run Mode Frequency * N 000, 001, 101, 111 Reserved 001(Multiplier) = 1 011(Multiplier) = 1.5 100 (Multiplier) = 2 110 (Multiplier) = 3 Hardware Reset, Watchdog Reset 010 default. Turbo Mode Freq(398.1MHz) = Run Mode Freq(199.1MHz) * N(2) Address : 0x4130/0004 Embedded System Lab. II 45
Core Clock Configuration Register(CCCR) (2) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0001 0010 0001 Reserved N M L M [6:5] Memory Frequency Run Mode Frequency Memory Freq = Crystal Frequency * L 00, 11 Reserved 01(Multiplier) = 1(Multiplier 1 Run Mode Freq Memory Frequency.) 10(Multiplier) = 2(Multiplier 2 Run Mode Freq Memory Frequency 2.) Hardware Reset, Watchdog Reset 10 default. Memory Freq(99.5MHz) = Crystal Frequency(3.6864MHz) * L(27) Embedded System Lab. II 46
Core Clock Configuration Register(CCCR) (3) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0001 0010 0001 Reserved N M L L[4:0] Crystal Frequency Memory Frequency (3.6864MHz Crystal ) 00000, 00110 to 11111 Reserved 00001(Multiplier) = 27 (Memory Freq 99.53MHz.) 00010(Multiplier) = 32 (Memory Freq 117.96MHz.) 00011(Multiplier) = 36 (Memory Freq 132.71MHz.) 00100(Multiplier) = 40 (Memory Freq 147.46MHz.) 00101(Multiplier) = 45 (Memory Freq 165.89MHz.) Hardware Reset, Watchdog Reset 00001 default. Embedded System Lab. II 47
Clock Enable Register(CKEN)(1) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0001 0111 1101 1110 1111 Reserved Reserved CKEN13 CKEN11 CKEN8 CKEN6 Reserved CKEN2 CKEN0 CKEN16 CKEN14 CKEN12 Reserved CKEN7 CKEN5 CKEN3 CKEN1 CKEN16[16] LCD Unit Clock Enable 0 = Clock LCD Unit. 1 = Clock LCD Unit. Hardware Reset, Watchdog Reset 1 set. CKEN14[14] I2C Unit Clock Enable 0 = Clock I2C Unit. 1 = Clock I2C Unit. Hardware Reset, Watchdog Reset 1 set. CKEN13[13] FICP Unit Clock Enable 0 = Clock FICP Unit. 1 = Clock FICP Unit. Hardware Reset, Watchdog Reset 1 set. CKEN12[12] MMU Unit Clock Enable 0 = Clock MMU Unit. 1 = Clock MMU Unit. Hardware Reset, Watchdog Reset 1 set. Address : 0x4130/0004 Embedded System Lab. II 48
Clock Enable Register(CKEN)(2) CKEN11[11] USB Unit Clock Enable 0 = Clock USB Unit. 1 = Clock USB Unit. Hardware Reset, Watchdog Reset 1 set. GP7 Alternate Function 1 48MHz Clock 1 set CKEN8[8] I2S Unit Clock Enable 0 = Clock I2S Unit. 1 = Clock I2S Unit. Hardware Reset, Watchdog Reset 1 set. CKEN7[7] BTUART Unit Clock Enable 0 = Clock BTUART Unit. 1 = Clock BTUART Unit. Hardware Reset, Watchdog Reset 1 set. CKEN6[6] FFUART Unit Clock Enable 0 = Clock FFUART Unit. 1 = Clock FFUART Unit. Hardware Reset, Watchdog Reset 1 set. CKEN5[5] STUART Unit Clock Enable 0 = Clock STUART Unit. 1 = Clock STUART Unit. Hardware Reset, Watchdog Reset 1 set. Embedded System Lab. II 49
Clock Enable Register(CKEN)(3) CKEN3<3>SSP Unit Clock Enable 0 = Clock SSP Unit. 1 = Clock SSP Unit. Hardware Reset, Watchdog Reset 1 set. GP7 Alternate Function 1 48MHz Clock 1 set CKEN2<2>AC97 Unit Clock Enable 0 = Clock AC97 Unit. 1 = Clock AC97 Unit. Hardware Reset, Watchdog Reset 1 set. CKEN1<1>PWM1 Unit Clock Enable 0 = Clock PWM1 Unit. 1 = Clock PWM1 Unit. Hardware Reset, Watchdog Reset 1 set. CKEN0<0>PWM0 Unit Clock Enable 0 = Clock PWM0 Unit. 1 = Clock PWM0 Unit. Hardware Reset, Watchdog Reset 1 set. Embedded System Lab. II 50
Oscillator Configuration Register(OSCC) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 Reserved OON OOK OSCC 32.768MHz Oscillator Configuration Control Register. Oscillator 10. Oscillator OOK bit 1 set. OON[1] Write-once only bit 0 = 32.768MHz Oscillator RTC Power Manager Clock3.6863MHz Oscillator.(112 ) Page 3-3 Figure 3-1 Clocks Manager Block Diagram 1 = 32.768KHz Oscillator. Hardware Reset Clear. OOK[0] Read-only bit 0 = OON bit 0 Oscillator 1 = OON bit 1 set Oscillator RTC Power Manager Clock 32.768KHz Oscillator Clock Hardware Reset Clear. Address : 0x4130/0008 Embedded System Lab. II 51
Timers and Watchdog One free running timer Runs from 3.68 MHz clock Three general purpose timer registers User programs a specific value in the registers When timer reaches the preprogrammed value, interrupts may be generated One timer register general purpose or watchdog Operation determined by state of bit 0 in OWER Value loaded at reset If enabled, cannot be disabled until reset occurs OS should occasionally check timer and add to this value if necessary Embedded System Lab. II 52
RTC Alarm Register(RTAR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 RTMV RTAR RCNR RTSR[ALE] bit 1 set RTSR[AL] bit 1 set. RTMV<31:0> RTC Target Match Value RTC counter Register(RCNR). Physical Address 0x40900004 Embedded System Lab. II 53
RTC Counter Register(RCNR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 RCV RCNR Register 1Hz(Default) rising edge 1. RCV<31:0> RTC Count Value RTC Counter Register. Ex) RTAR = RCNR + 1; RTC Interrupt 1. Physical Address 0x40900000 Embedded System Lab. II 54
RTC Status Register(RTSR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16???????????????????????????? 0000 Reserved <3> HZE : HZ 0 = HZ 1 = HZ <2> ALE : RTC alarm 0 = RTC alarm 1 = RTC alarm <1> HZ : HZ rising-edge / 0 = rising-edge. 1 = rising-edge. HZE bit 1. <0> AL : RTC alarm / 0 = RTC alarm. 1 = RTC alarm.(rcnr RTAR 1set) ALE bit 1. Physical Address 0x40900008 RTC alarm ALE bit 1 set. Embedded System Lab. II 55 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 HZE ALE HZ AL
RTC Status Register(RTSR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0?????00 0000 0000 0111 1111 1111 1111 Reserved LCK DEL CK_DIV <31> LCK 0 = RTTR value 1 = RTTR value <25:16> DEL Trim delete count This value represents the number of 32KHz clocks to delete when clock trimming begins <15:0> CK_DIV Clock divider count 32KHz CK_DIV. Default 0x7fff RTC 1Hz. 32KHz 0. Ex1) RTAR = RTCR + 1; CK_DIV 1 RTC Interrupt. Physical Address 0x4090000C Embedded System Lab. II 56
OS Timer Match Register 0-3 (OSMR0,OSMR1,OSMR2,OSMR3) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 OSMV OSMV<31:0> : OS Timer Match Value Register OSCR Register. Register OSCR Register Interrupt. (4 OSMR Register OSMR Register OIER Bit 1 Set.) Ex) OSMR1 = OSCR + 1000 (OSMR1 = 0 OSCR = 0 ) OSMR1 = 1000 OSCR 0. OSCR counting OSMR1 Register. OSCR OSMR1 Interrupt. OSMR IRQ No. OSMR0 : 26 OSMR1 : 27 OSMR2 : 28 OSMR3 : 29 (ICPR Register ) Physical Address : 0x40A00000, 0x40A00004, 0x40A00008, 0x40A0000C Embedded System Lab. II 57
OS Timer Counter Register(OSCR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0000 0000 0000 0000 0000 0000 0000 0000 OSCV OS Timer Counter Register - 32bit counter 3.6863MHz rising edge 1 OSCV<31:0> : OS Timer Counter Value Register OSMR Register Physical Address 0x40A00010 Embedded System Lab. II 58
OS Timer Interrupt Enable Register(OIER) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4???????????????????????????? 3 2 1 0 0000 Reserved E3 E2 E1 E0 Register OSMR[0-3] OSCR OSMR Interrupt Register. E[3-0] : 0 = OSMR[3-0] OSCR Interrupt. 1 = OSMR[3-0] OSCR Interrupt. Physical Address 0x40A0001C Embedded System Lab. II 59
OS Timer Status Register(OSSR) 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4???????????????????????????? 3 2 1 0 0000 Reserved M3 M2 M1 M0 4 OSMR Register OSCR match OSMR Register OIER bit 1 set OSMR OSCR match OSSR[3-0] bit 1 set. M[3-0] : 0 = OSMR[3-0] OSCR match. 1 = OSMR[3-0] OSCR match. Physical Address 0x40A00014 Embedded System Lab. II 60