ESP32: Need to take priority into account when allocating CPU interrupts

This commit is contained in:
Gregory Nutt
2016-10-25 16:27:58 -06:00
parent fef7b414c5
commit b8462d3e04
3 changed files with 98 additions and 29 deletions
+30 -8
View File
@@ -297,11 +297,17 @@
* 26 can be mapped to peripheral interrupts:
*
* Level triggered peripherals (21 total):
* 0-5, 8-9, 12-13, 17-21, 23-27, 31
* 0-5, 8-9, 12-13, 17-18 - Priority 1
* 19-21 - Priority 2
* 23, 27 - Priority 3
* 24-25 - Priority 4
* 26, 31 - Priority 5
* Edge triggered peripherals (4 total):
* 10, 22, 28, 30
* 10 - Priority 1
* 22 - Priority 3
* 28, 30 - Priority 4
* NMI (1 total):
* 14
* 14 - NMI
*
* CPU peripheral interrupts can be a assigned to a CPU interrupt using the
* PRO_*_MAP_REG or APP_*_MAP_REG. There are a pair of these registers for
@@ -310,11 +316,12 @@
*
* The remaining, five, internal CPU interrupts are:
*
* 6 Timer0
* 7 Software
* 15 Timer1
* 16 Timer2
* 29 Software
* 6 Timer0 - Priority 1
* 7 Software - Priority 1
* 11 Profiling - Priority 3
* 15 Timer1 - Priority 3
* 16 Timer2 - Priority 5
* 29 Software - Priority 3
*
* A peripheral interrupt can be disabled
*/
@@ -359,6 +366,21 @@
#define EPS32_CPUINT_PERIPHSET 0xdffe7f3f
#define EPS32_CPUINT_INTERNALSET 0x200180c0
/* Priority 1: 0-10, 12-13, 17-18 (15)
* Priority 2: 19-21 (3)
* Priority 3: 11, 15, 22-23, 27, 29 (6)
* Priority 4: 24-25, 28, 30 (4)
* Priority 5: 16, 26, 31 (3)
* Priority NMI: 14 (1)
*/
#define ESP32_INTPRI1_MASK 0x000637ff
#define ESP32_INTPRI2_MASK 0x00380000
#define ESP32_INTPRI3_MASK 0x28c08800
#define ESP32_INTPRI4_MASK 0x53000000
#define ESP32_INTPRI5_MASK 0x84010000
#define ESP32_INTNMI_MASK 0x00004000
/****************************************************************************
* Public Types
****************************************************************************/
+61 -14
View File
@@ -143,6 +143,12 @@
#define NO_CPUINT ESP32_CPUINT_TIMER0
/* Priority range is 1-5 */
#define ESP32_MIN_PRIORITY 1
#define ESP32_MAX_PRIORITY 5
#define ESP32_PRIO_INDEX(p) ((p) - ESP32_MIN_PRIORITY)
/****************************************************************************
* Private Data
****************************************************************************/
@@ -166,6 +172,17 @@ static uint32_t g_intenable[1];
static uint32_t g_level_ints = ESP32_LEVEL_SET;
static uint32_t g_edge_ints = ESP32_EDGE_SET;
/* Bitsets for each interrupt priority 1-5 */
static uint32_t g_priority[5] =
{
ESP32_INTPRI1_MASK,
ESP32_INTPRI2_MASK,
ESP32_INTPRI3_MASK,
ESP32_INTPRI4_MASK,
ESP32_INTPRI5_MASK
};
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -229,7 +246,7 @@ void up_enable_irq(int cpuint)
* Allocate a level CPU interrupt
*
* Input Parameters:
* None
* priority - Priority of the CPU interrupt (1-5)
*
* Returned Value:
* On success, the allocated level-sensitive, CPU interrupt numbr is
@@ -239,28 +256,39 @@ void up_enable_irq(int cpuint)
*
****************************************************************************/
int esp32_alloc_levelint(void)
int esp32_alloc_levelint(int priority)
{
irqstate_t flags;
uint32_t mask;
uint32_t intset;
int cpuint;
int ret = -ENOMEM;
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
/* Check if there are any level CPU interrupts available */
flags = enter_critical_section();
if ((g_level_ints & ESP32_LEVEL_SET) != 0)
{
/* Search for an unallocated CPU interrupt number in g_level_ints. */
for (cpuint = 0; cpuint < ESP32_CPUINT_NLEVELPERIPHS; cpuint++)
intset = g_level_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_LEVEL_SET;
if (intset != 0)
{
/* Skip over initial zeroes as quickly in groups of 8 bits. */
for (cpuint = 0, mask = 0xff;
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
cpuint += 8, mask <<= 8);
/* Search for an unallocated CPU interrupt number in the remaining intset. */
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
{
/* If the bit corresponding to the CPU interrupt is '1', then
* that CPU interrupt is available.
*/
mask = (1ul << cpuint);
if ((g_level_ints & mask) != 0)
if ((intset & mask) != 0)
{
/* Got it! */
@@ -268,6 +296,10 @@ int esp32_alloc_levelint(void)
ret = cpuint;
break;
}
/* Clear the bit in intset so that we may exit the loop sooner */
intset &= ~mask;
}
}
@@ -312,7 +344,7 @@ void esp32_free_levelint(int cpuint)
* Allocate an edge CPU interrupt
*
* Input Parameters:
* None
* priority - Priority of the CPU interrupt (1-5)
*
* Returned Value:
* On success, the allocated edge-sensitive, CPU interrupt numbr is
@@ -322,28 +354,39 @@ void esp32_free_levelint(int cpuint)
*
****************************************************************************/
int esp32_alloc_edgeint(void)
int esp32_alloc_edgeint(int priority)
{
irqstate_t flags;
uint32_t mask;
uint32_t intset;
int cpuint;
int ret = -ENOMEM;
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
/* Check if there are any level CPU interrupts available */
flags = enter_critical_section();
if ((g_edge_ints & ESP32_EDGE_SET) != 0)
{
/* Search for an unallocated CPU interrupt number in g_edge_ints. */
for (cpuint = 0; cpuint < ESP32_CPUINT_NEDGEPERIPHS; cpuint++)
intset = g_edge_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_EDGE_SET;
if (intset != 0)
{
/* Skip over initial zeroes as quickly in groups of 8 bits. */
for (cpuint = 0, mask = 0xff;
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
cpuint += 8, mask <<= 8);
/* Search for an unallocated CPU interrupt number in the remaining intset. */
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
{
/* If the bit corresponding to the CPU interrupt is '1', then
* that CPU interrupt is available.
*/
mask = (1ul << cpuint);
if ((g_edge_ints & mask) != 0)
if ((intset & mask) != 0)
{
/* Got it! */
@@ -351,6 +394,10 @@ int esp32_alloc_edgeint(void)
ret = cpuint;
break;
}
/* Clear the bit in intset so that we may exit the loop sooner */
intset &= ~mask;
}
}
+7 -7
View File
@@ -53,7 +53,7 @@
* Allocate a level CPU interrupt
*
* Input Parameters:
* None
* priority - Priority of the CPU interrupt (1-5)
*
* Returned Value:
* On success, the allocated level-sensitive, CPU interrupt numbr is
@@ -63,7 +63,7 @@
*
****************************************************************************/
int esp32_alloc_levelint(void);
int esp32_alloc_levelint(int priority);
/****************************************************************************
* Name: esp32_free_levelint
@@ -72,7 +72,7 @@ int esp32_alloc_levelint(void);
* Free a previoulsy allocated level CPU interrupt
*
* Input Parameters:
* The CPU interrupt number to be freed
* cpuint - The CPU interrupt number to be freed
*
* Returned Value:
* None
@@ -88,7 +88,7 @@ void esp32_free_levelint(int cpuint);
* Allocate an edge CPU interrupt
*
* Input Parameters:
* None
* priority - Priority of the CPU interrupt (1-5)
*
* Returned Value:
* On success, the allocated edge-sensitive, CPU interrupt numbr is
@@ -98,7 +98,7 @@ void esp32_free_levelint(int cpuint);
*
****************************************************************************/
int esp32_alloc_edgeint(void);
int esp32_alloc_edgeint(int priority);
/****************************************************************************
* Name: esp32_free_edgeint
@@ -107,14 +107,14 @@ int esp32_alloc_edgeint(void);
* Free a previoulsy allocated edge CPU interrupt
*
* Input Parameters:
* The CPU interrupt number to be freed
* cpuint - The CPU interrupt number to be freed
*
* Returned Value:
* None
*
****************************************************************************/
void esp32_free_edgeint(int cpuint);
void esp32_free_edgeint(int cpuint, int priority);
/****************************************************************************
* Name: esp32_attach_peripheral