Interrupt chaining: now working on all targets.

Tested on LPC1768, LPC11U24, KL25Z, LPC2368.
pull/23/head
Bogdan Marinescu 2013-08-07 14:43:36 +03:00
parent 43d4445074
commit d399e51bfd
25 changed files with 63 additions and 23 deletions

View File

@ -1,7 +1,7 @@
#ifndef MBED_INTERRUPTMANAGER_H #ifndef MBED_INTERRUPTMANAGER_H
#define MBED_INTERRUPTMANAGER_H #define MBED_INTERRUPTMANAGER_H
#include "cmsis_nvic.h" #include "cmsis.h"
#include "CallChain.h" #include "CallChain.h"
#include <string.h> #include <string.h>

View File

@ -74,7 +74,7 @@ bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq)
} }
void InterruptManager::irq_helper() { void InterruptManager::irq_helper() {
_chains[get_irq_index(NVIC_GetActiveInterrupt())]->call(); _chains[__get_IPSR()]->call();
} }
int InterruptManager::get_irq_index(IRQn_Type irq) { int InterruptManager::get_irq_index(IRQn_Type irq) {

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFFC00) // Vectors positioned at start of RAM #define NVIC_RAM_VECTOR_ADDRESS (0x1FFFFC00) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -9,6 +9,9 @@
#include "cmsis.h" #include "cmsis.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x1FFFF000) // Vectors positioned at start of RAM #define NVIC_RAM_VECTOR_ADDRESS (0x1FFFF000) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -27,7 +27,6 @@
* Option 2 is the one to go for, as RAM is the most valuable resource * Option 2 is the one to go for, as RAM is the most valuable resource
*/ */
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM #define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {

View File

@ -9,6 +9,9 @@
#include "cmsis.h" #include "cmsis.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM #define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -9,6 +9,9 @@
#include "cmsis.h" #include "cmsis.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -29,6 +29,3 @@ uint32_t NVIC_GetVector(IRQn_Type IRQn) {
return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; return vectors[IRQn + NVIC_USER_IRQ_OFFSET];
} }
IRQn_Type NVIC_GetActiveInterrupt(void) {
return (IRQn_Type)((SCB->ICSR & 0x1FF) - NVIC_USER_IRQ_OFFSET);
}

View File

@ -18,7 +18,6 @@ extern "C" {
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
uint32_t NVIC_GetVector(IRQn_Type IRQn); uint32_t NVIC_GetVector(IRQn_Type IRQn);
IRQn_Type NVIC_GetActiveInterrupt(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS 32
#define NVIC_USER_IRQ_OFFSET 0
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -8,6 +8,8 @@
#ifndef __ARM7_CORE_H__ #ifndef __ARM7_CORE_H__
#define __ARM7_CORE_H__ #define __ARM7_CORE_H__
#include "vector_defns.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -255,6 +257,15 @@ static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
NVIC->IntEnClr = 1 << (uint32_t)IRQn; NVIC->IntEnClr = 1 << (uint32_t)IRQn;
} }
static __INLINE uint32_t __get_IPSR(void)
{
unsigned i;
for(i = 0; i < 32; i ++)
if(NVIC->Address == NVIC->VectAddr[i])
return i;
return 1; // 1 is an invalid entry in the interrupt table on LPC2368
}
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -37,8 +37,10 @@
// VIC register addresses // VIC register addresses
#define VIC_Base 0xfffff000 #define VIC_Base 0xfffff000
#define VICAddress_Offset 0xf00 #define VICAddress_Offset 0xf00
#define VICVectAddr0_Offset 0x100
#define VICVectAddr2_Offset 0x108 #define VICVectAddr2_Offset 0x108
#define VICVectAddr3_Offset 0x10c #define VICVectAddr3_Offset 0x10c
#define VICVectAddr31_Offset 0x17c
#define VICIntEnClr_Offset 0x014 #define VICIntEnClr_Offset 0x014
#define VICIntEnClr (*(volatile unsigned long *)(VIC_Base + 0x014)) #define VICIntEnClr (*(volatile unsigned long *)(VIC_Base + 0x014))
#define VICVectAddr2 (*(volatile unsigned long *)(VIC_Base + 0x108)) #define VICVectAddr2 (*(volatile unsigned long *)(VIC_Base + 0x108))

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM #define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 41) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 53) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM #define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Location of vectors in RAM
// The LPC43xx can boot from multiple memories (internal Flash, external NOR, // The LPC43xx can boot from multiple memories (internal Flash, external NOR,

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 53) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM #define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 32) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -5,7 +5,6 @@
*/ */
#include "cmsis_nvic.h" #include "cmsis_nvic.h"
#define NVIC_NUM_VECTORS (16 + 81) // CORE + MCU Peripherals
#define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM #define NVIC_RAM_VECTOR_ADDRESS (0x20000000) // Location of vectors in RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash #define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash

View File

@ -7,6 +7,9 @@
#ifndef MBED_CMSIS_NVIC_H #ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H #define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (16 + 81) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h" #include "cmsis.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -12,8 +12,8 @@ void in_handler() {
} }
#if defined(TARGET_KL25Z) #if defined(TARGET_KL25Z)
#define PIN_OUT PTC7 #define PIN_OUT PTC6
#define PIN_IN PTA1 #define PIN_IN PTA5
#elif defined(TARGET_KL05Z) #elif defined(TARGET_KL05Z)
#define PIN_OUT PTB11 #define PIN_OUT PTB11

View File

@ -3,6 +3,18 @@
#include "cmsis.h" #include "cmsis.h"
#include "test_env.h" #include "test_env.h"
#if defined(TARGET_LPC1768)
#define TIMER_IRQ TIMER3_IRQn
#elif defined(TARGET_LPC11U24)
#define TIMER_IRQ TIMER_32_1_IRQn
#elif defined(TARGET_KL25Z)
#define TIMER_IRQ LPTimer_IRQn
#elif defined(TARGET_LPC2368)
#define TIMER_IRQ TIMER3_IRQn
#else
#error This test can't run on this target.
#endif
Serial pc(USBTX, USBRX); Serial pc(USBTX, USBRX);
Ticker flipper_1; Ticker flipper_1;
@ -28,7 +40,7 @@ Ticker flipper_2;
Sender s1(pc, '1'); Sender s1(pc, '1');
Sender s2(pc, '2'); Sender s2(pc, '2');
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) #if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) || defined(TARGET_LPC2368)
# define LED_NAME LED2 # define LED_NAME LED2
#elif defined(TARGET_KL05Z) #elif defined(TARGET_KL05Z)
# define LED_NAME LED2 # define LED_NAME LED2
@ -77,20 +89,20 @@ int main() {
flipper_2.add_function(&s2, &Sender::send); flipper_2.add_function(&s2, &Sender::send);
// Test global chaining (InterruptManager) // Test global chaining (InterruptManager)
printf("Handler initially: %08X\n", initial_handler = NVIC_GetVector(TIMER3_IRQn)); printf("Handler initially: %08X\n", initial_handler = NVIC_GetVector(TIMER_IRQ));
InterruptManager *pManager = InterruptManager::get(); InterruptManager *pManager = InterruptManager::get();
pFunctionPointer_t ptm = pManager->add_handler(testme, TIMER3_IRQn); pFunctionPointer_t ptm = pManager->add_handler(testme, TIMER_IRQ);
pFunctionPointer_t pinc = pManager->add_handler_front(&c, &Counter::inc, TIMER3_IRQn); pFunctionPointer_t pinc = pManager->add_handler_front(&c, &Counter::inc, TIMER_IRQ);
printf("Handler after calling InterruptManager: %08X\n", NVIC_GetVector(TIMER3_IRQn)); printf("Handler after calling InterruptManager: %08X\n", NVIC_GetVector(TIMER_IRQ));
wait(4.0); wait(4.0);
if (!pManager->remove_handler(ptm, TIMER3_IRQn) || !pManager->remove_handler(pinc, TIMER3_IRQn)) { if (!pManager->remove_handler(ptm, TIMER_IRQ) || !pManager->remove_handler(pinc, TIMER_IRQ)) {
printf ("remove handler failed.\n"); printf ("remove handler failed.\n");
notify_completion(false); notify_completion(false);
} }
printf("Interrupt handler calls: %d\n", c.get_count()); printf("Interrupt handler calls: %d\n", c.get_count());
printf("Handler after removing previously added functions: %08X\n", final_handler = NVIC_GetVector(TIMER3_IRQn)); printf("Handler after removing previously added functions: %08X\n", final_handler = NVIC_GetVector(TIMER_IRQ));
if (initial_handler != final_handler) { if (initial_handler != final_handler) {
printf( "InteruptManager test failed.\n"); printf( "InteruptManager test failed.\n");