git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1892 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2010-04-26 12:34:10 +00:00
parent e53a1a3208
commit 314ba53ca7
7 changed files with 130 additions and 67 deletions

View File

@ -21,8 +21,11 @@
* @page article_interrupts How to write interrupt handlers * @page article_interrupts How to write interrupt handlers
* Since version 1.1.0 ChibiOS/RT offers a cross-platform method for writing * Since version 1.1.0 ChibiOS/RT offers a cross-platform method for writing
* interrupt handlers. Port-related and compiler-related details are * interrupt handlers. Port-related and compiler-related details are
* encapsulated within standard system macros.<br> * encapsulated within standard system macros.
* An interrupt handler assumes the following general form: *
* <h2>Writing Regular Interrupt handlers</h2>
* A Regular Interrupts handler (see @ref interrupt_classes) must be written
* using the following general form:
* @code * @code
CH_IRQ_HANDLER(myIRQ) { CH_IRQ_HANDLER(myIRQ) {
CH_IRQ_PROLOGUE(); CH_IRQ_PROLOGUE();
@ -38,12 +41,26 @@ CH_IRQ_HANDLER(myIRQ) {
CH_IRQ_EPILOGUE(); CH_IRQ_EPILOGUE();
} }
* @endcode * @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 * <h2>Writing Fast Interrupt handlers</h2>
* omit the macros. * In those architectures (@ref ARM7 and @ref ARMCMx) supporting Fast
* Another note about the handler name "myIRQ", in some ports it must be a * 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
*
* <h2>Handlers naming</h2>
* 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 * 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. * within a predefined set, see the notes about the various ports.
*
* <h2>Important Notes</h2> * <h2>Important Notes</h2>
* - There is an important application note about ARM7 interrupt handlers, * - There is an important application note about ARM7 interrupt handlers,
* please read about it in the ARM7 port section: @ref ARM7_IH * please read about it in the ARM7 port section: @ref ARM7_IH

View File

@ -154,12 +154,20 @@
#define CH_IRQ_EPILOGUE() PORT_IRQ_EPILOGUE() #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 * @note @p id can be a function name or a vector number depending on the
* port implementation. * port implementation.
*/ */
#define CH_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id) #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -146,6 +146,15 @@ struct context {
*/ */
#define PORT_IRQ_HANDLER(id) void id(void) #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -117,13 +117,13 @@ struct context {
* @details This code usually setup the context switching frame represented * @details This code usually setup the context switching frame represented
* by an @p intctx structure. * by an @p intctx structure.
*/ */
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ #define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \ tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
wsize - \ wsize - \
sizeof(struct intctx)); \ sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = pf; \ tp->p_ctx.r13->r4 = pf; \
tp->p_ctx.r13->r5 = arg; \ tp->p_ctx.r13->r5 = arg; \
tp->p_ctx.r13->lr = _port_thread_start; \ tp->p_ctx.r13->lr = _port_thread_start; \
} }
/** /**
@ -160,9 +160,9 @@ struct context {
/** /**
* @brief Computes the thread working area global size. * @brief Computes the thread working area global size.
*/ */
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \ sizeof(struct intctx) + \
sizeof(struct extctx) + \ sizeof(struct extctx) + \
(n) + (INT_REQUIRED_STACK)) (n) + (INT_REQUIRED_STACK))
/** /**
@ -184,16 +184,16 @@ struct context {
* it is transparent to the user code. * it is transparent to the user code.
*/ */
#ifdef THUMB #ifdef THUMB
#define PORT_IRQ_PROLOGUE() { \ #define PORT_IRQ_PROLOGUE() { \
asm volatile (".code 32 \n\t" \ asm volatile (".code 32 \n\t" \
"stmfd sp!, {r0-r3, r12, lr} \n\t" \ "stmfd sp!, {r0-r3, r12, lr} \n\t" \
"add r0, pc, #1 \n\t" \ "add r0, pc, #1 \n\t" \
"bx r0 \n\t" \ "bx r0 \n\t" \
".code 16"); \ ".code 16"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define PORT_IRQ_PROLOGUE() { \ #define PORT_IRQ_PROLOGUE() { \
asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \ asm volatile ("stmfd sp!, {r0-r3, r12, lr}"); \
} }
#endif /* !THUMB */ #endif /* !THUMB */
@ -205,13 +205,13 @@ struct context {
* ARM or THUMB mode. * ARM or THUMB mode.
*/ */
#ifdef THUMB #ifdef THUMB
#define PORT_IRQ_EPILOGUE() { \ #define PORT_IRQ_EPILOGUE() { \
asm volatile ("ldr r0, =_port_irq_common \n\t" \ asm volatile ("ldr r0, =_port_irq_common \n\t" \
"bx r0"); \ "bx r0"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define PORT_IRQ_EPILOGUE() { \ #define PORT_IRQ_EPILOGUE() { \
asm volatile ("b _port_irq_common"); \ asm volatile ("b _port_irq_common"); \
} }
#endif /* !THUMB */ #endif /* !THUMB */
@ -222,6 +222,14 @@ struct context {
*/ */
#define PORT_IRQ_HANDLER(id) __attribute__((naked)) void id(void) #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. * @brief Port-related initialization code.
* @note This function is empty in this port. * @note This function is empty in this port.
@ -236,8 +244,8 @@ struct context {
* enabled. * enabled.
*/ */
#ifdef THUMB #ifdef THUMB
#define port_lock() { \ #define port_lock() { \
asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_lock_thumb" : : : "r3", "lr"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define port_lock() asm volatile ("msr CPSR_c, #0x9F") #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. * @note In this port it enables both the IRQ and FIQ sources.
*/ */
#ifdef THUMB #ifdef THUMB
#define port_unlock() { \ #define port_unlock() { \
asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define port_unlock() asm volatile ("msr CPSR_c, #0x1F") #define port_unlock() asm volatile ("msr CPSR_c, #0x1F")
@ -283,16 +291,16 @@ struct context {
* LPC214x datasheet. * LPC214x datasheet.
*/ */
#ifdef THUMB #ifdef THUMB
#define port_disable() { \ #define port_disable() { \
asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_disable_thumb" : : : "r3", "lr"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define port_disable() { \ #define port_disable() { \
asm volatile ("mrs r3, CPSR \n\t" \ asm volatile ("mrs r3, CPSR \n\t" \
"orr r3, #0x80 \n\t" \ "orr r3, #0x80 \n\t" \
"msr CPSR_c, r3 \n\t" \ "msr CPSR_c, r3 \n\t" \
"orr r3, #0x40 \n\t" \ "orr r3, #0x40 \n\t" \
"msr CPSR_c, r3" : : : "r3"); \ "msr CPSR_c, r3" : : : "r3"); \
} }
#endif /* !THUMB */ #endif /* !THUMB */
@ -303,8 +311,8 @@ struct context {
* FIQ sources. * FIQ sources.
*/ */
#ifdef THUMB #ifdef THUMB
#define port_suspend() { \ #define port_suspend() { \
asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define port_suspend() asm volatile ("msr CPSR_c, #0x9F") #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. * @note In this port it enables both the IRQ and FIQ sources.
*/ */
#ifdef THUMB #ifdef THUMB
#define port_enable() { \ #define port_enable() { \
asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \ asm volatile ("bl _port_enable_thumb" : : : "r3", "lr"); \
} }
#else /* !THUMB */ #else /* !THUMB */
#define port_enable() asm volatile ("msr CPSR_c, #0x1F") #define port_enable() asm volatile ("msr CPSR_c, #0x1F")
@ -335,29 +343,29 @@ struct context {
*/ */
#ifdef THUMB #ifdef THUMB
#if CH_DBG_ENABLE_STACK_CHECK #if CH_DBG_ENABLE_STACK_CHECK
#define port_switch(ntp, otp) { \ #define port_switch(ntp, otp) { \
register Thread *_ntp asm ("r0") = (ntp); \ register Thread *_ntp asm ("r0") = (ntp); \
register Thread *_otp asm ("r1") = (otp); \ register Thread *_otp asm ("r1") = (otp); \
register char *sp asm ("sp"); \ register char *sp asm ("sp"); \
if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
asm volatile ("mov r0, #0 \n\t" \ asm volatile ("mov r0, #0 \n\t" \
"ldr r1, =chDbgPanic \n\t" \ "ldr r1, =chDbgPanic \n\t" \
"bx r1"); \ "bx r1"); \
_port_switch_thumb(_ntp, _otp); \ _port_switch_thumb(_ntp, _otp); \
} }
#else /* !CH_DBG_ENABLE_STACK_CHECK */ #else /* !CH_DBG_ENABLE_STACK_CHECK */
#define port_switch(ntp, otp) _port_switch_thumb(ntp, otp) #define port_switch(ntp, otp) _port_switch_thumb(ntp, otp)
#endif /* !CH_DBG_ENABLE_STACK_CHECK */ #endif /* !CH_DBG_ENABLE_STACK_CHECK */
#else /* !THUMB */ #else /* !THUMB */
#if CH_DBG_ENABLE_STACK_CHECK #if CH_DBG_ENABLE_STACK_CHECK
#define port_switch(ntp, otp) { \ #define port_switch(ntp, otp) { \
register Thread *_ntp asm ("r0") = (ntp); \ register Thread *_ntp asm ("r0") = (ntp); \
register Thread *_otp asm ("r1") = (otp); \ register Thread *_otp asm ("r1") = (otp); \
register char *sp asm ("sp"); \ register char *sp asm ("sp"); \
if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \ if (sp - sizeof(struct intctx) - sizeof(Thread) < (char *)_otp) \
asm volatile ("mov r0, #0 \n\t" \ asm volatile ("mov r0, #0 \n\t" \
"b chDbgPanic"); \ "b chDbgPanic"); \
_port_switch_arm(_ntp, _otp); \ _port_switch_arm(_ntp, _otp); \
} }
#else /* !CH_DBG_ENABLE_STACK_CHECK */ #else /* !CH_DBG_ENABLE_STACK_CHECK */
#define port_switch(ntp, otp) _port_switch_arm(ntp, otp) #define port_switch(ntp, otp) _port_switch_arm(ntp, otp)

View File

@ -157,7 +157,16 @@ struct intctx {
* @note @p id can be a function name or a vector number depending on the * @note @p id can be a function name or a vector number depending on the
* port implementation. * 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. * @brief Port-related initialization code.

View File

@ -130,7 +130,16 @@ struct intctx {
* @note @p id can be a function name or a vector number depending on the * @note @p id can be a function name or a vector number depending on the
* port implementation. * 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. * @brief Port-related initialization code.

View File

@ -67,13 +67,16 @@
constants in different address spaces (AVR) because it is assumed that a constants in different address spaces (AVR) because it is assumed that a
pointer to a ROMCONST variable is compatible with a normal pointer. pointer to a ROMCONST variable is compatible with a normal pointer.
- NEW: AT91SAM7 HAL support for the DGBU UART peripheral, as SD3. - 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 - OPT: Internal optimization in the serial driver, it now is a bit smaller
and uses less RAM (all architectures). and uses less RAM (all architectures).
- CHANGE: Modified the STM32 FatFs demo, now it spawns a command shell or - 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 the serial port SD2, type "help" for the available commands. More commands
can be easily added. can be easily added.
- Various documentation fixes, added an article covering debugging under - 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 *** *** 1.5.5 ***
- FIX: Removed some "dead" code in the old ARMv7-M files (there are new - FIX: Removed some "dead" code in the old ARMv7-M files (there are new