From 314ba53ca7082138720a173f76467a9450f1c371 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 26 Apr 2010 12:34:10 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1892 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/src/interrupts.dox | 31 ++++++-- os/kernel/include/chsys.h | 10 ++- os/kernel/templates/chcore.h | 9 +++ os/ports/GCC/ARM7/chcore.h | 120 ++++++++++++++++--------------- os/ports/GCC/ARMCMx/chcore_v6m.h | 11 ++- os/ports/GCC/ARMCMx/chcore_v7m.h | 11 ++- readme.txt | 5 +- 7 files changed, 130 insertions(+), 67 deletions(-) diff --git a/docs/src/interrupts.dox b/docs/src/interrupts.dox index 64f336f08..bceea96c4 100644 --- a/docs/src/interrupts.dox +++ b/docs/src/interrupts.dox @@ -21,8 +21,11 @@ * @page article_interrupts How to write interrupt handlers * Since version 1.1.0 ChibiOS/RT offers a cross-platform method for writing * interrupt handlers. Port-related and compiler-related details are - * encapsulated within standard system macros.
- * An interrupt handler assumes the following general form: + * encapsulated within standard system macros. + * + *

Writing Regular Interrupt handlers

+ * A Regular Interrupts handler (see @ref interrupt_classes) must be written + * using the following general form: * @code CH_IRQ_HANDLER(myIRQ) { CH_IRQ_PROLOGUE(); @@ -38,15 +41,29 @@ CH_IRQ_HANDLER(myIRQ) { CH_IRQ_EPILOGUE(); } * @endcode - * Note that only interrupt handlers that have to invoke system @ref I-Class - * APIs must be written in this form, handlers unrelated to the OS activity can - * omit the macros. - * Another note about the handler name "myIRQ", in some ports it must be a + * + *

Writing Fast Interrupt handlers

+ * In those architectures (@ref ARM7 and @ref ARMCMx) supporting Fast + * Interrupts (see @ref interrupt_classes) handlers must be written + * using the following general form: + * @code +CH_FAST_IRQ_HANDLER(myIRQ) { + + // Fast IRQ handling code, preemptable if the architecture supports it. + // The invocation of any API is forbidden here because fast interrupt + // handlers can preempt the kernel even within its critical zones in + // order to minimize latency. +} + * @endcode + * + *

Handlers naming

+ * A note about the handler name "myIRQ", in some ports it must be a * vector number rather than a function name, it could also be a name from * within a predefined set, see the notes about the various ports. + * *

Important Notes

* - There is an important application note about ARM7 interrupt handlers, * please read about it in the ARM7 port section: @ref ARM7_IH * . */ - + \ No newline at end of file diff --git a/os/kernel/include/chsys.h b/os/kernel/include/chsys.h index 5c773136f..5759d0cca 100644 --- a/os/kernel/include/chsys.h +++ b/os/kernel/include/chsys.h @@ -154,12 +154,20 @@ #define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE() /** - * @brief Standard IRQ handler declaration. + * @brief Standard normal IRQ handler declaration. * @note @p id can be a function name or a vector number depending on the * port implementation. */ #define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) +/** + * @brief Standard fast IRQ handler declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + * @note Not all architectures support fast interrupts. + */ +#define CH_FAST_IRQ_HANDLER(id) PORT_FAST_IRQ_HANDLER(id) + #ifdef __cplusplus extern "C" { #endif diff --git a/os/kernel/templates/chcore.h b/os/kernel/templates/chcore.h index c91d45b27..bd5d824b6 100644 --- a/os/kernel/templates/chcore.h +++ b/os/kernel/templates/chcore.h @@ -146,6 +146,15 @@ struct context { */ #define PORT_IRQ_HANDLER(id) void id(void) +/** + * @brief Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + * @note Not all architectures support fast interrupts, in this case this + * macro must be omitted. + */ +#define PORT_FAST_IRQ_HANDLER(id) void id(void) + #ifdef __cplusplus extern "C" { #endif diff --git a/os/ports/GCC/ARM7/chcore.h b/os/ports/GCC/ARM7/chcore.h index a6cc59d56..89391b352 100644 --- a/os/ports/GCC/ARM7/chcore.h +++ b/os/ports/GCC/ARM7/chcore.h @@ -117,13 +117,13 @@ struct context { * @details This code usually setup the context switching frame represented * by an @p intctx structure. */ -#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ - tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ - wsize - \ - sizeof(struct intctx)); \ - tp->p_ctx.r13->r4 = pf; \ - tp->p_ctx.r13->r5 = arg; \ - tp->p_ctx.r13->lr = _port_thread_start; \ +#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ + tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ + wsize - \ + sizeof(struct intctx)); \ + tp->p_ctx.r13->r4 = pf; \ + tp->p_ctx.r13->r5 = arg; \ + tp->p_ctx.r13->lr = _port_thread_start; \ } /** @@ -160,9 +160,9 @@ struct context { /** * @brief Computes the thread working area global size. */ -#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ - sizeof(struct intctx) + \ - sizeof(struct extctx) + \ +#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ + sizeof(struct intctx) + \ + sizeof(struct extctx) + \ (n) + (INT_REQUIRED_STACK)) /** @@ -184,16 +184,16 @@ struct context { * it is transparent to the user code. */ #ifdef THUMB -#define PORT_IRQ_PROLOGUE() { \ - asm volatile (".code 32 \n\t" \ - "stmfd sp!, {r0-r3, r12, lr} \n\t" \ - "add r0, pc, #1 \n\t" \ - "bx r0 \n\t" \ - ".code 16"); \ +#define PORT_IRQ_PROLOGUE() { \ + asm volatile (".code 32 \n\t" \ + "stmfd sp!, {r0-r3, r12, lr} \n\t" \ + "add r0, pc, #1 \n\t" \ + "bx r0 \n\t" \ + ".code 16"); \ } #else /* !THUMB */ -#define PORT_IRQ_PROLOGUE() { \ - asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \ +#define PORT_IRQ_PROLOGUE() { \ + asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \ } #endif /* !THUMB */ @@ -205,13 +205,13 @@ struct context { * ARM or THUMB mode. */ #ifdef THUMB -#define PORT_IRQ_EPILOGUE() { \ - asm volatile ("ldr r0, =_port_irq_common \n\t" \ - "bx r0"); \ +#define PORT_IRQ_EPILOGUE() { \ + asm volatile ("ldr r0, =_port_irq_common \n\t" \ + "bx r0"); \ } #else /* !THUMB */ -#define PORT_IRQ_EPILOGUE() { \ - asm volatile ("b _port_irq_common"); \ +#define PORT_IRQ_EPILOGUE() { \ + asm volatile ("b _port_irq_common"); \ } #endif /* !THUMB */ @@ -222,6 +222,14 @@ struct context { */ #define PORT_IRQ_HANDLER(id) __attribute__((naked)) void id(void) +/** + * @brief Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_FAST_IRQ_HANDLER(id) \ + __attribute__((interrupt("FIQ"))) void id(void) + /** * @brief Port-related initialization code. * @note This function is empty in this port. @@ -236,8 +244,8 @@ struct context { * enabled. */ #ifdef THUMB -#define port_lock() { \ - asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \ +#define port_lock() { \ + asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \ } #else /* !THUMB */ #define port_lock() asm volatile ("msr CPSR_c, #0x9F") @@ -250,8 +258,8 @@ struct context { * @note In this port it enables both the IRQ and FIQ sources. */ #ifdef THUMB -#define port_unlock() { \ - asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \ +#define port_unlock() { \ + asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \ } #else /* !THUMB */ #define port_unlock() asm volatile ("msr CPSR_c, #0x1F") @@ -283,16 +291,16 @@ struct context { * LPC214x datasheet. */ #ifdef THUMB -#define port_disable() { \ - asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \ +#define port_disable() { \ + asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \ } #else /* !THUMB */ -#define port_disable() { \ - asm volatile ("mrs r3, CPSR \n\t" \ - "orr r3, #0x80 \n\t" \ - "msr CPSR_c, r3 \n\t" \ - "orr r3, #0x40 \n\t" \ - "msr CPSR_c, r3" : : : "r3"); \ +#define port_disable() { \ + asm volatile ("mrs r3, CPSR \n\t" \ + "orr r3, #0x80 \n\t" \ + "msr CPSR_c, r3 \n\t" \ + "orr r3, #0x40 \n\t" \ + "msr CPSR_c, r3" : : : "r3"); \ } #endif /* !THUMB */ @@ -303,8 +311,8 @@ struct context { * FIQ sources. */ #ifdef THUMB -#define port_suspend() { \ - asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \ +#define port_suspend() { \ + asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \ } #else /* !THUMB */ #define port_suspend() asm volatile ("msr CPSR_c, #0x9F") @@ -315,8 +323,8 @@ struct context { * @note In this port it enables both the IRQ and FIQ sources. */ #ifdef THUMB -#define port_enable() { \ - asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \ +#define port_enable() { \ + asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \ } #else /* !THUMB */ #define port_enable() asm volatile ("msr CPSR_c, #0x1F") @@ -335,29 +343,29 @@ struct context { */ #ifdef THUMB #if CH_DBG_ENABLE_STACK_CHECK -#define port_switch(ntp, otp) { \ - register Thread *_ntp asm ("r0") = (ntp); \ - register Thread *_otp asm ("r1") = (otp); \ - register char *sp asm ("sp"); \ - if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ - asm volatile ("mov r0, #0 \n\t" \ - "ldr r1, =chDbgPanic \n\t" \ - "bx r1"); \ - _port_switch_thumb(_ntp, _otp); \ +#define port_switch(ntp, otp) { \ + register Thread *_ntp asm ("r0") = (ntp); \ + register Thread *_otp asm ("r1") = (otp); \ + register char *sp asm ("sp"); \ + if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ + asm volatile ("mov r0, #0 \n\t" \ + "ldr r1, =chDbgPanic \n\t" \ + "bx r1"); \ + _port_switch_thumb(_ntp, _otp); \ } #else /* !CH_DBG_ENABLE_STACK_CHECK */ #define port_switch(ntp, otp) _port_switch_thumb(ntp, otp) #endif /* !CH_DBG_ENABLE_STACK_CHECK */ #else /* !THUMB */ #if CH_DBG_ENABLE_STACK_CHECK -#define port_switch(ntp, otp) { \ - register Thread *_ntp asm ("r0") = (ntp); \ - register Thread *_otp asm ("r1") = (otp); \ - register char *sp asm ("sp"); \ - if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ - asm volatile ("mov r0, #0 \n\t" \ - "b chDbgPanic"); \ - _port_switch_arm(_ntp, _otp); \ +#define port_switch(ntp, otp) { \ + register Thread *_ntp asm ("r0") = (ntp); \ + register Thread *_otp asm ("r1") = (otp); \ + register char *sp asm ("sp"); \ + if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ + asm volatile ("mov r0, #0 \n\t" \ + "b chDbgPanic"); \ + _port_switch_arm(_ntp, _otp); \ } #else /* !CH_DBG_ENABLE_STACK_CHECK */ #define port_switch(ntp, otp) _port_switch_arm(ntp, otp) diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 99e9c3138..b76aa075a 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -157,7 +157,16 @@ struct intctx { * @note @p id can be a function name or a vector number depending on the * port implementation. */ -#define PORT_IRQ_HANDLER(id) void id(void) +#define PORT_IRQ_HANDLER(id) \ + __attribute__((interrupt("IRQ"))) void id(void) + +/** + * @brief Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_FAST_IRQ_HANDLER(id) \ + __attribute__((interrupt("IRQ"))) void id(void) /** * @brief Port-related initialization code. diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h index 5323cee73..4f1e88a48 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.h +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -130,7 +130,16 @@ struct intctx { * @note @p id can be a function name or a vector number depending on the * port implementation. */ -#define PORT_IRQ_HANDLER(id) void id(void) +#define PORT_IRQ_HANDLER(id) \ + __attribute__((interrupt("IRQ"))) void id(void) + +/** + * @brief Fast IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. + */ +#define PORT_FAST_IRQ_HANDLER(id) \ + __attribute__((interrupt("IRQ"))) void id(void) /** * @brief Port-related initialization code. diff --git a/readme.txt b/readme.txt index 71ec4a2cf..4fc9892c3 100644 --- a/readme.txt +++ b/readme.txt @@ -67,13 +67,16 @@ constants in different address spaces (AVR) because it is assumed that a pointer to a ROMCONST variable is compatible with a normal pointer. - NEW: AT91SAM7 HAL support for the DGBU UART peripheral, as SD3. +- NEW: Introduced a new macro CH_FAST_IRQ_HANDLER() for the declaration of + fast interrupt handlers on those architectures that support them. - OPT: Internal optimization in the serial driver, it now is a bit smaller and uses less RAM (all architectures). - CHANGE: Modified the STM32 FatFs demo, now it spawns a command shell or the serial port SD2, type "help" for the available commands. More commands can be easily added. - Various documentation fixes, added an article covering debugging under - ChibiOS/RT. + ChibiOS/RT, updated the article about interrupt handlers to cover also + fast interrupt sources. *** 1.5.5 *** - FIX: Removed some "dead" code in the old ARMv7-M files (there are new