You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无限打印循环任务中为何无法触发PIT中断?

任务调度与PIT定时器异常问题

问题现象

  • 实现两个循环执行的任务:fn持续输出"a",fn2持续输出"b",通过schedule函数调度
  • 配置PIT定时器以20Hz频率触发中断,中断处理函数中调用schedule执行任务切换
  • 实际运行时,定时器仅触发一次,fn持续执行,无法切换到fn2

任务代码

int fn(void *arg)
{
  for(;;) {
    printf("a");
  }
  return 6;
}

int fn2(void *arg)
{
  for(;;) {
    printf("b");
  }
  return 6;
}

PIT定时器与调度关联代码

// 参考OSDev可编程间隔定时器文档
// PIT芯片振荡器频率约为1.193182 MHz
#define TIMER_INPUT_CLOCK_FREQUENCY    1193180
#define TIMER_CHANNEL_0_DATA_PORT    0x40
#define TIMER_CHANNEL_1_DATA_PORT    0x41
#define TIMER_CHANNEL_2_DATA_PORT    0x42
#define TIMER_COMMAND_PORT    0x43

// 系统启动后的时钟滴答计数
uint32 g_ticks = 0;
// 定时器频率(赫兹)
uint16 g_freq_hz = 0;

int task_switch_needed = 0;

// 设置定时器频率
void timer_set_frequency(uint16 f) {
    g_freq_hz = f;
    uint16 divisor = TIMER_INPUT_CLOCK_FREQUENCY / f;
    // 设置模式3:方波模式
    outportb(TIMER_COMMAND_PORT, 0b00110110);
    // 写入分频值低字节
    outportb(TIMER_CHANNEL_0_DATA_PORT, divisor & 0xFF);
    // 写入分频值高字节
    outportb(TIMER_CHANNEL_0_DATA_PORT, (divisor >> 8) & 0xFF);
}

void timer_handler(REGISTERS* r) {
    g_ticks++;
    printf("timer triggered at frequency %d\n", g_ticks);
    schedule();
}

void timer_init() {
    timer_set_frequency(20);
    isr_register_interrupt_handler(IRQ_BASE, timer_handler);
}

void sleep(int sec) {
    uint32 end = g_ticks + sec * g_freq_hz;
    while (g_ticks < end);
}

任务创建代码

uint32 *stack = kmalloc (0x400) + 0x3F0;

task_t *t = create_task(&fn, (void*)0x567, stack);

uint32 *stack2 = kmalloc (0x400) + 0x3F0;

task_t *t2 = create_task(&fn2, (void*)0x567, stack2);

内容的提问来源于stack exchange,提问作者xingharvey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:33