diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2010-04-30 11:27:01 +0000 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2010-04-30 11:27:01 +0000 |
commit | 11d6263b83d009b199dad5995a0b0c5aedde44b2 (patch) | |
tree | 1e6977420defba0f905742949f12a628248a3e58 /c/src/lib/libbsp | |
parent | 2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff) | |
download | rtems-11d6263b83d009b199dad5995a0b0c5aedde44b2.tar.bz2 |
2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de>
* include/irq-config.h: Removed file.
* include/irq.h: New file (renamed from 'include/irq-config.h').
* include/irq-generic.h, src/irq-info.c: Include <bsp/irq.h> instead
of <bsp/irq-config.h>.
* src/irq-server.c: Use events instead of semaphore. Added error
counter for multiple chain appends. Added error counter to detect
erroneous interrupt events.
Diffstat (limited to 'c/src/lib/libbsp')
-rw-r--r-- | c/src/lib/libbsp/shared/ChangeLog | 10 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/include/irq-generic.h | 46 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/include/irq.h (renamed from c/src/lib/libbsp/shared/include/irq-config.h) | 2 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/src/irq-info.c | 5 | ||||
-rw-r--r-- | c/src/lib/libbsp/shared/src/irq-server.c | 116 |
5 files changed, 87 insertions, 92 deletions
diff --git a/c/src/lib/libbsp/shared/ChangeLog b/c/src/lib/libbsp/shared/ChangeLog index 6c0f8adcc5..011cf2e866 100644 --- a/c/src/lib/libbsp/shared/ChangeLog +++ b/c/src/lib/libbsp/shared/ChangeLog @@ -1,5 +1,15 @@ 2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de> + * include/irq-config.h: Removed file. + * include/irq.h: New file (renamed from 'include/irq-config.h'). + * include/irq-generic.h, src/irq-info.c: Include <bsp/irq.h> instead + of <bsp/irq-config.h>. + * src/irq-server.c: Use events instead of semaphore. Added error + counter for multiple chain appends. Added error counter to detect + erroneous interrupt events. + +2010-04-30 Sebastian Huber <sebastian.huber@embedded-brains.de> + * include/bootcard.h: Documentation. 2010-04-28 Joel Sherrill <joel.sherrilL@OARcorp.com> diff --git a/c/src/lib/libbsp/shared/include/irq-generic.h b/c/src/lib/libbsp/shared/include/irq-generic.h index e35b57a366..181bc58e2c 100644 --- a/c/src/lib/libbsp/shared/include/irq-generic.h +++ b/c/src/lib/libbsp/shared/include/irq-generic.h @@ -9,7 +9,7 @@ /* * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette. * - * Copyright (c) 2008, 2009 + * Copyright (c) 2008, 2009, 2010 * embedded brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim @@ -28,7 +28,7 @@ #include <rtems/irq-extension.h> -#include <bsp/irq-config.h> +#include <bsp/irq.h> #ifdef __cplusplus extern "C" { @@ -86,30 +86,30 @@ static inline rtems_vector_number bsp_interrupt_handler_index( * * The BSP interrupt support manages a sequence of interrupt vector numbers * ranging from @ref BSP_INTERRUPT_VECTOR_MIN to @ref BSP_INTERRUPT_VECTOR_MAX - * including the end points. It provides methods to @ref - * bsp_interrupt_handler_install() "install", @ref - * bsp_interrupt_handler_remove() "remove" and @ref - * bsp_interrupt_handler_dispatch() "dispatch" interrupt handlers for each + * including the end points. It provides methods to + * @ref bsp_interrupt_handler_install() "install", + * @ref bsp_interrupt_handler_remove() "remove" and + * @ref bsp_interrupt_handler_dispatch() "dispatch" interrupt handlers for each * vector number. It implements parts of the RTEMS interrupt manager. * * The entry points to a list of interrupt handlers are stored in a table * (= handler table). * - * You have to configure the BSP interrupt support in the bsp/irq-config.h file - * for each BSP. For a minimum configuration you have to provide @ref - * BSP_INTERRUPT_VECTOR_MIN and @ref BSP_INTERRUPT_VECTOR_MAX. + * You have to configure the BSP interrupt support in the <bsp/irq.h> file + * for each BSP. For a minimum configuration you have to provide + * @ref BSP_INTERRUPT_VECTOR_MIN and @ref BSP_INTERRUPT_VECTOR_MAX. * - * For boards with small memory requirements you can define @ref - * BSP_INTERRUPT_USE_INDEX_TABLE. With an enabled index table the handler + * For boards with small memory requirements you can define + * @ref BSP_INTERRUPT_USE_INDEX_TABLE. With an enabled index table the handler * table will be accessed via a small index table. You can define the size of * the handler table with @ref BSP_INTERRUPT_HANDLER_TABLE_SIZE. You must - * provide a data type for the index table (@ref - * bsp_interrupt_handler_index_type). It must be an integer type big enough to - * index the complete handler table. + * provide a data type for the index table + * (@ref bsp_interrupt_handler_index_type). It must be an integer type big + * enough to index the complete handler table. * - * Normally new list entries are allocated from the heap. You may define @ref - * BSP_INTERRUPT_NO_HEAP_USAGE, if you do not want to use the heap. For this - * option you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as well. + * Normally new list entries are allocated from the heap. You may define + * @ref BSP_INTERRUPT_NO_HEAP_USAGE, if you do not want to use the heap. For + * this option you have to define @ref BSP_INTERRUPT_USE_INDEX_TABLE as well. * * You have to provide some special routines in your BSP (follow the links for * the details): @@ -182,9 +182,9 @@ rtems_status_code bsp_interrupt_facility_initialize(void); * * This function shall enable the vector at the corresponding facility (in most * cases the interrupt controller). It will be called then the first handler - * is installed for the vector in bsp_interrupt_handler_install(). For a - * vector out of range this function shall do nothing except returning - * RTEMS_SUCCESSFUL. + * is installed for the vector in bsp_interrupt_handler_install(). It is + * guaranteed that the vector number is within the BSP_INTERRUPT_VECTOR_MIN and + * BSP_INTERRUPT_VECTOR_MAX range. * * @note You must not install or remove an interrupt handler in this function. * This may result in a deadlock. @@ -198,9 +198,9 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector); * * This function shall disable the vector at the corresponding facility (in * most cases the interrupt controller). It will be called then the last - * handler is removed for the vector in bsp_interrupt_handler_remove(). For a - * vector out of range this function shall do nothing except returning - * RTEMS_SUCCESSFUL. + * handler is removed for the vector in bsp_interrupt_handler_remove(). It is + * guaranteed that the vector number is within the BSP_INTERRUPT_VECTOR_MIN and + * BSP_INTERRUPT_VECTOR_MAX range. * * @note You must not install or remove an interrupt handler in this function. * This may result in a deadlock. diff --git a/c/src/lib/libbsp/shared/include/irq-config.h b/c/src/lib/libbsp/shared/include/irq.h index ff3136e795..ae57bd1c54 100644 --- a/c/src/lib/libbsp/shared/include/irq-config.h +++ b/c/src/lib/libbsp/shared/include/irq.h @@ -9,7 +9,7 @@ /* * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette. * - * Copyright (c) 2008, 2009 + * Copyright (c) 2008, 2009, 2010 * embedded brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim diff --git a/c/src/lib/libbsp/shared/src/irq-info.c b/c/src/lib/libbsp/shared/src/irq-info.c index 474784752d..5e68e5efd0 100644 --- a/c/src/lib/libbsp/shared/src/irq-info.c +++ b/c/src/lib/libbsp/shared/src/irq-info.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008, 2009 + * Copyright (c) 2008, 2009, 2010 * embedded brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim @@ -21,11 +21,8 @@ #include <inttypes.h> -#include <rtems/irq.h> - #include <bsp/irq-generic.h> #include <bsp/irq-info.h> -#include <bsp/irq-config.h> typedef struct { void *context; diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c index 933c15d55f..0026f0f5a6 100644 --- a/c/src/lib/libbsp/shared/src/irq-server.c +++ b/c/src/lib/libbsp/shared/src/irq-server.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2009 + * Copyright (c) 2009, 2010 * embedded brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim @@ -21,68 +21,89 @@ #include <stdlib.h> +#include <rtems.h> +#include <rtems/chain.h> + #include <bsp/irq-generic.h> +#define BSP_INTERRUPT_EVENT RTEMS_EVENT_13 + typedef struct bsp_interrupt_server_entry { + rtems_chain_node node; rtems_vector_number vector; rtems_interrupt_handler handler; void *arg; - struct bsp_interrupt_server_entry *volatile next; } bsp_interrupt_server_entry; -static rtems_id bsp_interrupt_server_semaphore = RTEMS_ID_NONE; +static rtems_id bsp_interrupt_server_id = RTEMS_ID_NONE; -/* LIFO list head */ -static bsp_interrupt_server_entry *volatile -bsp_interrupt_server_list_head = NULL; +static RTEMS_CHAIN_DEFINE_EMPTY(bsp_interrupt_server_chain); static rtems_status_code bsp_interrupt_server_is_initialized(void) { - if (bsp_interrupt_server_semaphore != RTEMS_ID_NONE) { + if (bsp_interrupt_server_id != RTEMS_ID_NONE) { return RTEMS_SUCCESSFUL; } else { return RTEMS_INCORRECT_STATE; } } +static unsigned bsp_interrupt_server_errors; + static void bsp_interrupt_server_trigger(void *arg) { bsp_interrupt_server_entry *e = arg; - rtems_interrupt_level level; bsp_interrupt_vector_disable(e->vector); - /* Add interrupt server entry to the list */ + if (e->node.next == NULL) { + rtems_chain_append(&bsp_interrupt_server_chain, &e->node); + } else { + ++bsp_interrupt_server_errors; + } + + rtems_event_send(bsp_interrupt_server_id, BSP_INTERRUPT_EVENT); +} + +static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void) +{ + rtems_interrupt_level level; + bsp_interrupt_server_entry *e; + rtems_interrupt_disable(level); - e->next = bsp_interrupt_server_list_head; - bsp_interrupt_server_list_head = e; + e = (bsp_interrupt_server_entry *) + rtems_chain_get_unprotected(&bsp_interrupt_server_chain); + if (e != NULL) { + e->node.next = NULL; + } rtems_interrupt_enable(level); - rtems_semaphore_release(bsp_interrupt_server_semaphore); + return e; } static void bsp_interrupt_server_task(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_id sema = bsp_interrupt_server_semaphore; - rtems_interrupt_level level; - bsp_interrupt_server_entry *e = NULL; while (true) { - sc = rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_event_set events = 0; + bsp_interrupt_server_entry *e = NULL; + + sc = rtems_event_receive( + BSP_INTERRUPT_EVENT, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); if (sc != RTEMS_SUCCESSFUL) { break; } - /* Fetch next interrupt server entry from the list */ - rtems_interrupt_disable(level); - e = bsp_interrupt_server_list_head; - bsp_interrupt_server_list_head = e->next; - rtems_interrupt_enable(level); - - (*e->handler)(e->arg); + while ((e = bsp_interrupt_server_get_entry()) != NULL) { + (*e->handler)(e->arg); - bsp_interrupt_vector_enable(e->vector); + bsp_interrupt_vector_enable(e->vector); + } } rtems_task_delete(RTEMS_SELF); @@ -137,7 +158,7 @@ rtems_status_code rtems_interrupt_server_handler_install( return RTEMS_NOT_IMPLEMENTED; } - e = malloc(sizeof(bsp_interrupt_server_entry)); + e = calloc(1, sizeof(*e)); if (e == NULL) { return RTEMS_NO_MEMORY; } @@ -220,67 +241,34 @@ rtems_status_code rtems_interrupt_server_initialize( ) { rtems_status_code sc = RTEMS_SUCCESSFUL; - rtems_id sema_id = RTEMS_ID_NONE; - rtems_id task_id = RTEMS_ID_NONE; - rtems_interrupt_level level; if (server != NULL) { return RTEMS_NOT_IMPLEMENTED; } - sc = rtems_semaphore_create( - rtems_build_name('I', 'R', 'Q', 'S'), - 0, - RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE, - 0, - &sema_id - ); - if (sc != RTEMS_SUCCESSFUL) { - return sc; - } - sc = rtems_task_create( rtems_build_name('I', 'R', 'Q', 'S'), priority, stack_size, modes, attributes, - &task_id + &bsp_interrupt_server_id ); if (sc != RTEMS_SUCCESSFUL) { - rtems_semaphore_delete(sema_id); - - return sc; - } - - /* Initialize global data (this must be done before the task starts) */ - rtems_interrupt_disable(level); - if (bsp_interrupt_server_semaphore == RTEMS_ID_NONE) { - bsp_interrupt_server_semaphore = sema_id; - sc = RTEMS_SUCCESSFUL; - } else { - sc = RTEMS_INCORRECT_STATE; - } - rtems_interrupt_enable(level); - if (sc != RTEMS_SUCCESSFUL) { - rtems_semaphore_delete(sema_id); - rtems_task_delete(task_id); - - return sc; + return RTEMS_TOO_MANY; } sc = rtems_task_start( - task_id, + bsp_interrupt_server_id, bsp_interrupt_server_task, 0 ); if (sc != RTEMS_SUCCESSFUL) { /* In this case we could also panic */ - bsp_interrupt_server_semaphore = RTEMS_ID_NONE; - rtems_semaphore_delete(sema_id); - rtems_task_delete(task_id); + rtems_task_delete(bsp_interrupt_server_id); + bsp_interrupt_server_id = RTEMS_ID_NONE; - return sc; + return RTEMS_TOO_MANY; } return RTEMS_SUCCESSFUL; |