2019-06-16 05:22 AM
Hello,
I wrote a program for the STM32F4 using the Standard Peripheral library from ST. I compile the source code with the ARM-GCC tool chain and flash it on the chip using OpenOCD in combination with gdb. As long as I do not use interrupts everything works fine. But now I want to use Timer interrupts. I activate them according to the Standard Peripheral manual, i.e I configure the NVIC with the commands:
NVIC_InitTypeDef nvicStruct;
nvicStruct.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
nvicStruct.NVIC_IRQChannelPreemptionPriority = 0;
nvicStruct.NVIC_IRQChannelSubPriority = 1;
nvicStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicStruct);
Then I am activating the Timer interrupt:
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
But as soon as the above line is executed, in GDB a message is popping up which says:
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08020388 in ?? ()
The program does not react anymore to commands from GDB. Trying to step forward just results in a
Cannot find bounds of current function
messages. The exact same is happening when I do activate the Timer interrupts first and the NVIC configuration second. Then the GDB error message is appearing after
NVIC_Init(&nvicStruct);
What could be the reason for this error? I have the theory, that the MCU is somehow jumping to the wrong address, during an interrupt.
Every help is greatly appreciated.
2019-06-16 06:21 AM
>>I have the theory, that the MCU is somehow jumping to the wrong address, during an interrupt.
Try carrying that idea over the finishing line..
Check that the SCB->VTOR points to the vector table properly, and that the vectors therein point to the right routines.
Check the .MAP file, and inspect the table.
Then review your IRQ Handler does the appropriate things.
If using C++/.CPP compilation watch for name mangling.
2019-06-16 06:26 AM
If you activate an interrupt (enable), the corresponding interrupt function (ISR) must be in the program space or it will jump to anywhere.
Find in your files the following (these are STM32L4R5)
TIM1_BRK_TIM15_IRQn = 24, /*!< TIM1 Break interrupt and TIM15 global interrupt */
TIM1_UP_TIM16_IRQn = 25, /*!< TIM1 Update Interrupt and TIM16 global interrupt */
TIM1_TRG_COM_TIM17_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM17 global interrupt */
TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */
There should be the corresponding functions like
void TIM1_CC_IRQHandler(void) function to declare and fill.
If the interrupt is not clearing the pending interrupt signal, your core will enter leave reenter leave reenter leave and the main loop won't move.
These are from HAL/LL code, and it might be same in Std lib.
2019-11-17 12:27 PM
Thanks for your replies guys.
I am really sorry, I haven't answered, yet, but I was pretty busy with my job and hadn't any spare time to push on with my STM32 project until now.
I did what you recommended. The SCB-VTOR is currently pointing to
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET
which seems reasonably for me.
I also checked the symbol table of my final elf file and noticed that the ISR Handler I need are not in the
.isr_vector section but in the .text section as can be seen by the following output of objdump.
080005b6 g F .text 00000008 TIM1_UP_TIM10_IRQHandler
080005be g F .text 00000008 TIM2_IRQHandler
I don't understand why these isr handlers are put to the wrong sections. For the definitions of the isr handlers I used the standard way described on countless sites:
First declare a weak declaration in my startup code which is then overwritten by a strong definition in my application code.
I paid attention to name mangling by putting the strong declarations in "extern C" construct
extern "C" {
void TIM2_IRQHandler(void);
void TIM1_UP_TIM10_IRQHandler(void);
}
I believe that the compiler or linker is falsely configured. Any ideas what can I do differently to get rid of this problem?
2019-11-17 12:52 PM
> I also checked the symbol table of my final elf file and noticed that the ISR Handler I need are not in the
> .isr_vector section but in the .text section as can be seen by the following output of objdump.
It's the *body* of the ISR which is in .text, and that's OK. The .isr_vector table should contain *address* of that ISR, i.e. in the respective row of the table you should see (in disasm) the *addresses* you've shown us above (more precisely, increased by 1, that's because the Cortex-M are Thumb... that's a slightly longer story to be told right now).
JW
2019-11-18 01:30 PM
But the problem is now that while TIM1_UP_TIM10_IRQHandler and TIM2_IRQHandler exist as symbols in .text there are no corresponding symbols in .isr_vector for them. Therefore the my program crashes when these interrupts are triggered. But why is that so?
2019-11-18 02:18 PM
Did you use extern "C" around the definition, rather than just the prototype?
The mangled function name is not going to achieve linkage with the symbols in startup.s
2019-11-19 02:21 PM
Yes, I did so. I put all the isr handlers which I define in my application program in an extern "C" definition
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void TIM2_IRQHandler(void);
void TIM1_UP_TIM10_IRQHandler(void);
#ifdef __cplusplus
}
#endif
But still all these handlers are completely missing in the .isr_vector section of the resulting .elf file, though in the .text section they are present.
2019-11-19 02:31 PM
By the way, this is my project, where I get this error. It would be awesome if someone could look into it and give me hint, what the problem might be. The project is not using a plain Makefile for compiling but is using CMake as build generator. I know that this is unusual in the embedded systems field, but I like CMake and therefore I used it here, too.