驱动调试_Panic

发布时间 2023-09-06 15:03:02作者: charlie12345

原理:是系统时钟中断永不停息,可在系统时钟中断中添加打印信息。

系统定时器中断中调试(不可打印寄存器reg)

cat /proc/interrupts									//可查看系统定时器中断

/*
 * IRQ handler for the timer
 */
static irqreturn_t										//linux-2.6.22.6\arch\arm\plat-s3c24xx\time.c
s3c2410_timer_interrupt(int irq, void *dev_id)			//系统定时器中断,视频介绍是5ms 触发一次
{
	////////////////////////////////////////////////
	/* 如果10秒钟之内都是同一个进程在运行,就打印*/
	static pid_t pre_pid;
	static inti cnt=0;
	if (pre_pid == current->pid){
		cnt ++
	}else{
		cnt = 0;
		pre_pid = current->pid;
	}
	if (cnt == 10*HZ){
		cnt = 0;
		printk("s3c2410_timer_interrupt : pid = %d, task_name = %s\n", current->pid, current->comm);
	}
	////////////////////////////////////////////////


	write_seqlock(&xtime_lock);
	timer_tick();
	write_sequnlock(&xtime_lock);
	return IRQ_HANDLED;
}
static struct irqaction s3c2410_timer_irq = {
	.name		= "S3C2410 Timer Tick",
	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
	.handler	= s3c2410_timer_interrupt,
};

中断处理函数中调试,与上面有区别,可以打印出pc值

asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)				//中断处理函数,与上面有区别,可以打印出pc值   	linux-2.6.22.6\arch\arm\kernel\irq.c
{
	struct pt_regs *old_regs = set_irq_regs(regs);
	struct irq_desc *desc = irq_desc + irq;

	/*
	 * Some hardware gives randomly wrong interrupts.  Rather
	 * than crashing, do something sensible.
	 */
	if (irq >= NR_IRQS)
		desc = &bad_irq_desc;

	////////////////////////////////////////////////
	if(irq == 30)		//即等于系统定时器中断
	{
		/* 如果10秒钟之内都是同一个进程在运行,就打印*/
		static pid_t pre_pid;
		static inti cnt=0;
		if (pre_pid == current->pid){
			cnt ++
		}else{
			cnt = 0;
			pre_pid = current->pid;
		}
		if (cnt == 10*HZ){
			cnt = 0;
			printk("asm_do_IRQ : pid = %d, task_name = %s\n", current->pid, current->comm);
			printk("pc = %08x\n", regs->ARM_pc);											//打印出PC,确定函数
		}
	}
	////////////////////////////////////////////////

	irq_enter();

	desc_handle_irq(irq, desc);

	/* AT91 specific workaround */
	irq_finish(irq);

	irq_exit();
	set_irq_regs(old_regs);
}



./firstdrvtest on 
	asm_do_IRQ => s3c2410_timer_interrupt : pid = 752, task name = firstdrvtest
	pc = bf000084
	asm_do_IRQ => s3c2410_timer_interrupt : pid = 752, task name = firstdrvtest
	pc = bf000084   											// 对于中断, pc-4才是发生中断瞬间的地址

参考:韦东山Linux教程