From 9e5d3dacd668c54cccc643c595d9f63409057c24 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Tue, 2 Jul 2024 14:46:50 +0800 Subject: [PATCH] irq: dynaminc create g_irqmap reason: dynaminc create g_irqmap to reduce the use of data segments CONFIG_ARCH_NUSER_INTERRUPTS should be one more than the number of IRQs actually used Signed-off-by: hujun5 --- arch/Kconfig | 7 +++++++ sched/irq/irq.h | 9 +++++++-- sched/irq/irq_attach.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index a9a7c6050ecce..1ad53bf34978b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1158,6 +1158,13 @@ config ARCH_MINIMAL_VECTORTABLE IRQMAPPED_MAX, then hardware interrupt vector 42 is not used and if it occurs will result in an unexpected interrupt crash. +config ARCH_MINIMAL_VECTORTABLE_DYNAMIC + bool "Dynaminc Minimal RAM usage for vector table" + default n + depends on ARCH_MINIMAL_VECTORTABLE + ---help--- + Use a minimum amount of RAM for the vector table. + config ARCH_NUSER_INTERRUPTS int "Number of interrupts" default 0 diff --git a/sched/irq/irq.h b/sched/irq/irq.h index 1bf1146ac98cc..03bcb725d5b93 100644 --- a/sched/irq/irq.h +++ b/sched/irq/irq.h @@ -44,7 +44,9 @@ # error CONFIG_ARCH_NUSER_INTERRUPTS is not defined #endif -#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE +#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) +# define IRQ_TO_NDX(irq) (g_irqmap[irq] ? g_irqmap[irq] : irq_to_ndx(irq)) +#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) # define IRQ_TO_NDX(irq) \ (g_irqmap[(irq)] < CONFIG_ARCH_NUSER_INTERRUPTS ? g_irqmap[(irq)] : -EINVAL) #else @@ -94,7 +96,6 @@ extern struct irq_info_s g_irqvector[CONFIG_ARCH_NUSER_INTERRUPTS]; extern struct irq_info_s g_irqvector[NR_IRQS]; #endif -#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE /* This is the interrupt vector mapping table. This must be provided by * architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define * in the configuration. @@ -104,6 +105,10 @@ extern struct irq_info_s g_irqvector[NR_IRQS]; * declaration is here for the time being. */ +#if defined(CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC) +extern irq_mapped_t g_irqmap[NR_IRQS]; +int irq_to_ndx(int irq); +#elif defined(CONFIG_ARCH_MINIMAL_VECTORTABLE) extern const irq_mapped_t g_irqmap[NR_IRQS]; #endif diff --git a/sched/irq/irq_attach.c b/sched/irq/irq_attach.c index 4ecbb14dd60d3..ba561209104b5 100644 --- a/sched/irq/irq_attach.c +++ b/sched/irq/irq_attach.c @@ -30,10 +30,52 @@ #include "irq/irq.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC +static int g_irqmap_count = 1; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC + +/* This is the interrupt vector mapping table. This must be provided by + * architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define + * in the configuration. + * + * REVISIT: This should be declared in include/nuttx/irq.h. The declaration + * at that location, however, introduces a circular include dependency so the + * declaration is here for the time being. + */ + +irq_mapped_t g_irqmap[NR_IRQS]; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ +#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE_DYNAMIC +int irq_to_ndx(int irq) +{ + DEBUGASSERT(g_irqmap_count < CONFIG_ARCH_NUSER_INTERRUPTS); + + irqstate_t flags = spin_lock_irqsave(NULL); + if (g_irqmap[irq] == 0) + { + g_irqmap[irq] = g_irqmap_count++; + } + + spin_unlock_irqrestore(NULL, flags); + return g_irqmap[irq]; +} +#endif + /**************************************************************************** * Name: irq_attach *