中断处理流程记录

阅读: 评论:0

中断处理流程记录

中断处理流程记录

函数顺序
request_irq – request_threaded_irq – __setup_irq

 ret = request_irq(RX_IRQ(port),w55fa93_serial_irq, 0,w55fa93_serial_portname(port), ourport);

各参数的意义 中断号 处理函数 标记 名称 可以是传递的参数可以是作为区分共享中断
request_threaded_irq 里面有对结构体struct irqaction *action;进行填充初始化。将中断处理程序赋值给这个结构体。
__setup_irq 继续将irq_desc结构体进行赋值,并将action放置在自己的irq_desc结构体中。在proc文件系统中创建相关目录。设置触发方式,并使能中断。


“arch/arm/mach-w55fa93/irq.c”文件中

void __init w55fa93_init_irq(void)
{int irqno;__raw_writel(0xFFFFFFFF, REG_AIC_MDCR);for (irqno = IRQ_WDT; irqno < NR_IRQS; irqno++) {set_irq_chip(irqno, &w55fa93_irq_chip);set_irq_handler(irqno, handle_level_irq);set_irq_flags(irqno, IRQF_VALID);}
}

屏蔽所有中断,然后统一接口赋值,chip handler flags给irq_desc结构体。

“arch/arm/mach-w55fa93/mach-w55fa93.c”

MACHINE_START(W55FA93, "W55FA93").phys_io        = W55FA93_PA_UART,.io_pg_offst    = (((u32)W55FA93_VA_UART) >> 18) & 0xfffc,
#ifdef CONFIG_INITRAMFS_ROOT_UID.boot_params    = 0x0,
#else.boot_params    = 0x100,
#endif.map_io         = mach_w55fa93_map_io,.init_irq       = w55fa93_init_irq,.init_machine   = w55fa93_init,.timer          = &w55fa93_timer,
MACHINE_END#define MACHINE_START(_type,_name)                      
static const struct machine_desc __mach_desc_##_type    __used                                                 __attribute__((__section__(".arch.info.init"))) = {    .nr             = MACH_TYPE_##_type,            .name           = _name,#define MACHINE_END                             
};

将w55fa93_init_irq赋值给machine_desc结构体

void __init setup_arch(char **cmdline_p)
{struct tag *tags = (struct tag *)&init_tags;struct machine_desc *mdesc;char *from = default_command_line;unwind_init();setup_processor();mdesc = setup_machine(machine_arch_type);machine_name = mdesc->name;if (mdesc->soft_reboot)reboot_setup("s");if (__atags_pointer)tags = phys_to_virt(__atags_pointer);else if (mdesc->boot_params)tags = phys_to_virt(mdesc->boot_params);/** If we have the old style parameters, convert them to* a tag list.*/if (tags->hdr.tag != ATAG_CORE)convert_to_tag_list(tags);if (tags->hdr.tag != ATAG_CORE)tags = (struct tag *)&init_tags;if (mdesc->fixup)mdesc->fixup(mdesc, tags, &from, &meminfo);if (tags->hdr.tag == ATAG_CORE) {if (_banks != 0)squash_mem_tags(tags);save_atags(tags);parse_tags(tags);}init_mm.start_code = (unsigned long) _text;d_code   = (unsigned long) _etext;d_data   = (unsigned long) _edata;init_mm.brk        = (unsigned long) _end;/* parse_early_param needs a boot_command_line */strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);*cmdline_p = cmd_line;parse_early_param();paging_init(mdesc);request_standard_resources(&meminfo, mdesc);#ifdef CONFIG_SMPsmp_init_cpus();
#endifcpu_init();tcm_init();/** Set up various architecture-specific pointers*/init_arch_irq = mdesc->init_irq;system_timer = mdesc->timer;init_machine = mdesc->init_machine;#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)conswitchp = &dummy_con;
#endif
#endifearly_trap_init();
}

这个函数中实现了赋值init_arch_irq = mdesc->init_irq;

void __init init_IRQ(void)
{int irq;for (irq = 0; irq < NR_IRQS; irq++)irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;init_arch_irq();
}

init_arch_irq()被init_IRQ函数调用,而init_IRQ的实现就是在start_kernel中。


当发生中断时
首先异常向量表,保存一条跳转指令,一般存放在0x00000000或者0xffff000地址,linux使用后者,中断发生后CPU进入异常模式,将跳转到相应的异常向量表处执行,异常向量表保存跳转指令,经过一段汇编,最后跳转到中断的入口asm_do_IRQ
asm_do_IRQ – generic_handle_irq – generic_handle_irq_desc – desc->handle_irq(irq, desc) – handle_IRQ_event – action->handler
最后到达此irq的desc结构体的handle_irq函数。即在w55fa93_init_irq中给desc结构体的赋值。
set_irq_handler(irqno, handle_level_irq);
handle_level_irq这个函数分析

void
handle_level_irq(unsigned int irq, struct irq_desc *desc)
{struct irqaction *action;irqreturn_t action_ret;raw_spin_lock(&desc->lock);mask_ack_irq(desc, irq);                     屏蔽并清中断if (unlikely(desc->status & IRQ_INPROGRESS))goto out_unlock;desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);kstat_incr_irqs_this_cpu(irq, desc);          中断统计计数  /** If its disabled or no action available* keep it masked and get out of here*/action = desc->action;                      取出action这个结构体if (unlikely(!action || (desc->status & IRQ_DISABLED)))goto out_unlock;desc->status |= IRQ_INPROGRESS;           标记中断状态raw_spin_unlock(&desc->lock);action_ret = handle_IRQ_event(irq, action);   处理中断if (!noirqdebug)note_interrupt(irq, desc, action_ret);raw_spin_lock(&desc->lock);desc->status &= ~IRQ_INPROGRESS;if (!(desc->status & (IRQ_DISABLED | IRQ_ONESHOT)))unmask_irq(desc, irq);
out_unlock:raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_level_irq);

本文发布于:2024-01-29 13:56:53,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170650781515763.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:流程
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23