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

📄 ckinit.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/*-------------------------------------------------------------------------+| ckinit.c v1.1 - PC386 BSP - 1997/08/07+--------------------------------------------------------------------------+| This file contains the PC386 clock package.+--------------------------------------------------------------------------+| (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 based on:|   ckinit.c,v 1.4 1995/12/19 20:07:13 joel Exp - go32 BSP| 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: ckinit.c,v 1.7.8.1 2003/09/04 18:44:03 joel Exp $+--------------------------------------------------------------------------*/#include <stdlib.h>#include <bsp.h>#include <irq.h>#include <rtems/libio.h>/*-------------------------------------------------------------------------+| Macros+--------------------------------------------------------------------------*/#if 0/* This was dropped in the last revision.  Its a nice thing to know. */#define TICKS_PER_SECOND() \          (1000000 / (Clock_isrs_per_tick * microseconds_per_isr))#endif /* 0 *//*-------------------------------------------------------------------------+| Global Variables+--------------------------------------------------------------------------*/volatile rtems_unsigned32 Clock_driver_ticks;   /* Tick (interrupt) counter. */         rtems_unsigned32 Clock_isrs_per_tick;  /* ISRs per tick.            */         rtems_unsigned32 Clock_isrs;           /* ISRs until next tick.     *//* The following variables are set by the clock driver during its init */rtems_device_major_number rtems_clock_major = ~0;rtems_device_minor_number rtems_clock_minor;/*-------------------------------------------------------------------------+|         Function: clockIsr|      Description: Interrupt Service Routine for clock (0h) interruption.| Global Variables: Clock_driver_ticks, Clock_isrs.|        Arguments: vector - standard RTEMS argument - see documentation.|          Returns: standard return value - see documentation. +--------------------------------------------------------------------------*/static void clockIsr(){  /*-------------------------------------------------------------------------+  | PLEASE NOTE: The following is directly transcribed from the go32 BSP for  |              those who wish to use it with PENTIUM based machine. It needs  |              to be correctly integrated with the rest of the code!!!  +--------------------------------------------------------------------------*/#if 0 && defined(pentium) /* more accurate clock for PENTIUMs (not supported) */  {    extern long long Last_RDTSC;    __asm __volatile(".byte 0x0F, 0x31" : "=A" (Last_RDTSC));  }#endif /* 0 && pentium */  Clock_driver_ticks++;  if ( Clock_isrs == 1 )  {    rtems_clock_tick();    Clock_isrs = Clock_isrs_per_tick;  }  else    Clock_isrs--;} /* clockIsr *//*-------------------------------------------------------------------------+|         Function: Clock_exit|      Description: Clock 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. +--------------------------------------------------------------------------*/void clockOff(const rtems_irq_connect_data* unused){  /* reset timer mode to standard (BIOS) value */  outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);  outport_byte(TIMER_CNTR0, 0);  outport_byte(TIMER_CNTR0, 0);} /* Clock_exit *//*-------------------------------------------------------------------------+|         Function: Install_clock|      Description: Initialize and install clock interrupt handler.| Global Variables: None.|        Arguments: None.|          Returns: Nothing. +--------------------------------------------------------------------------*/static void clockOn(const rtems_irq_connect_data* unused){  rtems_unsigned32  microseconds_per_isr;#if 0  /* Initialize clock from on-board real time clock.  This breaks the  */  /* test code which assumes which assumes the application will do it. */  {    rtems_time_of_day now;    /* External Prototypes */    extern void init_rtc(void);                /* defined in 'rtc.c' */    extern long rtc_read(rtems_time_of_day *); /* defined in 'rtc.c' */    init_rtc();    if (rtc_read(&now) >= 0)      clock_set(&now);  }#endif /* 0 */  /* Start by assuming hardware counter is large enough, then  scale it until     it actually fits. */  Clock_driver_ticks  = 0;  Clock_isrs_per_tick = 1;  if (BSP_Configuration.microseconds_per_tick == 0)    microseconds_per_isr = 10000; /* default 10 ms */  else    microseconds_per_isr = BSP_Configuration.microseconds_per_tick;  while (US_TO_TICK(microseconds_per_isr) > 65535)  {    Clock_isrs_per_tick  *= 10;    microseconds_per_isr /= 10;  }  Clock_isrs = Clock_isrs_per_tick; /* Initialize Clock_isrs */  {    /* 105/88 approximates TIMER_TICK * 1e-6 */    rtems_unsigned32 count = US_TO_TICK(microseconds_per_isr);    outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN);    outport_byte(TIMER_CNTR0, count >> 0 & 0xff);    outport_byte(TIMER_CNTR0, count >> 8 & 0xff);  } } int clockIsOn(const rtems_irq_connect_data* unused){  return ((i8259s_cache & 0x1) == 0);}static rtems_irq_connect_data clockIrqData = {BSP_PERIODIC_TIMER,					      clockIsr,					      clockOn,					      clockOff,					      clockIsOn};					      					      /*-------------------------------------------------------------------------+| Clock device driver INITIALIZE entry point.+--------------------------------------------------------------------------+| Initilizes the clock driver.+--------------------------------------------------------------------------*/rtems_device_driverClock_initialize(rtems_device_major_number major,                 rtems_device_minor_number minor,                 void                      *pargp){  if (!BSP_install_rtems_irq_handler (&clockIrqData)) {    printk("Unable to initialize system clock\n");    rtems_fatal_error_occurred(1);  }  /* make major/minor avail to others such as shared memory driver */   rtems_clock_major = major;  rtems_clock_minor = minor;   return RTEMS_SUCCESSFUL;} /* Clock_initialize */					      /*-------------------------------------------------------------------------+| Console device driver CONTROL entry point+--------------------------------------------------------------------------*/rtems_device_driverClock_control(rtems_device_major_number major,              rtems_device_minor_number minor,	      void                      *pargp){  if (pargp != NULL)  {    rtems_libio_ioctl_args_t *args = pargp;            /*-------------------------------------------------------------------------+    | This is hokey, but until we get a defined interface to do this, it will    | just be this simple...    +-------------------------------------------------------------------------*/     if      (args->command == rtems_build_name('I', 'S', 'R', ' '))      clockIsr();    else if (args->command == rtems_build_name('N', 'E', 'W', ' '))    {      if (!BSP_install_rtems_irq_handler (&clockIrqData)) {	printk("Error installing clock interrupt handler!\n");	rtems_fatal_error_occurred(1);      }    }  }  return RTEMS_SUCCESSFUL;} /* Clock_control */void Clock_exit(){  BSP_remove_rtems_irq_handler (&clockIrqData);}/*-------------------------------------------------------------------------+| PLEASE NOTE: The following is directly transcribed from the go32 BSP for|              those who wish to use it with PENTIUM based machine. It needs|              to be correctly integrated with the rest of the code!!!+--------------------------------------------------------------------------*/#if 0 && defined(pentium)/* This can be used to get extremely accurate timing on a pentium. *//* It isn't supported. [bryce]                                     */#define HZ 90.0volatile long long Last_RDTSC;#define RDTSC()\  ({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; })long long Kernel_Time_ns( void ){  extern rtems_unsigned32 _TOD_Ticks_per_second;  unsigned  isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second;  long long now;  int       flags;  disable_intr(flags);  now = 1e9 * Clock_driver_ticks / isrs_per_second +        (RDTSC() - Last_RDTSC) * (1000.0/HZ);  enable_intr(flags);  return now;} /* Kernel_Time_ns */#endif /* 0 && pentium */

⌨️ 快捷键说明

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