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

📄 timer.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
        }        else {#if defined(DEBUG)            printk("ISR: timer initialization\n");#endif            Timer_initialize_function = &i386_timer_initialize;            Read_timer_function = &i386_read_timer;            Timer_exit_function = &i386_timer_exit;        }        First = FALSE;    }    (*Timer_initialize_function)();}uint32_tRead_timer(){    return (*Read_timer_function)();}voidTimer_exit(){    return (*Timer_exit_function)();}/*-------------------------------------------------------------------------+|         Function: Empty_function|      Description: Empty function used in time tests.| Global Variables: None.|        Arguments: None.|          Returns: Nothing.+--------------------------------------------------------------------------*/rtems_status_code Empty_function(void){  return RTEMS_SUCCESSFUL;} /* Empty function *//*-------------------------------------------------------------------------+|         Function: Set_find_average_overhead|      Description: Set internal Timer_driver_Find_average_overhead flag value.| Global Variables: Timer_driver_Find_average_overhead.|        Arguments: find_flag - new value of the flag.|          Returns: Nothing.+--------------------------------------------------------------------------*/voidSet_find_average_overhead(rtems_boolean find_flag){  Timer_driver_Find_average_overhead = find_flag;} /* Set_find_average_overhead */static unsigned short lastLoadedValue;/*-------------------------------------------------------------------------+| Description: Loads timer 0 with value passed as arguemnt.| Returns: Nothing. Loaded value must be a number of clock bits...+--------------------------------------------------------------------------*/void loadTimerValue( unsigned short loadedValue ){  lastLoadedValue = loadedValue;  outport_byte(TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_SQWAVE);  outport_byte(TIMER_CNTR0, loadedValue & 0xff);  outport_byte(TIMER_CNTR0, (loadedValue >> 8) & 0xff);}/*-------------------------------------------------------------------------+| Description: Reads the current value of the timer, and converts the|			   number of ticks to micro-seconds.| Returns: number of clock bits elapsed since last load.+--------------------------------------------------------------------------*/unsigned int readTimer0(){  unsigned short lsb, msb;  unsigned char  status;  unsigned int	 count;  outport_byte(TIMER_MODE, (TIMER_RD_BACK | (RB_COUNT_0 & ~(RB_NOT_STATUS | RB_NOT_COUNT))));  inport_byte(TIMER_CNTR0, status);  inport_byte(TIMER_CNTR0, lsb);  inport_byte(TIMER_CNTR0, msb);  count = ( msb << 8 ) | lsb ;  if (status & RB_OUTPUT )  	count += lastLoadedValue;  return (2*lastLoadedValue - count);}void Timer0Reset(){  loadTimerValue(0xffff);  readTimer0();}void fastLoop (unsigned int loopCount){  unsigned int i;  for( i=0; i < loopCount; i++ )outport_byte( SLOW_DOWN_IO, 0 );}void slowLoop (unsigned int loopCount){  unsigned int j;  for (j=0; j <100 ;  j++) {    fastLoop (loopCount);  }}/* * #define DEBUG_CALIBRATE */voidCalibrate_loop_1ms(void){  unsigned int offset, offsetTmp, emptyCall, emptyCallTmp, res, i, j;  unsigned int targetClockBits, currentClockBits;  unsigned int slowLoopGranularity, fastLoopGranularity;  rtems_interrupt_level  level;#ifdef DEBUG_CALIBRATE  printk( "Calibrate_loop_1ms is starting,  please wait ( but not too loooong. )\n" );#endif  targetClockBits = US_TO_TICK(1000);  rtems_interrupt_disable(level);  /*   * Fill up the cache to get a correct offset   */  Timer0Reset();  readTimer0();  /*   * Compute the minimal offset to apply due to read counter register.   */  offset = 0xffffffff;  for (i=0; i <1000; i++) {    Timer0Reset();    offsetTmp = readTimer0();    offset += offsetTmp;  }  offset = offset / 1000; /* compute average */  /*   * calibrate empty call   */  fastLoop (0);  emptyCall = 0;  j = 0;  for (i=0; i <10; i++) {    Timer0Reset();    fastLoop (0);    res =  readTimer0();    /* res may be inferior to offset on fast     * machine because we took an average for offset     */    if (res >  offset) {      ++j;      emptyCallTmp = res - offset;      emptyCall += emptyCallTmp;    }  }  if (j == 0) emptyCall = 0;  else emptyCall = emptyCall / j; /* compute average */  /*   * calibrate fast loop   */  Timer0Reset();  fastLoop (10000);  res = readTimer0() - offset;  if (res < emptyCall) {     printk("Problem #1 in offset computation in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");    while (1);  }  fastLoopGranularity = (res - emptyCall) / 10000;  /*   * calibrate slow loop   */  Timer0Reset();  slowLoop(10);  res = readTimer0();  if (res < offset + emptyCall) {     printk("Problem #2 in offset computation in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");    while (1);  }  slowLoopGranularity = (res - offset - emptyCall)/ 10;  if (slowLoopGranularity == 0) {    printk("Problem #3 in Calibrate_loop_1ms in file libbsp/i386/pc386/timer/timer.c\n");    while (1);  }  targetClockBits += offset;#ifdef DEBUG_CALIBRATE  printk("offset = %u, emptyCall = %u, targetClockBits = %u\n",	 offset, emptyCall, targetClockBits);  printk("slowLoopGranularity = %u fastLoopGranularity =  %u\n",	 slowLoopGranularity, fastLoopGranularity);#endif  slowLoop1ms = (targetClockBits - emptyCall) / slowLoopGranularity;  if (slowLoop1ms != 0) {    fastLoop1ms = targetClockBits % slowLoopGranularity;    if (fastLoop1ms > emptyCall) fastLoop1ms -= emptyCall;  }  else    fastLoop1ms = targetClockBits - emptyCall / fastLoopGranularity;  if (slowLoop1ms != 0) {    /*     * calibrate slow loop     */    while(1)      {	int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */	Timer0Reset();	slowLoop(slowLoop1ms);	currentClockBits = readTimer0();	if (currentClockBits > targetClockBits) {	  if ((currentClockBits - targetClockBits) < slowLoopGranularity) {	    /* decrement loop counter anyway to be sure slowLoop(slowLoop1ms) < targetClockBits */	    --slowLoop1ms;	    break;	  }	  else {	    --slowLoop1ms;	    if (slowLoop1ms == 0) break;	    if (previousSign == 0) previousSign = 2;	    if (previousSign == 1) break;	  }	}	else {	  if ((targetClockBits - currentClockBits) < slowLoopGranularity) {	    break;	  }	  else {	    ++slowLoop1ms;	    if (previousSign == 0) previousSign = 1;	    if (previousSign == 2) break;	  }	}      }  }  /*   * calibrate fast loop   */  if (fastLoopGranularity != 0 ) {    while(1) {      int previousSign = 0; /* 0 = unset, 1 = incrementing,  2 = decrementing */      Timer0Reset();      if (slowLoop1ms != 0) slowLoop(slowLoop1ms);      fastLoop(fastLoop1ms);      currentClockBits = readTimer0();      if (currentClockBits > targetClockBits) {	if ((currentClockBits - targetClockBits) < fastLoopGranularity)	  break;	else {	  --fastLoop1ms;	  if (previousSign == 0) previousSign = 2;	  if (previousSign == 1) break;	}      }      else {	if ((targetClockBits - currentClockBits) < fastLoopGranularity)	  break;	else {	  ++fastLoop1ms;	  if (previousSign == 0) previousSign = 1;	  if (previousSign == 2) break;	}      }    }  }#ifdef DEBUG_CALIBRATE  printk("slowLoop1ms = %u, fastLoop1ms = %u\n", slowLoop1ms, fastLoop1ms);#endif  rtems_interrupt_enable(level);}/*-------------------------------------------------------------------------+|         Function: Wait_X_1ms|      Description: loop which waits at least timeToWait ms| Global Variables: loop1ms|        Arguments: timeToWait|          Returns: Nothing.+--------------------------------------------------------------------------*/voidWait_X_ms( unsigned int timeToWait){  unsigned int j;  for (j=0; j<timeToWait ; j++) {    if (slowLoop1ms != 0) slowLoop(slowLoop1ms);    fastLoop(fastLoop1ms);  }}

⌨️ 快捷键说明

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