Skip to main content
Lars Beiderbecke
Senior III
July 25, 2021
Solved

Missing EXTI IR handler code

  • July 25, 2021
  • 1 reply
  • 1492 views

I'm using the EXTI1 interrupt and defined the EXTI1 handler like this:

void EXTI1_IRQHandler(void)
{
 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
 if (GPIOA->IDR & 0x0100 { 
 EXTI->PR = 1;
 (void) EXTI->PR;
 NVIC_ClearPendingIRQ(EXTI0_IRQn);
 NVIC_EnableIRQ(EXTI0_IRQn);
 fun1();
 } else {
 NVIC_DisableIRQ(EXTI0_IRQn);
 EXTI->PR = 1;
 (void) EXTI->PR; // wait for hardware
 NVIC_ClearPendingIRQ(EXTI0_IRQn);
}

When I look at the generated list file, I find this assembly code:

000001d4 <EXTI1_IRQHandler>:
 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == RESET);
 1d4:	4bab 	ldr	r3, [pc, #684]	; (484 <_Min_Heap_Size+0x84>)
 1d6:	2102 	movs	r1, #2
 if (count-- == 0U)
 1d8:	4aab 	ldr	r2, [pc, #684]	; (488 <_Min_Heap_Size+0x88>)
 1da:	b5f0 	push	{r4, r5, r6, r7, lr}
 1dc:	6159 	str	r1, [r3, #20]
 1de:	6912 	ldr	r2, [r2, #16]
 1e0:	0792 	lsls	r2, r2, #30
 1e2:	d525 	bpl.n	230 <EXTI1_IRQHandler+0x5c>
 hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
 1e4:	4aa9 	ldr	r2, [pc, #676]	; (48c <_Min_Heap_Size+0x8c>)
 hrtc->Instance->ALRMASSR = subsecondtmpreg;
 1e6:	2040 	movs	r0, #64	; 0x40
 __HAL_RTC_ALARMA_ENABLE(hrtc);
 1e8:	2401 	movs	r4, #1
 1ea:	4ea9 	ldr	r6, [pc, #676]	; (490 <_Min_Heap_Size+0x90>)
 1ec:	2500 	movs	r5, #0
 1ee:	615c 	str	r4, [r3, #20]
 __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
 1f0:	695b 	ldr	r3, [r3, #20]
 1f2:	f8c2 0180 	str.w	r0, [r2, #384]	; 0x180
 1f6:	6010 	str	r0, [r2, #0]
 1f8:	6932 	ldr	r2, [r6, #16]
 while(Value >= 10)
 1fa:	4ba6 	ldr	r3, [pc, #664]	; (494 <_Min_Heap_Size+0x94>)
 1fc:	f402 4060 	and.w	r0, r2, #57344	; 0xe000
 200:	601a 	str	r2, [r3, #0]
 202:	f5b0 4f80 	cmp.w	r0, #16384	; 0x4000
 206:	671d 	str	r5, [r3, #112]	; 0x70
 208:	d025 	beq.n	256 <EXTI1_IRQHandler+0x82>
 20a:	f5b0 5f00 	cmp.w	r0, #8192	; 0x2000
 20e:	d062 	beq.n	2d6 <EXTI1_IRQHandler+0x102>
 return HAL_ERROR;
 210:	f5b0 4fc0 	cmp.w	r0, #24576	; 0x6000
 hsd->State = HAL_SD_STATE_READY;
 214:	d040 	beq.n	298 <EXTI1_IRQHandler+0xc4>
 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
 216:	f5b0 4f20 	cmp.w	r0, #40960	; 0xa000
 hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;
 21a:	da61 	bge.n	2e0 <EXTI1_IRQHandler+0x10c>
 21c:	f5b0 4f00 	cmp.w	r0, #32768	; 0x8000
 220:	f000 80c5 	beq.w	3ae <EXTI1_IRQHandler+0x1da>
 hsd->State = HAL_SD_STATE_READY;
 224:	4a9c 	ldr	r2, [pc, #624]	; (498 <_Min_Heap_Size+0x98>)
 hsd->Context = SD_CONTEXT_NONE;
 226:	4b9d 	ldr	r3, [pc, #628]	; (49c <_Min_Heap_Size+0x9c>)
 return HAL_ERROR;
 228:	6811 	ldr	r1, [r2, #0]
 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
 22a:	400b 	ands	r3, r1
 hsd->State = HAL_SD_STATE_READY;
 22c:	6013 	str	r3, [r2, #0]
 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
 22e:	bdf0 	pop	{r4, r5, r6, r7, pc}
 return HAL_ERROR;
 230:	4c99 	ldr	r4, [pc, #612]	; (498 <_Min_Heap_Size+0x98>)
 hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;
 232:	2040 	movs	r0, #64	; 0x40
 234:	4a99 	ldr	r2, [pc, #612]	; (49c <_Min_Heap_Size+0x9c>)
 236:	6825 	ldr	r5, [r4, #0]
 238:	4994 	ldr	r1, [pc, #592]	; (48c <_Min_Heap_Size+0x8c>)
 hsd->State = HAL_SD_STATE_READY;
 23a:	402a 	ands	r2, r5
 23c:	6022 	str	r2, [r4, #0]
 hsd->Context = SD_CONTEXT_NONE;
 23e:	f8c1 0080 	str.w	r0, [r1, #128]	; 0x80
 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS);
 242:	f3bf 8f4f 	dsb	sy
 hsd->State = HAL_SD_STATE_READY;
 246:	f3bf 8f6f 	isb	sy
 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS);
 24a:	2201 	movs	r2, #1
 hsd->State = HAL_SD_STATE_READY;
 24c:	615a 	str	r2, [r3, #20]
 24e:	695b 	ldr	r3, [r3, #20]
 return HAL_OK;
 250:	f8c1 0180 	str.w	r0, [r1, #384]	; 0x180
 254:	bdf0 	pop	{r4, r5, r6, r7, pc}
 256:	6858 	ldr	r0, [r3, #4]
// fun2(!) follows

This isn't my handler at all. Is there some boiler plate coding responsible for the context switch? Looking further, it seems that EXTI2 and EXTI3 handlers don't contain this boiler plate code.

So would the code shown actually be my EXTI1 handler, even though the source lines shown don't match?

    This topic has been closed for replies.
    Best answer by Lars Beiderbecke

    You know what? When I was looking closely at the generated assembly source, or rather the generated comments, I noticed that the assembly does match my handler, but the C source lines don't!

    So this is a bug after all, although not in code generation. Would gcc be the culprit here, or some other tool? Maybe I should switch to CubeIDE, since TrueSTUDIO isn't updated any more.

    1 reply

    TDK
    Super User
    July 25, 2021

    Your EXTI1_IRQHandler function won't compile as written because it has unbalanced parentheses and unbalanced brackets. Are you sure you're looking at the right files and not files in a different project?

    "If you feel a post has answered your question, please click ""Accept as Solution""."
    Lars Beiderbecke
    Senior III
    July 25, 2021

    Sorry, I copied it manually and replaced some defines. The handler is correct and compiles, though.

    And yes, I'm looking at the right file, as it changed today just minutes ago.

    TDK
    Super User
    July 25, 2021

    Clean the project, insert a syntax error into your EXTI1_IRQHandler, and try to compile. It should error out. If it does, fix the error and complete compiling. If that doesn't fix it, not sure what else it could be.

    > GPIOA->IDR & 0x0100

     

    This is checking against a reserved bit within IDR. Probably not what you want either.

    "If you feel a post has answered your question, please click ""Accept as Solution""."