cancel
Showing results for 
Search instead for 
Did you mean: 

Missing EXTI IR handler code

Lars Beiderbecke
Senior III

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?

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

8 REPLIES 8
TDK
Guru

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".

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.

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".

Yes, adding a syntax error to the handler will throw an error at exactly that handler, using the Atollic IDE.

Regarding the (potentially wrong) mask, I had substituted a macro here, and chosen a random value. The actual value is 0x2. Sorry to have led you down the wrong trail.

Do you know if all source code lines will be included in the list file as comments? Because I miss quite a few. And while I'm not surprised that the optimization -O2 shuffles code around, the fun2 in above snippet actually denotes the middle of some other inlined function

Also, what does the code do? I'm not using alarms myself, but I do use the SDMMC1 peripheral. To investigate, I searched for the first line, and found a hit in HAL_RTC_SetAlarm_IT, which also seems to contain the rest of the lines. Again, I have no idea why this is invoked here.

That's all very odd behavior. I do not have an explanation other than possibly a compiler/linker bug, but those are typically very unlikely.
Not sure if all source lines will be listed. I imagine not, but in my test with GCC, all of them (including comments) were listed. In any case, enough of them should be listed in order for you to see what's going on. In this case, the assembly code clearly does not match up with what's in your source file.
If you feel a post has answered your question, please click "Accept as Solution".

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.

Just for the record: Same behavior with gcc from CubeIDE.

If you’re in a position to share the full project code, or create a minimum working example which compiles to reproduce, I’ll take a closer look.
If you feel a post has answered your question, please click "Accept as Solution".