2022-10-31 02:10 PM
Hi community,
This question is all about the behavior of the DMA1_Channel1_IRQHandler in my application.
I am working with an STM32G431CBT. It is running at 168MHz. Configured with 4 Flash wait states.
NVIC interrupt priorities are setup using CMSIS functions as follows:
SystemCoreClockUpdate();
clock = SystemCoreClock;
SysTick_Config(clock/1e3);
NVIC_SetPriorityGrouping(0);
NVIC_DisableIRQ(SysTick_IRQn);
irq_prio = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 10, 0);
NVIC_SetPriority(SysTick_IRQn, irq_prio);
NVIC_EnableIRQ(SysTick_IRQn);
irq_prio = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 13, 0);
NVIC_SetPriority(USART2_IRQn, irq_prio);
NVIC_EnableIRQ(USART2_IRQn);
irq_prio = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0); //highest priority!!!
NVIC_SetPriority(DMA1_Channel1_IRQn, irq_prio);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
TIM1->CCR5 (on match) triggers ADC conversion sequence. ADC triggers DMA1_Channel1 (circular, periph-to-mem). DMA1 is setup to issue an interrupt on transfer complete (TCIE).
The DMA1_Channel1_IRQHandler (has highest priority) then fires and a few things are processed and calculated within it.
My code compiles with no errors and warnings. And as far as I can see it all works as intended.
But here comes the strange thing:
Right at the start of DMA1_Channel1_IRQHandler I set a GPIO Pin high. At the End of DMA1_Channel1_IRQHandler I set the same Pin low. Looking at the generated high-low pulse with an oscilloscope I can measure the execution time of the DMA1_Channel1_IRQHandler. It takes 1.69µs.
But if I shrink the code in the main() by a few lines of code I can see that the execution time gets lower!!! :o And if I put just an empty while(1) loop in the main() execution time gets even lower....to its lowest-->1.22µs !!!!:o
How can that be? An ISR should not be affected in such a way by the amount of code in a low priority function just like main().
Anybody any ideas on that?
Cheers
2022-10-31 02:50 PM
Check alignment of IRQHandlers, and related call-back functions.
2022-10-31 06:29 PM
Put the interrupts in a different C file than main, otherwise the compiler just optimized too much by not needing to save/restore core registers on stack.
2022-10-31 09:55 PM
Try creating an interrupt handler that does the bare minimum besides setting the GPIO bits, that is no calls, write straight to the registers. Perhaps something is branching within the interrupt handler (perhaps within a routine the interrupt handler calls). You say the timing shrinks from 1.69uS to 1.22uS - but is that for all calls to the handler? Perhaps 1 in 10 ( 20, 30 ...) calls is still 1.69uS.
2022-11-01 05:03 PM
@Community member
OK seems I have to go through quite some learning curve here. How can I check the alignment of the Handler?
@S.Ma
I tried that. Did not make a difference at all.
@Community member
The ISR looks like this:
void DMA1_Channel1_IRQHandler(void)
{
if(DMA1->ISR & DMA_ISR_TCIF1) //check we are here cause of a valid interrupt occurred
{
DMA1->IFCR |= DMA_IFCR_CTCIF1; //reset interrupt flag
GPIOC->ODR |= (1U << 14); //Set Pin high
ev = (v - my_array[0]);
vp = A * ev;
vi = B * vi1;
if(vi > 4100) vi=4100;
if(vi < 0) vi=0;
vi1 = vi;
vd = C * (ev - (e1v+2));
e1v = ev;
cv = vp + vi + vd;
if(cv < 0) cv=0;
cv_t = cv/2;
if(cv_t > 4000 ) cv_t=4000;
/*------------------------------------------------------*/
ei = (my_array[1] - i);
ip = D * ei;
ii = E * ii1;
if(ii > 4100000 ) ii=4100000;
if(ii < 0 ) ii=0;
ii1 = ii;
id = F * (ei + (e1i-2));
e1i = ei;
ci = ip + ii + id;
if(ci < 0) ci=0;
ci_t = ci/1000;
if(ci_t > 4000 ) ci_t=4000;
cdac_t = (cv_t - ci_t);
if(cdac_t > 4000) cdac_t=4000;
if(cdac_t < 1500) cdac_t=1500;
GPIOC->ODR &= ~(1U << 14); //Set Pin low
}
}
All the variables are global. Some of them are "int" and others are "float". I am using the FPU.
The timing shrinks down to 1.22µs for every call to the handler. I verified that with the pulse trigger function of the oscilloscope. No longer pulses occur.
2022-11-01 05:22 PM
The .MAP file should give a good breakdown of the function placement.
You could perhaps do a listing / disassembly via objcopy or fromelf, and review that.
2022-11-01 05:47 PM
First thing I would say - Change the setting of the IO pin to use the BSSR register. it is a much safer way of setting the IO pin from an interrupt handler.
Try moving the "... //Set Pin low" before the first "if..." statement - and see if the variation still occurs - assuming it is ok at that point, progressively step/shift the statement to through the handler until the variation occurs. A bit laborious I know, but might help pin point the variation.
2022-11-01 11:22 PM
You are using the fpu... in the interrupt routine? If yes, this is a possible warning flag. Variables accessed in the ISR and outside are declared volatile?
2022-11-04 07:11 AM
This is what I could find in the .map file regarding the DMA1_Channel1_IRQHandler:
.text 0x0000000008000c88 0x3c /home/MB/opt/stm32CubeIDE_1.10.1/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.linux64_1.0.0.202111181127/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7e-m+fp/hard/libgcc.a(_fixunsdfdi.o)
0x0000000008000c88 __aeabi_d2ulz
0x0000000008000c88 __fixunsdfdi
*(.text*)
.text.DMA1_Channel1_IRQHandler
0x0000000008000cc4 0x258 ./Core/Src/ISR_Handlers.o
0x0000000008000cc4 DMA1_Channel1_IRQHandler
.text.cli_cmd_handler_kpv
0x0000000008000f1c 0x74 ./Core/Src/cli.o
0x0000000008000f1c cli_cmd_handler_kpv
And here a few snippets from the .list file that may help to find an issue:
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 000001d8 08000000 08000000 00010000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00006c0c 080001e0 080001e0 000101e0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00000a3c 08006df0 08006df0 00016df0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .ARM.extab 00000000 0800782c 0800782c 000202bc 2**0
CONTENTS
4 .ARM 00000000 0800782c 0800782c 000202bc 2**0
CONTENTS
5 .preinit_array 00000000 0800782c 0800782c 000202bc 2**0
CONTENTS, ALLOC, LOAD, DATA
6 .init_array 00000004 0800782c 0800782c 0001782c 2**2
CONTENTS, ALLOC, LOAD, DATA
7 .fini_array 00000004 08007830 08007830 00017830 2**2
CONTENTS, ALLOC, LOAD, DATA
8 .data 000002bc 20000000 08007834 00020000 2**2
CONTENTS, ALLOC, LOAD, DATA
9 .bss 000013b8 200002bc 08007af0 000202bc 2**2
ALLOC
10 ._user_heap_stack 00000604 20001674 08007af0 00021674 2**0
ALLOC
11 .ARM.attributes 00000030 00000000 00000000 000202bc 2**0
CONTENTS, READONLY
12 .comment 00000050 00000000 00000000 000202ec 2**0
CONTENTS, READONLY
13 .debug_frame 000017c8 00000000 00000000 0002033c 2**2
CONTENTS, READONLY, DEBUGGING, OCTETS
14 .stab 000000cc 00000000 00000000 00021b04 2**2
CONTENTS, READONLY, DEBUGGING
15 .stabstr 000001b9 00000000 00000000 00021bd0 2**0
CONTENTS, READONLY, DEBUGGING
2022-11-04 07:12 AM
8000cc0: 41f00000 .word 0x41f00000
08000cc4 <DMA1_Channel1_IRQHandler>:
8000cc4: 4b73 ldr r3, [pc, #460] ; (8000e94 <DMA1_Channel1_IRQHandler+0x1d0>)
8000cc6: 681a ldr r2, [r3, #0]
8000cc8: 0792 lsls r2, r2, #30
8000cca: b510 push {r4, lr}
8000ccc: f140 80c2 bpl.w 8000e54 <DMA1_Channel1_IRQHandler+0x190>
8000cd0: 685a ldr r2, [r3, #4]
8000cd2: 4871 ldr r0, [pc, #452] ; (8000e98 <DMA1_Channel1_IRQHandler+0x1d4>)
8000cd4: 4971 ldr r1, [pc, #452] ; (8000e9c <DMA1_Channel1_IRQHandler+0x1d8>)
8000cd6: f042 0202 orr.w r2, r2, #2
8000cda: 605a str r2, [r3, #4]
8000cdc: 4a70 ldr r2, [pc, #448] ; (8000ea0 <DMA1_Channel1_IRQHandler+0x1dc>)
8000cde: edd1 6a00 vldr s13, [r1]
8000ce2: 6993 ldr r3, [r2, #24]
8000ce4: f443 4380 orr.w r3, r3, #16384 ; 0x4000
8000ce8: 6193 str r3, [r2, #24]
8000cea: 4b6e ldr r3, [pc, #440] ; (8000ea4 <DMA1_Channel1_IRQHandler+0x1e0>)
8000cec: 681a ldr r2, [r3, #0]
8000cee: 8803 ldrh r3, [r0, #0]
8000cf0: b29b uxth r3, r3
8000cf2: 1ad2 subs r2, r2, r3
8000cf4: 4b6c ldr r3, [pc, #432] ; (8000ea8 <DMA1_Channel1_IRQHandler+0x1e4>)
8000cf6: 601a str r2, [r3, #0]
8000cf8: 4b6c ldr r3, [pc, #432] ; (8000eac <DMA1_Channel1_IRQHandler+0x1e8>)
8000cfa: 681b ldr r3, [r3, #0]
8000cfc: 4353 muls r3, r2
8000cfe: ee07 3a90 vmov s15, r3
8000d02: 4b6b ldr r3, [pc, #428] ; (8000eb0 <DMA1_Channel1_IRQHandler+0x1ec>)
8000d04: eef8 7ae7 vcvt.f32.s32 s15, s15
8000d08: edc3 7a00 vstr s15, [r3]
8000d0c: 4b69 ldr r3, [pc, #420] ; (8000eb4 <DMA1_Channel1_IRQHandler+0x1f0>)
8000d0e: 681b ldr r3, [r3, #0]
8000d10: 4353 muls r3, r2
8000d12: ee07 3a10 vmov s14, r3
8000d16: eeb8 7ac7 vcvt.f32.s32 s14, s14
8000d1a: 4b67 ldr r3, [pc, #412] ; (8000eb8 <DMA1_Channel1_IRQHandler+0x1f4>)
8000d1c: ee37 7a26 vadd.f32 s14, s14, s13
8000d20: eddf 6a66 vldr s13, [pc, #408] ; 8000ebc <DMA1_Channel1_IRQHandler+0x1f8>
8000d24: eeb4 7ae6 vcmpe.f32 s14, s13
8000d28: eef1 fa10 vmrs APSR_nzcv, fpscr
8000d2c: f340 8093 ble.w 8000e56 <DMA1_Channel1_IRQHandler+0x192>
8000d30: edc3 6a00 vstr s13, [r3]
8000d34: edd3 6a00 vldr s13, [r3]
8000d38: 4c61 ldr r4, [pc, #388] ; (8000ec0 <DMA1_Channel1_IRQHandler+0x1fc>)
8000d3a: edc1 6a00 vstr s13, [r1]
8000d3e: 4961 ldr r1, [pc, #388] ; (8000ec4 <DMA1_Channel1_IRQHandler+0x200>)
8000d40: 6824 ldr r4, [r4, #0]
8000d42: 680b ldr r3, [r1, #0]
8000d44: 600a str r2, [r1, #0]
8000d46: 1ad3 subs r3, r2, r3
8000d48: 4363 muls r3, r4
8000d4a: ee07 3a10 vmov s14, r3
8000d4e: ee77 7aa6 vadd.f32 s15, s15, s13
8000d52: eeb8 7ac7 vcvt.f32.s32 s14, s14
8000d56: 4b5c ldr r3, [pc, #368] ; (8000ec8 <DMA1_Channel1_IRQHandler+0x204>)
8000d58: 4a5c ldr r2, [pc, #368] ; (8000ecc <DMA1_Channel1_IRQHandler+0x208>)
8000d5a: ed83 7a00 vstr s14, [r3]
8000d5e: ee77 7a87 vadd.f32 s15, s15, s14
8000d62: 495b ldr r1, [pc, #364] ; (8000ed0 <DMA1_Channel1_IRQHandler+0x20c>)
8000d64: eefd 7ae7 vcvt.s32.f32 s15, s15
8000d68: ee17 3a90 vmov r3, s15
8000d6c: 2b00 cmp r3, #0
8000d6e: bfb8 it lt
8000d70: 2300 movlt r3, #0
8000d72: 6013 str r3, [r2, #0]
8000d74: 6813 ldr r3, [r2, #0]
8000d76: 8842 ldrh r2, [r0, #2]
8000d78: 4856 ldr r0, [pc, #344] ; (8000ed4 <DMA1_Channel1_IRQHandler+0x210>)
8000d7a: f5b3 6f7a cmp.w r3, #4000 ; 0xfa0
8000d7e: bfc8 it gt
8000d80: f44f 637a movgt.w r3, #4000 ; 0xfa0
8000d84: 600b str r3, [r1, #0]
8000d86: 4b54 ldr r3, [pc, #336] ; (8000ed8 <DMA1_Channel1_IRQHandler+0x214>)
8000d88: edd0 6a00 vldr s13, [r0]
8000d8c: 681b ldr r3, [r3, #0]
8000d8e: b292 uxth r2, r2
8000d90: 1ad2 subs r2, r2, r3
8000d92: 4b52 ldr r3, [pc, #328] ; (8000edc <DMA1_Channel1_IRQHandler+0x218>)
8000d94: 601a str r2, [r3, #0]
8000d96: 4b52 ldr r3, [pc, #328] ; (8000ee0 <DMA1_Channel1_IRQHandler+0x21c>)
8000d98: 681b ldr r3, [r3, #0]
8000d9a: 4353 muls r3, r2
8000d9c: ee07 3a90 vmov s15, r3
8000da0: 4b50 ldr r3, [pc, #320] ; (8000ee4 <DMA1_Channel1_IRQHandler+0x220>)
8000da2: eef8 7ae7 vcvt.f32.s32 s15, s15
8000da6: edc3 7a00 vstr s15, [r3]
8000daa: 4b4f ldr r3, [pc, #316] ; (8000ee8 <DMA1_Channel1_IRQHandler+0x224>)
8000dac: 681b ldr r3, [r3, #0]
8000dae: 4353 muls r3, r2
8000db0: ee07 3a10 vmov s14, r3
8000db4: eeb8 7ac7 vcvt.f32.s32 s14, s14
8000db8: 4b4c ldr r3, [pc, #304] ; (8000eec <DMA1_Channel1_IRQHandler+0x228>)
8000dba: ee37 7a26 vadd.f32 s14, s14, s13
8000dbe: eddf 6a4c vldr s13, [pc, #304] ; 8000ef0 <DMA1_Channel1_IRQHandler+0x22c>
8000dc2: eeb4 7ae6 vcmpe.f32 s14, s13
8000dc6: eef1 fa10 vmrs APSR_nzcv, fpscr
8000dca: dd50 ble.n 8000e6e <DMA1_Channel1_IRQHandler+0x1aa>
8000dcc: edc3 6a00 vstr s13, [r3]
8000dd0: edd3 6a00 vldr s13, [r3]
8000dd4: 4c47 ldr r4, [pc, #284] ; (8000ef4 <DMA1_Channel1_IRQHandler+0x230>)
8000dd6: edc0 6a00 vstr s13, [r0]
8000dda: 4847 ldr r0, [pc, #284] ; (8000ef8 <DMA1_Channel1_IRQHandler+0x234>)
8000ddc: 6824 ldr r4, [r4, #0]
8000dde: 6803 ldr r3, [r0, #0]
8000de0: 6002 str r2, [r0, #0]
8000de2: 1ad3 subs r3, r2, r3
8000de4: 4363 muls r3, r4
8000de6: ee07 3a10 vmov s14, r3
8000dea: ee77 7aa6 vadd.f32 s15, s15, s13
8000dee: eeb8 7ac7 vcvt.f32.s32 s14, s14
8000df2: 4b42 ldr r3, [pc, #264] ; (8000efc <DMA1_Channel1_IRQHandler+0x238>)
8000df4: 4a42 ldr r2, [pc, #264] ; (8000f00 <DMA1_Channel1_IRQHandler+0x23c>)
8000df6: ed83 7a00 vstr s14, [r3]
8000dfa: ee77 7a87 vadd.f32 s15, s15, s14
8000dfe: eefd 7ae7 vcvt.s32.f32 s15, s15
8000e02: ee17 3a90 vmov r3, s15
8000e06: 2b00 cmp r3, #0
8000e08: bfb8 it lt
8000e0a: 2300 movlt r3, #0
8000e0c: 6013 str r3, [r2, #0]
8000e0e: 6813 ldr r3, [r2, #0]
8000e10: 4a3c ldr r2, [pc, #240] ; (8000f04 <DMA1_Channel1_IRQHandler+0x240>)
8000e12: 4293 cmp r3, r2
8000e14: 4a3c ldr r2, [pc, #240] ; (8000f08 <DMA1_Channel1_IRQHandler+0x244>)
8000e16: bfce itee gt
8000e18: f44f 637a movgt.w r3, #4000 ; 0xfa0
8000e1c: f44f 707a movle.w r0, #1000 ; 0x3e8
8000e20: fb93 f3f0 sdivle r3, r3, r0
8000e24: 6013 str r3, [r2, #0]
8000e26: 6812 ldr r2, [r2, #0]
8000e28: 680b ldr r3, [r1, #0]
8000e2a: 1a9b subs r3, r3, r2
8000e2c: f5b3 6f7a cmp.w r3, #4000 ; 0xfa0
8000e30: 4a36 ldr r2, [pc, #216] ; (8000f0c <DMA1_Channel1_IRQHandler+0x248>)
8000e32: dd28 ble.n 8000e86 <DMA1_Channel1_IRQHandler+0x1c2>
8000e34: f44f 637a mov.w r3, #4000 ; 0xfa0
8000e38: 6013 str r3, [r2, #0]
8000e3a: 4b35 ldr r3, [pc, #212] ; (8000f10 <DMA1_Channel1_IRQHandler+0x24c>)
8000e3c: 6819 ldr r1, [r3, #0]
8000e3e: 6813 ldr r3, [r2, #0]
8000e40: 4a34 ldr r2, [pc, #208] ; (8000f14 <DMA1_Channel1_IRQHandler+0x250>)
8000e42: ea43 5301 orr.w r3, r3, r1, lsl #20
8000e46: 65d3 str r3, [r2, #92] ; 0x5c
8000e48: f102 4278 add.w r2, r2, #4160749568 ; 0xf8000000
8000e4c: 6993 ldr r3, [r2, #24]
8000e4e: f043 4380 orr.w r3, r3, #1073741824 ; 0x40000000
8000e52: 6193 str r3, [r2, #24]
8000e54: bd10 pop {r4, pc}
8000e56: eeb5 7ac0 vcmpe.f32 s14, #0.0
8000e5a: eddf 6a2f vldr s13, [pc, #188] ; 8000f18 <DMA1_Channel1_IRQHandler+0x254>
8000e5e: eef1 fa10 vmrs APSR_nzcv, fpscr
8000e62: bf48 it mi
8000e64: eeb0 7a66 vmovmi.f32 s14, s13
8000e68: ed83 7a00 vstr s14, [r3]
8000e6c: e762 b.n 8000d34 <DMA1_Channel1_IRQHandler+0x70>
8000e6e: eeb5 7ac0 vcmpe.f32 s14, #0.0
8000e72: eddf 6a29 vldr s13, [pc, #164] ; 8000f18 <DMA1_Channel1_IRQHandler+0x254>
8000e76: eef1 fa10 vmrs APSR_nzcv, fpscr
8000e7a: bf48 it mi
8000e7c: eeb0 7a66 vmovmi.f32 s14, s13
8000e80: ed83 7a00 vstr s14, [r3]
8000e84: e7a4 b.n 8000dd0 <DMA1_Channel1_IRQHandler+0x10c>
8000e86: f240 51db movw r1, #1499 ; 0x5db
8000e8a: 428b cmp r3, r1
8000e8c: bfd8 it le
8000e8e: f240 53dc movwle r3, #1500 ; 0x5dc
8000e92: e7d1 b.n 8000e38 <DMA1_Channel1_IRQHandler+0x174>
8000e94: 40020000 .word 0x40020000
8000e98: 20001548 .word 0x20001548
8000e9c: 20001544 .word 0x20001544
8000ea0: 48000800 .word 0x48000800
8000ea4: 20001550 .word 0x20001550
8000ea8: 20001524 .word 0x20001524
8000eac: 200000cc .word 0x200000cc
8000eb0: 2000154c .word 0x2000154c
8000eb4: 200000c4 .word 0x200000c4
8000eb8: 20001540 .word 0x20001540
8000ebc: 45802000 .word 0x45802000
8000ec0: 200014f8 .word 0x200014f8
8000ec4: 2000151c .word 0x2000151c
8000ec8: 2000153c .word 0x2000153c
8000ecc: 20001508 .word 0x20001508
8000ed0: 2000150c .word 0x2000150c
8000ed4: 20001530 .word 0x20001530
8000ed8: 20001538 .word 0x20001538
8000edc: 20001520 .word 0x20001520
8000ee0: 200000c8 .word 0x200000c8
8000ee4: 20001534 .word 0x20001534
8000ee8: 200000c0 .word 0x200000c0
8000eec: 2000152c .word 0x2000152c
8000ef0: 4a7a3e80 .word 0x4a7a3e80
8000ef4: 200014f4 .word 0x200014f4
8000ef8: 20001518 .word 0x20001518
8000efc: 20001528 .word 0x20001528
8000f00: 20001500 .word 0x20001500
8000f04: 003d0ce7 .word 0x003d0ce7
8000f08: 20001504 .word 0x20001504
8000f0c: 200014fc .word 0x200014fc
8000f10: 200000d0 .word 0x200000d0
8000f14: 50000800 .word 0x50000800
8000f18: 00000000 .word 0x00000000
08000f1c <cli_cmd_handler_kpv>:
8000f1c: 2802 cmp r0, #2