NuttX 中断管理
来源:互联网 发布:苹果手机导出照片到mac 编辑:程序博客网 时间:2024/06/05 23:39
(嵌入式 实时操作系统 rtos nuttx 7.18 stm32 源代码分析)
nuttx中断处理流程:
g_irqvector[NR_IRQS]
中断处理程序列表,一个中断号对应一项,当中断发生后,irq_dispatch()根据中断号从列表中读取对应处理程序的地址。
(code1):
nuttx/sched/irq/irq_initialize.c
nuttx/arch/arm/src/chip/stm32_irq.c
nuttx/sched/irq/irq_attach.c
nuttx/sched/irq/irq_dispatch.c
NuttX 中断管理
转载请注明出处: http://blog.csdn.net/zhumaill/article/details/70141440nuttx中断处理流程:
硬件查表 向量号 地址 handlers |--> 0 8000000 IDLE_STACK---------->| |--> 1 8000004 __start | |--> 2 8000008 stm32_nmi----------->| |--> 3 800000c stm32_hardfault----->| 硬件产生中断-|--> 4 8000010 stm32_mpu----------->| |--> 5 8000014 stm32_busfault------>| |--> 6 8000018 stm32_usagefault---->| |--> 7 800001c stm32_reserved | |--> 8 8000020 stm32_reserved | |--> 9 8000024 stm32_reserved | |--> 10 8000028 stm32_reserved | |--> 11 800002c stm32_svcall-------->| |--> 12 8000030 stm32_dbgmonitor---->| |--> 13 8000034 stm32_reserved------>| |--> 14 8000038 stm32_pendsv-------->| |--> 15 800003c stm32_systick------->| |--> 16 8000040 stm32_wwdg---------->| 中断号0 |--> ... ... ......-------------->| ...... |--> 83 800014c stm32_otgfs--------->| 中断号67 | | |<------------------------------------------------------| | | |-->irq_unexpected_isr() |-->exception_common()-->up_doirq()-->irq_dispatch()(code4)-->| |-->g_irqvector[irq]()虽然一个向量号对应一个handlers,但功能是一样的,将向量号写入R0,然后跳转到exception_common()。nuttx没有使用cortex-m3的硬件跳转功能,而是由irq_dispatch()实现软件跳转。
g_irqvector[NR_IRQS]
中断处理程序列表,一个中断号对应一项,当中断发生后,irq_dispatch()根据中断号从列表中读取对应处理程序的地址。
(code1):
nuttx/sched/irq/irq_initialize.c
/* 系统初始化时调用 */void irq_initialize(void){ int i; /* 将所有中断向量都指向非正常中断处理程序 */ for (i = 0; i < NR_IRQS; i++) { g_irqvector[i] = irq_unexpected_isr; }}(code2):
nuttx/arch/arm/src/chip/stm32_irq.c
/* 设置中断优先级,关联硬件异常处理函数,系统初始化时调用 */void up_irqinitialize(void){ uint32_t regaddr; int num_priority_registers; int i; /* 禁用所有中断 */ for (i = 0; i < NR_IRQS - STM32_IRQ_FIRST; i += 32) { putreg32(0xffffffff, NVIC_IRQ_CLEAR(i)); } /* 在中断栈填充固定数据(0xdeadbeef)以方便调试 */#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 { size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), intstack_size); }#endif /* 向量表的标准位置起始于 FLASH地址0x0800:0000 * 如果我们使用 STMicro DFU bootloader, * 向量表将偏移到FLASH的不同位置, * 我们需要设置 NVIC向量到改变后位置 */#if defined(__ICCARM__) putreg32((uint32_t)__vector_table, NVIC_VECTAB);#else putreg32((uint32_t)_vectors, NVIC_VECTAB);#endif#ifdef CONFIG_ARCH_RAMVECTORS /* 如果定义了CONFIG_ARCH_RAMVECTORS, * 我们正在使用基于RAM的向量表,需要特别的初始化 */ up_ramvec_initialize();#endif /* 设置所有的异常和中断到默认的优先级 */ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY); putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY); putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY); /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt * lines that the NVIC supports: * * 0 -> 32 interrupt lines, 8 priority registers * 1 -> 64 " " " ", 16 priority registers * 2 -> 96 " " " ", 32 priority registers * ... */ num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8; /* Now set all of the interrupt lines to the default priority */ regaddr = NVIC_IRQ0_3_PRIORITY; while (num_priority_registers--) { putreg32(DEFPRIORITY32, regaddr); regaddr += 4; } /* currents_regs is non-NULL only while processing an interrupt */ CURRENT_REGS = NULL; /* Attach the SVCall and Hard Fault exception handlers. The SVCall * exception is used for performing context switches; The Hard Fault * must also be caught because a SVCall may show up as a Hard Fault * under certain conditions. */ irq_attach(STM32_IRQ_SVCALL, up_svcall); irq_attach(STM32_IRQ_HARDFAULT, up_hardfault); /* Set the priority of the SVCall interrupt */#ifdef CONFIG_ARCH_IRQPRIO /* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */#endif#ifdef CONFIG_ARMV7M_USEBASEPRI stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);#endif /* If the MPU is enabled, then attach and enable the Memory Management * Fault handler. */#ifdef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault); up_enable_irq(STM32_IRQ_MEMFAULT);#endif /* 关联所有其它的处理器异常(除了复位和系统滴答) */#ifdef CONFIG_DEBUG_FEATURES irq_attach(STM32_IRQ_NMI, stm32_nmi);#ifndef CONFIG_ARM_MPU irq_attach(STM32_IRQ_MEMFAULT, up_memfault);#endif irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault); irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault); irq_attach(STM32_IRQ_PENDSV, stm32_pendsv); irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor); irq_attach(STM32_IRQ_RESERVED, stm32_reserved);#endif stm32_dumpnvic("initial", NR_IRQS);#ifndef CONFIG_SUPPRESS_INTERRUPTS /* 最后,使能中断 */ up_irq_enable();#endif}(code3):
nuttx/sched/irq/irq_attach.c
/* 配置IRQ子系统,以便使用IRQ 号 'irq' 分派 'isr',外设初始化时调用 */int irq_attach(int irq, xcpt_t isr){#if NR_IRQS > 0 int ret = ERROR; if ((unsigned)irq < NR_IRQS) { irqstate_t flags; /* 如果 ISR 是 NULL, ISR 将不被关联. * 这种情况下,禁用 ISR ,中断将指向非正常中断处理程序 */ flags = enter_critical_section(); if (isr == NULL) { /* Disable the interrupt if we can before detaching it. We might * not be able to do this if: (1) the device does not have a * centralized interrupt controller (so up_disable_irq() is not * supported). Or (2) if the device has different number for vector * numbers and IRQ numbers (in that case, we don't know the correct * IRQ number to use to disable the interrupt). In those cases, the * code will just need to be careful that it disables all interrupt * sources before detaching from the interrupt vector. */#if !defined(CONFIG_ARCH_NOINTC) && !defined(CONFIG_ARCH_VECNOTIRQ) up_disable_irq(irq);#endif /* Detaching the ISR really means re-attaching it to the * unexpected exception handler. */ isr = irq_unexpected_isr; } /* 保存新的 ISR 到表. */ g_irqvector[irq] = isr; leave_critical_section(flags); ret = OK; } return ret;#else return OK;#endif}(code4):
nuttx/sched/irq/irq_dispatch.c
/* 此函数必须从架构特定的逻辑调用,以分派一个中断到适当的、已注册的处理逻辑, 中断发生时调用 */void irq_dispatch(int irq, FAR void *context){ xcpt_t vector; /* Perform some sanity checks */#if NR_IRQS > 0 if ((unsigned)irq >= NR_IRQS || g_irqvector[irq] == NULL) { vector = irq_unexpected_isr; } else { vector = g_irqvector[irq]; }#else vector = irq_unexpected_isr;#endif /* 分派到中断处理程序 */ vector(irq, context);}
0 0
- NuttX 中断管理
- NuttX 任务管理
- NuttX
- 中断管理之下半部软中断
- 2440之中断管理
- Windows CE 中断管理
- linuxBSPmini2440中断管理
- Rtems--c_user--中断管理
- ARM9 中断管理
- FOS中断管理
- CAN的中断管理
- 5.中断管理
- 3.uCOSIII中断管理
- STM32中断管理
- NVIC中断优先级管理
- 中断和异常管理
- NVIC中断优先级管理
- 070中断管理
- Redis使用认证密码登录
- 垃圾收集器和杂七杂八
- JavaScript基础实战
- ajax is not defined异常解决
- python内置方法之完整版
- NuttX 中断管理
- 内存与对于返回局部指针变量的思考
- Listener使用案例
- javascript内置对象(四)
- 脏读
- 基于vue-cli快速构建
- java中线程有多少种状态
- Android webView自适应屏幕
- jquery 中append追加不能写if等逻辑语句及table列合并问题