1분간 loop를 돌며 돌때마다 20ms씩 nanosleep를 주어 카운트를 세어 보았는데..
      글쓴이: lee3390 / 작성시간: 화, 2007/01/30 - 3:02오후    
  
  1분간 loop를 돌며 돌때마다 20ms씩 nanosleep를 주어 카운트를 세어 보았는데..
3000번을 돌아가 정상일텐데
실제로는 2500회 정도 뿐이 돌지를 않습니다.
레드헷 엔터프라이즈 4 update 4에
제온 2.8G 램 1기가인 IBM서버 장비인데.. 왜이렇게 오차가 심하나요?
오차를 줄일 수 있는 방법은 무엇이 있을가요?
    for( ; endTime > curTime ; ) {
        count++;
        if ( nanosleep(&sleepTime, NULL) < 0 ) {
            printf("%s\n",strerror(errno));
        }
        time(&curTime);
    }Forums: 


RTOS 가
RTOS 가 아니거든요.
/dev/rtc 를 1024Hz 로 설정하시고 rtc periodic interrupt 를 이용하시면 오차는 확실히 줄어듭니다. 1024Hz 외에 다른 주파수로도 설정이 가능하긴 한데, 얼마 이상부턴 root 권한으로만 변경할 수 있습니다.
여러가지로 실험을 해봤는데 1024Hz 가 가장 오차가 적었습니다. 10ms 정도 해상도에서는요.
periodic_freq : 1024 << 이렇게 기본으로 되어있습니다.
흠... nanosleep일 경우에 2500회 정도 루프를 도는데
select로 sleep를 걸 경우 2800회 정도 나오는군요..
select가 오차가 많이 적네요.. 휴...
RTC periodic interrupt
RTC periodic interrupt 사용은 그냥 저절로 되는게 아닙니다.
기본개념은..
ioctl(rtc_fp, RTC_PIE_ON);
으로 RTC_PI 를 활성화시키고,
read(rtc_fp, &tmp, sizeof(tmp);
으로 대기하면 1초에 1024번에 가깝게 깨어납니다.
누적오차를 줄이기 위한 트릭은 별도로 구현해야지요.
예전에 만든... pxa27x 의 OS timer 를 시뮬레이션하기 위한 코드 중의 일부입니다.
static void OSCR_proc(void *arg) { timer_ctx_t *ctx = (timer_ctx_t*)arg; unsigned long tmp; // printf("OSCR thread started\n"); while (read(ctx->rtc_fp, &tmp, sizeof(tmp)) >= 0) { ctx->OSCR++; if ((!ctx->in_interrupt) && (ctx->OSCR == ctx->OSMR)) { pthread_cond_signal(&tick_cond); } } if (!ctx->stop_all) perror(""); } static void tick_proc(void *arg) { timer_ctx_t *ctx = (timer_ctx_t *)arg; signed TEST_UNIT next_match; // printf("tick thread started\n"); while (!ctx->stop_all) { ctx->in_interrupt = 0; pthread_cond_wait(&tick_cond, &tick_mutex); ctx->in_interrupt = 1; do { next_match = (ctx->OSMR += LIBK_LATCH); jiffies++; check_timer_task(ctx); } while ((signed TEST_UNIT)(next_match - ctx->OSCR) <= 8); } }댓글 달기