⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-------------------------------------------------------------------------+| timer.c v1.1 - PC386 BSP - 1997/08/07+--------------------------------------------------------------------------+| This file contains the PC386 timer package.+--------------------------------------------------------------------------+| NOTE: It is important that the timer start/stop overhead be determined|       when porting or modifying this code.+--------------------------------------------------------------------------+| (C) Copyright 1997 -| - NavIST Group - Real-Time Distributed Systems and Industrial Automation|| http://pandora.ist.utl.pt|| Instituto Superior Tecnico * Lisboa * PORTUGAL+--------------------------------------------------------------------------+| Disclaimer:|| This file is provided "AS IS" without warranty of any kind, either| expressed or implied.+--------------------------------------------------------------------------+| This code is base on:|   timer.c,v 1.7 1995/12/19 20:07:43 joel Exp - go32 BSP|| Rosimildo daSilva -ConnectTel, Inc - Fixed infinite loop in the Calibration| routine. I've seen this problems with faster machines ( pentiums ). Sometimes| RTEMS just hangs at startup.|| With the following copyright notice:| **************************************************************************| *  COPYRIGHT (c) 1989-1999.| *  On-Line Applications Research Corporation (OAR).| *| *  The license and distribution terms for this file may be| *  found in found in the file LICENSE in this distribution or at| *  http://www.rtems.com/license/LICENSE.| **************************************************************************||  $Id: timer.c,v 1.12.6.2 2005/10/05 02:39:35 joel Exp $+--------------------------------------------------------------------------*/#include <stdlib.h>#include <bsp.h>#include <irq.h>/*-------------------------------------------------------------------------+| Constants+--------------------------------------------------------------------------*/#define AVG_OVERHEAD  0              /* 0.1 microseconds to start/stop timer. */#define LEAST_VALID   1              /* Don't trust a value lower than this.  */#define SLOW_DOWN_IO  0x80     	/* io which does nothing */#define TWO_MS	(uint32_t)(2000)     /* TWO_MS = 2000us (sic!) */#define MSK_NULL_COUNT 0x40	/* bit counter available for reading */#define CMD_READ_BACK_STATUS 0xE2   /* command read back status *//*-------------------------------------------------------------------------+| Global Variables+--------------------------------------------------------------------------*/volatile uint32_t         Ttimer_val;rtems_boolean    	  Timer_driver_Find_average_overhead = TRUE;volatile unsigned int     fastLoop1ms, slowLoop1ms;void (*Timer_initialize_function)(void) = 0;uint32_t (*Read_timer_function)(void) = 0;void (*Timer_exit_function)(void) = 0;/*-------------------------------------------------------------------------+| External Prototypes+--------------------------------------------------------------------------*/extern void timerisr(void);       /* timer (int 08h) Interrupt Service Routine (defined in 'timerisr.s') */extern int x86_capability;/* * forward declarations */void Timer_exit();/*-------------------------------------------------------------------------+| Pentium optimized timer handling.+--------------------------------------------------------------------------*//*-------------------------------------------------------------------------+|         Function: rdtsc|      Description: Read the value of PENTIUM on-chip cycle counter.| Global Variables: None.|        Arguments: None.|          Returns: Value of PENTIUM on-chip cycle counter.+--------------------------------------------------------------------------*/static inline unsigned long longrdtsc(void){  /* Return the value of the on-chip cycle counter. */  unsigned long long result;  asm volatile(".byte 0x0F, 0x31" : "=A" (result));  return result;} /* rdtsc *//*-------------------------------------------------------------------------+|         Function: Timer_exit|      Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is|                   not really necessary, since there will be a reset at exit.| Global Variables: None.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/voidtsc_timer_exit(void){} /* tsc_timer_exit *//*-------------------------------------------------------------------------+|         Function: Timer_initialize|      Description: Timer initialization routine.| Global Variables: Ttimer_val.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/voidtsc_timer_initialize(void){  static rtems_boolean First = TRUE;  if (First)  {    First = FALSE;    atexit(Timer_exit); /* Try not to hose the system at exit. */  }  Ttimer_val = rdtsc(); /* read starting time */} /* tsc_timer_initialize *//*-------------------------------------------------------------------------+|         Function: Read_timer|      Description: Read hardware timer value.| Global Variables: Ttimer_val, Timer_driver_Find_average_overhead.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/uint32_ttsc_read_timer(void){  register uint32_t         total;  total =  (uint32_t)(rdtsc() - Ttimer_val);  if (Timer_driver_Find_average_overhead)    return total;  else if (total < LEAST_VALID)    return 0; /* below timer resolution */  else    return (total - AVG_OVERHEAD);} /* tsc_read_timer *//*-------------------------------------------------------------------------+| Non-Pentium timer handling.+--------------------------------------------------------------------------*/#define US_PER_ISR   250  /* Number of micro-seconds per timer interruption *//*-------------------------------------------------------------------------+|         Function: Timer_exit|      Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is|                   not really necessary, since there will be a reset at exit.| Global Variables: None.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/static voidtimerOff(const rtems_raw_irq_connect_data* used){    /*     * disable interrrupt at i8259 level     */     BSP_irq_disable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);     /* reset timer mode to standard (DOS) value */     outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);     outport_byte(TIMER_CNTR0, 0);     outport_byte(TIMER_CNTR0, 0);} /* Timer_exit */static voidtimerOn(const rtems_raw_irq_connect_data* used){     /* load timer for US_PER_ISR microsecond period */     outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);     outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 0 & 0xff);     outport_byte(TIMER_CNTR0, US_TO_TICK(US_PER_ISR) >> 8 & 0xff);    /*     * enable interrrupt at i8259 level     */     BSP_irq_enable_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);}static inttimerIsOn(const rtems_raw_irq_connect_data *used){     return BSP_irq_enabled_at_i8259s(used->idtIndex - BSP_IRQ_VECTOR_BASE);}static rtems_raw_irq_connect_data timer_raw_irq_data = {  BSP_PERIODIC_TIMER + BSP_IRQ_VECTOR_BASE,  timerisr,  timerOn,  timerOff,  timerIsOn};/*-------------------------------------------------------------------------+|         Function: Timer_exit|      Description: Timer cleanup routine at RTEMS exit. NOTE: This routine is|                   not really necessary, since there will be a reset at exit.| Global Variables: None.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/voidi386_timer_exit(void){  i386_delete_idt_entry (&timer_raw_irq_data);} /* Timer_exit *//*-------------------------------------------------------------------------+|         Function: Timer_initialize|      Description: Timer initialization routine.| Global Variables: Ttimer_val.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/voidi386_timer_initialize(void){  static rtems_boolean First = TRUE;  if (First)  {    First = FALSE;    atexit(Timer_exit); /* Try not to hose the system at exit. */    if (!i386_set_idt_entry (&timer_raw_irq_data)) {      printk("raw handler connexion failed\n");      rtems_fatal_error_occurred(1);    }  }  /* wait for ISR to be called at least once */  Ttimer_val = 0;  while (Ttimer_val == 0)    continue;  Ttimer_val = 0;} /* Timer_initialize *//*-------------------------------------------------------------------------+|         Function: Read_timer|      Description: Read hardware timer value.| Global Variables: Ttimer_val, Timer_driver_Find_average_overhead.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/uint32_ti386_read_timer(void){  register uint32_t         total, clicks;  register uint8_t          lsb, msb;  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_LATCH);  inport_byte(TIMER_CNTR0, lsb);  inport_byte(TIMER_CNTR0, msb);  clicks = (msb << 8) | lsb;  total  = (Ttimer_val * US_PER_ISR) + (US_PER_ISR - TICK_TO_US(clicks));  if (Timer_driver_Find_average_overhead)    return total;  else if (total < LEAST_VALID)    return 0; /* below timer resolution */  else    return (total - AVG_OVERHEAD);}/* * General timer functions using either TSC-based implementation * or interrupt-based implementation */voidTimer_initialize(void){    static rtems_boolean First = TRUE;    if (First) {        if (x86_capability & (1 << 4) ) {#if defined(DEBUG)            printk("TSC: timer initialization\n");#endif            Timer_initialize_function = &tsc_timer_initialize;            Read_timer_function = &tsc_read_timer;            Timer_exit_function = &tsc_timer_exit;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -