从零开始操作系统-08:计时器

这一节主要主要是计时器。

所需要的文件在Github:https://github.com/yongkangluo/Ubuntu20.04OS/tree/main/Files/Lec7-ExternalInterrupt

计时器:

可编程间隔计时器:PIT(Programmalbe Interval Timer)8254

使用APIC自带的Timer:
更高精度并且能对CUP单独设置;

概述而言就是:
使用 两个Count来做计时:
FEE0 0380H :Initial Count;
FEE0 0390H :Current Count

if(ICR){
	do{
		CCR = ICR;
		while(CCR--);
		Interrput;
	} while(Timer Model)
}

计数器的行为设置:
在这里插入图片描述

手动测量频率
使用一个固定已知频率的时钟做参考:
Lapic 计时器发生中断时,经过了多少的间隔:
F t i m e r = F C P U / k I C R / F t i m e r = t / F R T C F_{timer} = F_{CPU} / k\\ ICR / F_{timer} = t / F_{RTC} Ftimer=FCPU/kICR/Ftimer=t/FRTC
使用CPU来计算是不准确的,可能存在超频的可能。所以需要用手动测量。使用主板上的COMS来作为时间参考。

步骤如下:

  1. 安装RTC和Lapic Timer 的临时中断服务例程
  2. 配置RTC的频率(1024赫兹)
  3. 打开中断
  4. 写入ICR
  5. PIE置位
  6. 阻塞
  7. 党LAPIC Timer触发之后,计算频率并关闭RTC
  8. 清楚临时例程
Code
void
timer_init(uint32_t frequency)
{
    timer_init_context();
    cpu_disable_interrupt();
    // 配置LAPIC中的中断寄存器; One shot, 中断号是202
    apic_write_reg(APIC_TIMER_LVT,
                   LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_ONESHOT));
    // Time Driver设置为64
    apic_write_reg(APIC_TIMER_DCR, APIC_TIMER_DIV64);
    timer_ctx->base_frequency = 0;
    rtc_counter = 0;
    apic_timer_done = 0;
    // 安装APIC对一个的中断程序
    intr_subscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer);
    intr_subscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick);
    // 开启RTC计时器
    rtc_enable_timer();    
    // 在APIC中写一个很大的常数                              
    apic_write_reg(APIC_TIMER_ICR, APIC_CALIBRATION_CONST); 
    // 开启中断
    cpu_enable_interrupt();
    wait_until(apic_timer_done);
    assert_msg(timer_ctx->base_frequency, "Fail to initialize timer (NOFREQ)");
    kprintf(KINFO "Base frequency: %u Hz\n", timer_ctx->base_frequency);
    timer_ctx->running_frequency = frequency;
    timer_ctx->tick_interval = timer_ctx->base_frequency / frequency;
    
    intr_unsubscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer);
    intr_unsubscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick);
    apic_write_reg(APIC_TIMER_LVT,
                   LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_PERIODIC));
    intr_subscribe(APIC_TIMER_IV, timer_update);
    apic_write_reg(APIC_TIMER_ICR, timer_ctx->tick_interval);
}

在这里插入图片描述

方法主要跟着B站Up主做的,B站视频链接在:https://www.bilibili.com/video/BV1jL4y1s7X6/?spm_id_from=333.788&vd_source=72ce864f895f9fbf22b81450817f2875

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值