📄 timer.c
字号:
} 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 + -