mirror of https://github.com/ARMmbed/mbed-os.git
Interrupt chaining: now working on all targets.
Tested on LPC1768, LPC11U24, KL25Z, LPC2368.pull/23/head
parent
43d4445074
commit
d399e51bfd
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue