2015-10-19 07:32 AM
Hi,
I'm using OpenSTM32to debug my application.
I want to interrupt every 100 usec. In order to do that, I configure an interrupt based on a timer.
First, I evaluated theapplication in Nucleo-F334R8 and aparently it works fine.
But, I need to do that in the STM32303E-Eval. So, I tried to evaluate the same code in this board and it does not work, a hard fault exception is produced always.
This is the code:
main.c
#include ''stm32f30x.h''
#include ''stm32f30x_it.h''
static unsigned short status = 0;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
int main(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* Enable timer (timer runs at 10 KHz)*/
//The APB1 bus for timers works at 72 MHz
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_ClockDivision = 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 3600 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 2 - 1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0xF;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0xF;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
while (1)
{
while(status==0) {};
status=0;
}
}
void TIM2_IRQHandler(void) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
status=1;
//nothing to do here except for possibly copying DMA buffers of previous conversion
}
This is part of the clocks configuration
:
........
static void SetSysClock(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------*/
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer and set Flash Latency */
FLASH->ACR = FLASH_ACR_PRFTBE | (uint32_t)FLASH_ACR_LATENCY_1;
/* HCLK = SYSCLK / 1 */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 1 */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK / 2 */
//This is the Timer 2 clock and I think that it is 36 MHz x 2 = 72 MHz
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* PLL configuration */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL9);
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
........
I don't know why the hard fault exception is produced in this simple example...I have tried with different timers, but it occurs the same...
If you have any suggestion, I would be very grateful.
Thank you!!
#f3 #hard-fault #timer #interrupt2015-10-19 08:01 AM
Double check the vector table, it's location and it's content.
Confirm your routine is linking correctly, check the .MAP file. Doesn't appear to be a C++ issue, as this is main.c Presumably if you leave the NVIC enable out, it doesn't fault?2015-10-19 09:20 AM
Thank you clive1 for your fast answer.
Double check the vector table, it's location and it's content.Do you refer to check the NVIC_InitTypeDef and TIM_TimeBaseInitTypeDef structures? The same configuration works in Nucleo board¿?Confirm your routine is linking correctly, check the .MAP file.How can I know if the routine has been linked correctly? What can I watch exactly in the map file? I suppose that you refer to memory addresses...But, how can I solve this issue?Presumably if you leave the NVIC enable out, it doesn't fault?Do you refer to disable NVIC? If I disable NVIC, the timer interrupts do not attend...and hard fault exceptions neither happen.2015-10-19 10:03 AM
Neither of those definitions refers to the vector table.
The vector table is typically situated in the startup_stm32f3xx.s file (or equivalent), that needs to be tailored to the specific part being used. Make sure the IRQHandler you are using specifically matches the NAMED one in the table. The vector table address is typically assigned in system_stm32f3xx.c The .MAP file should help you identify what the linker put in the output file, and where it put it. You should confirm the IRQHandler gets into the output file, you should review the address, and then cross-check that with the data visible in the .HEX/.BIN at the location within the vector table that it should fall. You can also look at it in memory with the debugger. Make sure the name is not mangled, which C++ or .cpp, would do. Make sure the compiler command line defines the correct CPU, so that stm32f3xx.h enumerates the right set of interrupt indexes. The goal here is to understand WHY it's failing in the way it is. Right now I think its in files and settings not presented, or your build process. Once we understand why it fails, we'll be in a position to diagnose and fix the problem.