Timer Programming in Linux Embedded System Lab. II Embedded System Lab. II 1 (event-driven) (time-driven) time-driven eventdriven RTC(Real Time Clock) RTC CPU RTC xtime RTC /dev/rtc RTC Embedded System Lab. II 2 Embedded System Lab. II 3
PIT(Programmable Interrupt Timer) ( ) PIT PIT ( ) (tick) tick tick Hz(10ms) IRQ0 () (Tick Rate) HZ preprocessor HZ <arm/param.h> // arm #define HZ Architecture HZ ( ) Embedded System Lab. II 4 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 0 32 or 1024 50,, or 0 or 0 0 24,, or 122 0 (HZ) HZ ( tick) poll(), select() HZ Embedded System Lab. II 6 Embedded System Lab. II 7
jiffies Jiffies overflow 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) 32 jiffies HZ 497 overflow 0 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 8 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*/ xtime_lock Jiffies_64 xtime do_timer() xtime_lock Embedded System Lab. II 10 Embedded System Lab. II 11
do_timer() Jiffies_64 1 xtime_lock 32 scheduler_tick() xtime (load average) /* */ /* */ 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 12 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 * (0000 / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 0); while (read_seqretry(&xtime_lock, seq)); (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 14 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 <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 18 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 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 20 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);. void process_timeout(unsigned long data) wake_up_process((struct task_struct *)data); Embedded System Lab. II 23 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);
PXA In up time(), ftime(), gettimeofday() time() 1970 1 1 ftime() timeb gettimeofday() ftime() timeval timezone 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 24 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 */ 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 26 Embedded System Lab. II 27
pxa_timer_interrupt() do_timer(struct pt_regs *regs) 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 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; void timer_bh(void) update_times(); run_timer_list(); timer_bh(void) Embedded System Lab. II 30 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); 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 >= 0000) xtime.tv_usec -= 0000; xtime.tv_sec++; second_overflow(); Embedded System Lab. II 32 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; repeat: head = tv1.vec + tv1.index; curr = head->next; if (curr!= head) struct timer_list *timer; void (*fn)(unsigned long); unsigned long data; run_timer_list(void) (2) 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 34 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); Timer (mytimer.c) Embedded System Lab. II 36 Embedded System Lab. II 37 /* global variables */ static struct timer_list s_mytimer; static struct mytimer_data s_mytimer_data; void cleanup_module(void) del_mytimer(); Timer /* 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; 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 add_mytimer(); Timer return 0; Embedded System Lab. II 38 Embedded System Lab. II 39
void add_mytimer(void) init_timer(&s_mytimer); s_mytimer.function = mytimer_proc; s_mytimer.data = (unsigned long) &s_mytimer_data; s_mytimer.expires = jiffies + HZ * 5; /* 5 seconds */ Timer 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 0000 0000 0000 0000 0000 0000 0000 0000 3 2 1 0 FP FS PXA255 Processor Clock CCLKCFG cp14 c6.1 : turbo 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 OPDE [0x 40F0 001C] OSCC, OON 1 0 1 0 CCCR Embedded System Lab. II 42 Embedded System Lab. II 43
L 27 27 36 45 27 Core PLL Output Frequencies M 1 2 2 2 4 Turbo Mode Frequency (MHz) for Values N and Core Clock Configuration Register (CCCR[15:0]) Programming for Values of N : 1.00 (Run) 99.5 @1.0 V 36 1 132.7 @1.0 V 199.1 @1.0 V 265.4 @1.1 V 331.8 @1.3 V 398.1 @1.3 V 1.50 298.6 @1.1 v 2.00 199.1 @1.0 V 398.1 @1.3 V 3.00 298.6 @1.1 v PXbus Frequency 50 66 99.5 132.7 165.9 196 MEM, LCD Frequency (MHz) 99.5 132.7 99.5 132.7 165.9 99.5 SDRAM max Freq 99.5 66 99.5 66 83 99.5 N[9:7] Core Clock Configuration Register(CCCR) (1) 31 30 29 28 27 26 25 24 23 22 21 20 0000 0000 0000 0000 0000 0001 0010 0001 Run Mode Frequency Turbo Mode Frequency Turbo Mode Freq. = Run Mode Frequency * N 000, 001, 101, 111 001(Multiplier) = 1 011(Multiplier) = 1.5 (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 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 N M 3 2 1 0 L Embedded System Lab. II 44 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 N M L 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 N M L M [6:5] Memory Frequency Run Mode Frequency Memory Freq = Crystal Frequency * L 00, 11 01(Multiplier) = 1(Multiplier 1 Run Mode Freq Memory Frequency.) 10(Multiplier) = 2(Multiplier 2 Run Mode Freq Memory Frequency 2.) L[4:0] Crystal Frequency Memory Frequency (3.6864MHz Crystal ) 00000, 00110 to 11111 00001(Multiplier) = 27 (Memory Freq 99.53MHz.) 00010(Multiplier) = 32 (Memory Freq 117.96MHz.) 00011(Multiplier) = 36 (Memory Freq 132.71MHz.) 00(Multiplier) = 40 (Memory Freq 147.46MHz.) 00101(Multiplier) = 45 (Memory Freq 165.89MHz.) Hardware Reset, Watchdog Reset 10 default. Memory Freq(99.5MHz) = Crystal Frequency(3.6864MHz) * L(27) Hardware Reset, Watchdog Reset 00001 default. Embedded System Lab. II 46 Embedded System Lab. II 47
Clock Enable Register(CKEN)(1) 31 30 29 28 27 26 25 24 23 22 21 20 0000 0000 0000 0001 0111 1101 1110 1111 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 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 CKEN13 CKEN11 CKEN8 CKEN6 CKEN2 CKEN0 CKEN16 CKEN14 CKEN12 CKEN7 CKEN5 CKEN3 CKEN1 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 31 30 29 28 27 26 25 24 23 22 21 20 Oscillator Configuration Register(OSCC) 0000 0000 0000 0000 0000 0000 0000 0000 Embedded System Lab. II 51 OON OOK OSCC 32.768MHz Oscillator Configuration Control Register. Oscillator 10. Oscillator OOK bit 1 set. OON[1] 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 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 3 2 1 0
Timers and Watchdog RTC Alarm Register(RTAR) 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 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> Physical Address 0x40900004 RTC Target Match Value RTC counter Register(RCNR). Embedded System Lab. II 52 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 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???????????????????????????? 0000 ALE RCV HZE HZ AL 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 <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
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 0?????00 0000 0000 0111 1111 1111 1111 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 3 2 1 0 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 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 + 0 (OSMR1 = 0 OSCR = 0 ) OSMR1 = 0 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 3 2 1 0 Embedded System Lab. II 56 Embedded System Lab. II 57 OS Timer Counter Register(OSCR) 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 0000 0000 0000 0000 0000 0000 0000 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 OSCV E3 E2 E1 E0 OS Timer Counter Register - 32bit counter 3.6863MHz rising edge 1 OSCV<31:0> : OS Timer Counter Value Register OSMR Register Physical Address 0x40A00010 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 58 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 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