2012-12-04 06:56 AM
Dear all,
I've an issue with TIM2 on the STM32f051 I did a port from STM32f103, however the interrupt is not activated anymore. A big difference is that I use a f0discovery board, so I make use of an internal RC occilator. I did some changes to use the HSI for clocking the PLL at the correct frequency Since TIM14 is working, it looks like initialising the clock is working fine. This is how the clock is initialized:static void Clk_Init(void)
{ RCC_HSICmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);/* Init PLL (8MHZ/2)*12 = 48MHZ */
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12); RCC_PLLCmd(ENABLE);while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);FLASH_PrefetchBufferCmd(ENABLE);
FLASH_SetLatency(FLASH_Latency_1); /* TIM2,3,14 at 48MHz */ RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM14 | RCC_APB1Periph_USART2, ENABLE); } This is how the initalisation of the timer is done void init_timer(void) { /* Peripherals InitStructure define */ static TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; static NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseStructure.TIM_Period = 48; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* set up Timer 2 */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM2, (NR_MSEC_FOR_MAIN * MSEC), TIM_PSCReloadMode_Immediate); TIM_InternalClockConfig(TIM2); TIM_Cmd(TIM2, ENABLE); /* switch timer on */ } After this initialisation, the micro never enters the TIM2_IRQHandler() Does someone has any idea? did I forgot any initalisation? TIM14 is working fine, however it does not make use of an IRQHandler(). Regards, Evert Huijben #irq-tim2-discoveryf02012-12-06 02:57 AM
I have used the IAP example of ...
IAP is tricky, I haven't yet done much with it.The USART and TIM interrupt handlers are defined by default, so I expect that this should be no problem.
I think my idea from yesterday doesn't match your problem. The TIM2 interrupt share the same name. I had been porting an application from a F10x to a F05x, while stumbling over this issue. The ADC interrupts have different names, and the F0 ADC shares his interrupt with the comparator. But there is another thing you can check. As the F0x-variants have different peripherals, I'm not sure if all use the same vector map. I'm using Crossworks (also GCC--based), which includes a ''stm32fxxx.vec'' file in the startup code (for F10x). That include relies on having the proper variant definition in the project properties. I have not yet checked this for F0 devices. But I would check for proper placement of the TIM2 interrupt routine both in the map file and finally on the device, using the debugger.However, I used the template /Source/Template/TrueSTUDIO/startup_stm32f0xx.s.
Is this the correct file for usage with a GNU compiler? or should the ARM or GCC_ride version be used?
This should be ok. The Atollic and RIDE startups are very similar, and the vector table section is identical. Both toolchains are based on GCC, and use the same assembler syntax. Keil does not. And, by the way, the Cortex M0 does not have a vector table offset register, it's vtable is fixed.
2012-12-06 05:37 AM
Hi
IAP is tricky, I haven't yet done much with it.
Indeed, it seems that my problem has something to do with the IAP, because in my bootloader interrups are working fine. From the moment I jump to my application they are not working anymore.But I would check for proper placement of the TIM2 interrupt routine both in the map file and finally on the device, using the debugger.
I've checked the map file of my application and the map file of my bootloader. I see some remarkable things but I don't have that much knowledge about map files. In the map file of the bootloader I see next entries with the TIM2_IRQHandler .text.TIM2_IRQHandler 0x08004bd8 0x50 /tmp/ccSj94Ve.o 0x08004bd8 TIM2_IRQHandler in the map file of the application I only see next entries when searching for the irq handler of TIM2: .dataf 0x20000d34 0x7c /tmp/ccmPzkVI.o 0x20000d34 TIM2_IRQHandler 0x20000d84 start_event_timer Maybe there is a relation with the definition of the IRQ handler: What does FASTCALL mean in the prefix of this function? By the way, omitting FASTCALL doen't resolve the problem. void FASTCALL TIM2_IRQHandler(void) { ...... } I found that debugging is very difficult on this device, especially with interrupts, Some more idea's, tips or tricks? Regards, Evert Huijben
2012-12-06 06:51 AM
Maybe there is a relation with the definition of the IRQ handler:
What does FASTCALL mean in the prefix of this function?
By the way, omitting FASTCALL doen't resolve the problem.
IMHO ''FASTCALL'' does not make sense at all here. It is basically for interfacing ASM routines. It's effect is to put some function argument into registers, and not on the stack. First, the ARM ABI does that anyway, and second (and more important), an interrupt handler has no arguments. So no wonder the effect is nil... But to understand your application: You have a bootloader, which uses UART and TIM2, and this part is working. This bootloader downloads your application, and stores it into FLASH. Is this also assumed to replace the interrupt handler in question ? Not sure how that would work without relocatable vector table. Is it possible that a TIM2 interrupt is then diverted to your old, ''bootloader''- TIM2 handler routine ?
2012-12-06 06:54 AM
Examine how AN4065 handles the relocation of the vector table into RAM
STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\binary_template\src...
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define APPLICATION_ADDRESS (uint32_t)0x08003000
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static __IO uint32_t TimingDelay;
#if (defined ( __CC_ARM ))
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));
#elif (defined (__ICCARM__))
#pragma location = 0x20000000
__no_init __IO uint32_t VectorTable[48];
#elif defined ( __GNUC__ )
__IO uint32_t VectorTable[48] __attribute__((section(''.RAMVectorTable'')));
#elif defined ( __TASKING__ )
__IO uint32_t VectorTable[48] __at(0x20000000);
#endif
/* Private function prototypes -----------------------------------------------*/
void Delay(__IO uint32_t nTime);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
uint32_t i = 0;
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f0xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f0xx.c file
*/
/* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/
/* Copy the vector table from the Flash (mapped at the base of the application
load address 0x08003000) to the base address of the SRAM at 0x20000000. */
for(i = 0; i < 48; i++)
{
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
}
/* Enable the SYSCFG peripheral clock*/
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Remap SRAM at 0x00000000 */
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
...
2012-12-06 07:21 AM
Hi,
You have a bootloader, which uses UART and TIM2, and this part is working.That's correctThis bootloader downloads your application, and stores it into FLASH.
Is this also assumed to replace the interrupt handler in question ?
Indeed, Those interrupts should be independant from each other.Is it possible that a TIM2 interrupt is then diverted to your old, ''bootloader''- TIM2 handler routine ? Since my application is started from a new adress in flash, including 'another' vector table, I don't expect that 'old' code is loaded. What can be an issue is that still some reset's needs to be done before jumping to my application. I already disable all interrupts before jumping to the new application location. Evert Huijben
2012-12-06 07:25 AM
2012-12-06 08:23 AM
No, I really don't think any additional initialization/resetting is required, you will need to enable interrupts if you have disabled them,but I'm not wholly convinced that's required if you deinitialize things properly before leaving the boot loader.
You need to verify the placement of VectorTable[] in your .MAP file. If that's broken none of the interrupt stuff is going to work. You could look at the Atollic Linker Script STM32F0xx_AN4065_FW_V1.0.0\Project\STM32F0xx_IAP\binary_template\TrueSTUDIO\STM320518_EVAL\stm32_flash.ld Although I personally would use something different in GNU/GCC via Yagarto.2012-12-07 01:44 AM
Hi Clive,
I use the linker file you mentioned in your post (the atollic version) is the one I use in my application. It has some changesto put the vector table in RAM. My changes are only related to the memory locations: MEMORY { /* Right now first 24K is occupied by the bootloader */ FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 64K - 0x8000 VTRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0xc0 /* First part of RAM is reserved to the vector table */ RAM (xrw) : ORIGIN = 0x200000c0, LENGTH = 8K - 0xc0 MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K } When I look in the MAP file, I see the vector table (isr_vector) is placed at 0x20000000. This seems correct. I also see next: .RAMVectorTable 0x20000000 0xc0 *(.RAMVectorTable) .RAMVectorTable 0x20000000 0xc0 /tmp/ccML7ryR.o 0x20000000 VectorTable It alo looks fine. I've added my MAP file as an attachment, maybe you can take a look into it. Also the IRQ's are mentioned in this file, Regards, Evert Huijben ________________ Attachments : gdr216-app.map : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0da&d=%2Fa%2F0X0000000bbk%2FeVeU8q1J4ZRkxDTH0_6n7uvd3RUE9g4Cax.rurNmy4U&asPdf=false2012-12-10 07:35 AM
2014-01-29 11:48 AM
Dear All,
I need your help. My MCU is STM32F030C8.I wrote a bootloader firmware and an application for this system.The bootloader is supposed to start at 0x0800 0000 and is 0x3000 in size.The application is supposed to start at 0x0800 3000 and is 0xC800 in size. (I keep the last two pages for device information).My problem is that I cannot successfully jump to the app...In my app I ensured to have done the following:/* Private macro -------------------------------------------------------------*/#if (defined ( __CC_ARM )) __IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));#elif (defined (__ICCARM__))#pragma location = 0x20000000 __no_init __IO uint32_t VectorTable[48];#elif defined ( __GNUC__ ) __IO uint32_t VectorTable[48] __attribute__((section(''.RAMVectorTable'')));#elif defined ( __TASKING__ ) __IO uint32_t VectorTable[48] __at(0x20000000);#endif/************************************************************//*** \brief Main application entry point* At this stage the microcontroller clock setting is already configured, * this is done through SystemInit() function which is called from startup* file (startup_stm32f030x8.s) before to branch to application main.* To reconfigure the default setting of SystemInit() function, refer to* startup_stm32f030x8.c file* *****************************************************************/int main( void ){ uint32_t i = 0; /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/ /* Copy the vector table from the Flash (mapped at the base of the application load address 0x08003000) to the base address of the SRAM at 0x20000000. */ for(i = 0; i < 48; i++) { VectorTable[i] = *(__IO uint32_t*)(IAP_APP_ADDRESS + (i<<2)); } RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; /* Enable the SYSCFG peripheral clock*/ SYSCFG->CFGR1 = SYSCFG_CFGR1_MEM_MODE; /* Remap SRAM at 0x00000000 *//***************** Application code starts here ***************************/}I am developing on Keil uVision 5 and used the following scatter loading file for bootloader and application.LR_IROM1 0x08000000 0x00003000 { ; load region size_region
ER_IROM1 0x08000000 0x00003000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x0000
2000 { ; RW data
.ANY (+RW +ZI) }} LR_IROM1 0x08003000 0x0000C800 { ; load region size_region ER_IROM1 0x08003000 0x0000C800 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x200000C0 0x00001FD0 { ; RW data .ANY (+RW +ZI) } }The section of code to jump to the app is as follows :void INTFLASH_execute_main_app(const char mode){ MyFunc_ptr AppEntry; __disable_irq(); AppEntry = (MyFunc_ptr) INTFLASH_calculate_page_addr(IAP_APP_START_PAGE); if( mode || intflash_check_main_app() ) { Main_App_ptr = (uint8_t*)AppEntry; if( (*Main_App_ptr != 0xFF) && (Main_App_ptr) ) { AppEntry(); } } __enable_irq();}When the code reaches AppEntry(); It causes an Hardwarde Fault exception and ends up here:HardFault_Handler\ PROC EXPORT HardFault_Handler [WEAK] B HardFault_Handler_C ENDPAs you can see I directed the exception to HardFault_Handler_C ISR inside system_stm32f0xx.c which is defined as follows:void HardFault_Handler_C(unsigned int* hardfault_args){ unsigned int buffer[14]; buffer[0] = hardfault_args[0]; //R0 buffer[1] = hardfault_args[1]; //R1 buffer[2] = hardfault_args[2]; //R2 buffer[3] = hardfault_args[3]; //R3 buffer[4] = hardfault_args[4]; //R12 buffer[5] = hardfault_args[5]; //LR buffer[6] = hardfault_args[6]; //PC buffer[7] = hardfault_args[7]; //PSR buffer[8] = *(unsigned int*)0xE000ED38; //BFAR buffer[9] = *(unsigned int*)0xE000ED28; //CFSR buffer[10] = *(unsigned int*)0xE000ED2C; //HFSR buffer[11] = *(unsigned int*)0xE000ED30; //DFSR buffer[12] = *(unsigned int*)0xE000ED3C; //AFSR buffer[13] = SCB->SHCSR; //SHCSR while (1);} The content of buffer is {0x20000c00, 0x080059e5, 0x080059ed, 0x080059ef, 0, 0, 0, 0,0 ,0....}Looking at the map of the main app. I saw that the addresses above match:__initial_sp 0x20000c00 Data 0 startup_stm32f030x8.o(STACK)Reset_Handler 0x080059e5 Thumb Code 8 startup_stm32f030x8.o(.text)NMI_Handler 0x080059ed Thumb Code 2 startup_stm32f030x8.o(.text)HardFault_Handler 0x080059ef Thumb Code 2 startup_stm32f030x8.o(.text)Can you please help me understand what is going on? I cannot successfully jump to the app...