zoukankan      html  css  js  c++  java
  • 驱动调试(六)利用中断打印


    title: 16-驱动调试(六)利用中断打印
    date: 2019/1/15 23:35:14
    toc: true

    原理

    • 这一章节也没啥新知识,原理就是利用系统时钟的中断,去打印一些信息.

    • 在进入中断之前,会保存现场,包括LR,可以打印这个LR就能看到,定时器中断是普通中断,保存现场的时候已经将返回地址+4到LR寄存器,这个是硬件决定的,所以我们查找这个返回地址的时候减去4.

    保护现场

    • 硬件自动保存

      • 保存当前的cpsr到中断下的scpsr
      • 保存返回地址到LR寄存器,(某种异常模式的LR等于被中断的下一条指令的地址)它有可能是PC + 4有可能是PC + 8,到底是那种取决于不同的情况
    • 软件需要做的stmdb sp!, {r0-r12, lr}

      • 保存R0~R12寄存器

      • 保存LR寄存器,注意这个保存之后是退出中断的返回地址,因为ARM架构的原因,不同的中断异常有不同的返回地址,所以需要对这个LR先进行一些运算再保存.偏移地址如下:举个例子比如UDEF异常,只需要直接复制,而FIQ则需要保存LR+4

        BL 		MOV PC, R14
        SWI 	MOVS PC, R14_svc 
        UDEF 	MOVS PC, R14_und 
        FIQ 	SUBS PC, R14_fiq, #4 
        IRQ 	SUBS PC, R14_irq, #4 
        PABT 	SUBS PC, R14_abt, #4 
        DABT 	SUBS PC, R14_abt, #8 
        

    死循环判断流程

    记录pid,如果pid一直是同一个并且大于10s,打印这个pid和LR

    asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
    {
    	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;
        
        
    #ifdef 1
        static pid_t pre_pid;                    //进程号  
        static int cnt=0;                          //计数值
        if(irq==30)          //判断irq中断号,是否等于系统时钟
        {  
            if(pre_pid==current->pid)
            {   
                cnt++;
            }
            else
            {
                cnt=0;   
                pre_pid=current->pid;
            }
            if(cnt==10*HZ)   //超时10s
            {
            cnt=0;
            printk("s3c2410_timer_interrupt : pid = %d, task_name = %s
    ",current->pid,current->comm);
            printk("pc = %08x
    ",regs->ARM_pc);
            }
    }     
    #endif
        
        
    	irq_enter();
    
    	desc_handle_irq(irq, desc);
    
    	/* AT91 specific workaround */
    	irq_finish(irq);
    
    	irq_exit();
    	set_irq_regs(old_regs);
    }
    

    代码简单解释

    • 中断号是30,在 includeasm-armarch-s3c2410Irqs.h,或者使用cat /proc/interrupt查看

    • current->pid:当前进程的PID号

    • current->com表示当前进程的name

    • HZ也是一个宏,代表每S的频率,比如每隔10ms加1,那么HZ就等于100

    • 参数的regs表示原有的寄存器,用他来查看进来之前普通函数的lr

    参考

    https://www.cnblogs.com/lifexy/p/8024415.html

  • 相关阅读:
    oracle12c中新能优化新特性之热度图和自动数据优化
    Oracle10g以上sysaux表空间的维护和清理
    mysql 及 posgresql之优劣势大比拼
    Oracle外部表的管理和应用
    Oracle ASM 相关的 视图(V$) 和 数据字典(X$)
    Oracle12c功能增强新特性之维护&升级&恢复&数据泵等
    Oracle12c功能增强 新特性之管理功能的增强
    Oracle12c 中RAC功能增强新特性之ASM&Grid
    oracle12c新特点之可插拔数据库(Pluggable Database,PDB)
    SRM-697-DIV2
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/10272077.html
Copyright © 2011-2022 走看看