Skip to content

Commit 401af50

Browse files
committed
stmhal: Add pyb.irq_stats() to get statistics about IRQ calls.
Adds a lot of code, makes IRQs a bit less efficient, but is very useful for debugging. Usage: pyb.irq_stats() returns a memory view that can be read and written, eg: list(pyb.irq_stats()) pyb.irq_stats()[0] pyb.irq_stats()[0] = 0 The patch provides general IRQ_ENTER() and IRQ_EXIT() macros that can be modified to provide further IRQ statistics if desired.
1 parent abd0fcf commit 401af50

7 files changed

Lines changed: 127 additions & 16 deletions

File tree

stmhal/dma.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,22 @@ volatile dma_idle_count_t dma_idle;
8686

8787
#define DMA_CHANNEL_AS_UINT8(dma_channel) (((dma_channel) & DMA_SxCR_CHSEL) >> 24)
8888

89-
void DMA1_Stream0_IRQHandler(void) { if (dma_handle[0] != NULL) { HAL_DMA_IRQHandler(dma_handle[0]); } }
90-
void DMA1_Stream1_IRQHandler(void) { if (dma_handle[1] != NULL) { HAL_DMA_IRQHandler(dma_handle[1]); } }
91-
void DMA1_Stream2_IRQHandler(void) { if (dma_handle[2] != NULL) { HAL_DMA_IRQHandler(dma_handle[2]); } }
92-
void DMA1_Stream3_IRQHandler(void) { if (dma_handle[3] != NULL) { HAL_DMA_IRQHandler(dma_handle[3]); } }
93-
void DMA1_Stream4_IRQHandler(void) { if (dma_handle[4] != NULL) { HAL_DMA_IRQHandler(dma_handle[4]); } }
94-
void DMA1_Stream5_IRQHandler(void) { if (dma_handle[5] != NULL) { HAL_DMA_IRQHandler(dma_handle[5]); } }
95-
void DMA1_Stream6_IRQHandler(void) { if (dma_handle[6] != NULL) { HAL_DMA_IRQHandler(dma_handle[6]); } }
96-
void DMA1_Stream7_IRQHandler(void) { if (dma_handle[7] != NULL) { HAL_DMA_IRQHandler(dma_handle[7]); } }
97-
void DMA2_Stream0_IRQHandler(void) { if (dma_handle[8] != NULL) { HAL_DMA_IRQHandler(dma_handle[8]); } }
98-
void DMA2_Stream1_IRQHandler(void) { if (dma_handle[9] != NULL) { HAL_DMA_IRQHandler(dma_handle[9]); } }
99-
void DMA2_Stream2_IRQHandler(void) { if (dma_handle[10] != NULL) { HAL_DMA_IRQHandler(dma_handle[10]); } }
100-
void DMA2_Stream3_IRQHandler(void) { if (dma_handle[11] != NULL) { HAL_DMA_IRQHandler(dma_handle[11]); } }
101-
void DMA2_Stream4_IRQHandler(void) { if (dma_handle[12] != NULL) { HAL_DMA_IRQHandler(dma_handle[12]); } }
102-
void DMA2_Stream5_IRQHandler(void) { if (dma_handle[13] != NULL) { HAL_DMA_IRQHandler(dma_handle[13]); } }
103-
void DMA2_Stream6_IRQHandler(void) { if (dma_handle[14] != NULL) { HAL_DMA_IRQHandler(dma_handle[14]); } }
104-
void DMA2_Stream7_IRQHandler(void) { if (dma_handle[15] != NULL) { HAL_DMA_IRQHandler(dma_handle[15]); } }
89+
void DMA1_Stream0_IRQHandler(void) { IRQ_ENTER(DMA1_Stream0_IRQn); if (dma_handle[0] != NULL) { HAL_DMA_IRQHandler(dma_handle[0]); } IRQ_EXIT(DMA1_Stream0_IRQn); }
90+
void DMA1_Stream1_IRQHandler(void) { IRQ_ENTER(DMA1_Stream1_IRQn); if (dma_handle[1] != NULL) { HAL_DMA_IRQHandler(dma_handle[1]); } IRQ_EXIT(DMA1_Stream1_IRQn); }
91+
void DMA1_Stream2_IRQHandler(void) { IRQ_ENTER(DMA1_Stream2_IRQn); if (dma_handle[2] != NULL) { HAL_DMA_IRQHandler(dma_handle[2]); } IRQ_EXIT(DMA1_Stream2_IRQn); }
92+
void DMA1_Stream3_IRQHandler(void) { IRQ_ENTER(DMA1_Stream3_IRQn); if (dma_handle[3] != NULL) { HAL_DMA_IRQHandler(dma_handle[3]); } IRQ_EXIT(DMA1_Stream3_IRQn); }
93+
void DMA1_Stream4_IRQHandler(void) { IRQ_ENTER(DMA1_Stream4_IRQn); if (dma_handle[4] != NULL) { HAL_DMA_IRQHandler(dma_handle[4]); } IRQ_EXIT(DMA1_Stream4_IRQn); }
94+
void DMA1_Stream5_IRQHandler(void) { IRQ_ENTER(DMA1_Stream5_IRQn); if (dma_handle[5] != NULL) { HAL_DMA_IRQHandler(dma_handle[5]); } IRQ_EXIT(DMA1_Stream5_IRQn); }
95+
void DMA1_Stream6_IRQHandler(void) { IRQ_ENTER(DMA1_Stream6_IRQn); if (dma_handle[6] != NULL) { HAL_DMA_IRQHandler(dma_handle[6]); } IRQ_EXIT(DMA1_Stream6_IRQn); }
96+
void DMA1_Stream7_IRQHandler(void) { IRQ_ENTER(DMA1_Stream7_IRQn); if (dma_handle[7] != NULL) { HAL_DMA_IRQHandler(dma_handle[7]); } IRQ_EXIT(DMA1_Stream7_IRQn); }
97+
void DMA2_Stream0_IRQHandler(void) { IRQ_ENTER(DMA2_Stream0_IRQn); if (dma_handle[8] != NULL) { HAL_DMA_IRQHandler(dma_handle[8]); } IRQ_EXIT(DMA2_Stream0_IRQn); }
98+
void DMA2_Stream1_IRQHandler(void) { IRQ_ENTER(DMA2_Stream1_IRQn); if (dma_handle[9] != NULL) { HAL_DMA_IRQHandler(dma_handle[9]); } IRQ_EXIT(DMA2_Stream1_IRQn); }
99+
void DMA2_Stream2_IRQHandler(void) { IRQ_ENTER(DMA2_Stream2_IRQn); if (dma_handle[10] != NULL) { HAL_DMA_IRQHandler(dma_handle[10]); } IRQ_EXIT(DMA2_Stream2_IRQn); }
100+
void DMA2_Stream3_IRQHandler(void) { IRQ_ENTER(DMA2_Stream3_IRQn); if (dma_handle[11] != NULL) { HAL_DMA_IRQHandler(dma_handle[11]); } IRQ_EXIT(DMA2_Stream3_IRQn); }
101+
void DMA2_Stream4_IRQHandler(void) { IRQ_ENTER(DMA2_Stream4_IRQn); if (dma_handle[12] != NULL) { HAL_DMA_IRQHandler(dma_handle[12]); } IRQ_EXIT(DMA2_Stream4_IRQn); }
102+
void DMA2_Stream5_IRQHandler(void) { IRQ_ENTER(DMA2_Stream5_IRQn); if (dma_handle[13] != NULL) { HAL_DMA_IRQHandler(dma_handle[13]); } IRQ_EXIT(DMA2_Stream5_IRQn); }
103+
void DMA2_Stream6_IRQHandler(void) { IRQ_ENTER(DMA2_Stream6_IRQn); if (dma_handle[14] != NULL) { HAL_DMA_IRQHandler(dma_handle[14]); } IRQ_EXIT(DMA2_Stream6_IRQn); }
104+
void DMA2_Stream7_IRQHandler(void) { IRQ_ENTER(DMA2_Stream7_IRQn); if (dma_handle[15] != NULL) { HAL_DMA_IRQHandler(dma_handle[15]); } IRQ_EXIT(DMA2_Stream7_IRQn); }
105105

106106
#define DMA1_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA1EN) != 0)
107107
#define DMA2_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA2EN) != 0)

stmhal/irq.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131

3232
/// \moduleref pyb
3333

34+
#if IRQ_ENABLE_STATS
35+
uint32_t irq_stats[FPU_IRQn + 1] = {0};
36+
#endif
37+
3438
/// \function wfi()
3539
/// Wait for an interrupt.
3640
/// This executies a `wfi` instruction which reduces power consumption
@@ -62,3 +66,11 @@ STATIC mp_obj_t pyb_enable_irq(uint n_args, const mp_obj_t *arg) {
6266
return mp_const_none;
6367
}
6468
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_enable_irq_obj, 0, 1, pyb_enable_irq);
69+
70+
#if IRQ_ENABLE_STATS
71+
// return a memoryview of the irq statistics array
72+
STATIC mp_obj_t pyb_irq_stats(void) {
73+
return mp_obj_new_memoryview(0x80 | 'I', MP_ARRAY_SIZE(irq_stats), &irq_stats[0]);
74+
}
75+
MP_DEFINE_CONST_FUN_OBJ_0(pyb_irq_stats_obj, pyb_irq_stats);
76+
#endif

stmhal/irq.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@
2828
#define IRQ_STATE_DISABLED (0x00000001)
2929
#define IRQ_STATE_ENABLED (0x00000000)
3030

31+
// Enable this to get a count for the number of times each irq handler is called,
32+
// accessible via pyb.irq_stats().
33+
#define IRQ_ENABLE_STATS (0)
34+
35+
#if IRQ_ENABLE_STATS
36+
extern uint32_t irq_stats[FPU_IRQn + 1];
37+
#define IRQ_ENTER(irq) ++irq_stats[irq]
38+
#define IRQ_EXIT(irq)
39+
#else
40+
#define IRQ_ENTER(irq)
41+
#define IRQ_EXIT(irq)
42+
#endif
43+
3144
static inline mp_uint_t query_irq(void) {
3245
return __get_PRIMASK();
3346
}
@@ -60,6 +73,7 @@ static inline void restore_irq_pri(uint32_t basepri) {
6073
MP_DECLARE_CONST_FUN_OBJ(pyb_wfi_obj);
6174
MP_DECLARE_CONST_FUN_OBJ(pyb_disable_irq_obj);
6275
MP_DECLARE_CONST_FUN_OBJ(pyb_enable_irq_obj);
76+
MP_DECLARE_CONST_FUN_OBJ(pyb_irq_stats_obj);
6377

6478
// IRQ priority definitions.
6579
//

stmhal/modpyb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
139139
{ MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj },
140140
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
141141
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
142+
#if IRQ_ENABLE_STATS
143+
{ MP_OBJ_NEW_QSTR(MP_QSTR_irq_stats), (mp_obj_t)&pyb_irq_stats_obj },
144+
#endif
142145

143146
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&machine_sleep_obj },
144147
{ MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&machine_deepsleep_obj },

stmhal/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Q(wfi)
4040
Q(disable_irq)
4141
Q(enable_irq)
4242
Q(reset)
43+
Q(irq_stats)
4344
Q(stop)
4445
Q(standby)
4546
Q(idle)

stmhal/sdcard.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ uint64_t sdcard_get_capacity_in_bytes(void) {
196196
}
197197

198198
void SDIO_IRQHandler(void) {
199+
IRQ_ENTER(SDIO_IRQn);
199200
HAL_SD_IRQHandler(&sd_handle);
201+
IRQ_EXIT(SDIO_IRQn);
200202
}
201203

202204
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {

0 commit comments

Comments
 (0)