Loading...
 

Zephyr project on STM32

   Zephyr Workbench, a VSCode extension to manage Zephyr on STM32.
It enables users to easily create, develop, and debug Zephyr applications.
Main features:
  • Install host dependencies.
  • Import toolchain and SDK.
  • Create, configure, build and manage apps.
  • Debug STM32.
You can directly download it from the VSCode marketplace
For more details, visit the Zephyr Workbench

System Workbench for STM32


Usart receive interrupt sends program to UsageFault_Handler() infinite loop

I am working on linux with STM32F407 disco board and writing code using CMSIS libraries.

Whenever usart receive interrupt fires, program halts. Not one line executes.
When debugging, program stays in UsageFault_Handler() infinite loop.
I can provide code, if needed.

Could it be that startup code vector table isn’t initialized with USART2_IRQHandler ?

is the usart irq handler fired before fault handler?

No, usart irq handler never executes.
Probbably the problem is that void USART2_IRQHandler(void) is not definened in startup file, since
it is handled like unexpected interrupt.

Whole code is here (Maybe i forgot to call some specific stm32 workbench interrupt enable command :-D ):

  1. include “stm32f4xx_gpio.h”
  2. include “stm32f4xx.h”
  3. include “stm32f4xx_rcc.h”
  4. include “stm32f4xx_usart.h”
  5. include “stm32f4xx_exti.h”



//GPIO’s defines and functions

  1. define LEDG GPIO_Pin_12
  2. define LEDO GPIO_Pin_13
  3. define LEDR GPIO_Pin_14
  4. define LEDB GPIO_Pin_15
  5. define LEDPORT GPIOD
  6. define LEDPORTCLK RCC_AHB1ENR_GPIODEN
  7. define BUTTON GPIO_Pin_0
  8. define BUTTONPORT GPIOA
  9. define BUTTONPORTCLK RCC_AHB1ENR_GPIOAEN
  10. define DELAY 900000

  1. define BAUD_115200 115200
  2. define BAUD_9600 9600
  3. define BAUD_4800 4800


//These are the prototypes for the routines
void usart2_Init(int baudrate);
void usart2_Send(uint8_t data);
uint16_t usart2_Recieve(void);
void usart2_confInterrupt(void);
void usart2_SendString(char* string);
char* usart2_RecieveString(char* String);

void initializeLeds(void);
void initializeButton(void);

int main(void)
{

initializeLeds();
usart2_Init(BAUD_9600);
//initializeButton();
GPIO_ToggleBits(LEDPORT,LEDG);
usart2_confInterrupt();

for(;;){

usart2_SendString(“BEEF\n”);
}
}

// Serial data interrupt handler
void USART2_IRQHandler(void){
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){

usart2_Send(USART_ReceiveData(USART2));
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}
}


void EXTI0_IRQHandler(void){

if(EXTI_GetITStatus(EXTI_Line0) == SET){

GPIO_ToggleBits(LEDPORT,LEDG);
EXTI_ClearITPendingBit(EXTI_Line0);
}
}

void initializeLeds(){

GPIO_InitTypeDef GPIO_InitStructure;
//Enable clock on APB2 pripheral bus where button and LEDs are connected
RCC_AHB1PeriphClockCmd(LEDPORTCLK, ENABLE);
//select pins to initialize LED
GPIO_InitStructure.GPIO_Pin = LEDG|LEDB|LEDR|LEDO;
//select output push-pull mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//highest speed available
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LEDPORT, &GPIO_InitStructure);

}

void initializeButton(void){

GPIO_InitTypeDef GPIO_InitStructure;
//Enable clock on APB2 pripheral bus where button and LEDs are connected
RCC_AHB1PeriphClockCmd(BUTTONPORTCLK, ENABLE);
//select pins to initialize LED
GPIO_InitStructure.GPIO_Pin = BUTTON;
//select output push-pull mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//highest speed available
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(BUTTONPORT, &GPIO_InitStructure);

RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFGEN, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);

EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line= EXTI_Line0;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_Init(&NVIC_InitStructure);

}

void usart2_Init(int baudrate){

GPIO_InitTypeDef GPIO_InitStruct;

// Enable clock for GPIOA
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

/**
* Tell pins PA9 and PA10 which alternating function you will use
* @important Make sure, these lines are before pins configuration!
*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
// Initialize pins as alternating function
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/**
* Enable clock for USART1 peripheral
*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

/**
* Set Baudrate to value you pass to function
* Disable Hardware Flow control
* Set Mode To TX and RX, so USART will work in full-duplex mode
* Disable parity bit
* Set 1 stop bit
* Set Data bits to 8
*
* Initialize USART1
* Activate USART1
*/
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = baudrate;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART2, &USART_InitStruct);

USART_Cmd(USART2, ENABLE);
}

void usart2_Send(uint8_t data)
{
USART_SendData(USART2,data);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC ) == RESET){

}
}

void usart2_SendString(char* string){
while(*string != 0){
usart2_Send(*string++);
}
}

char* usart2_RecieveString(char* String){
while(*String != ‘\r’){
while(USART_GetFlagStatus(USART2,USART_FLAG_RXNE) == RESET);
*String++ = USART_ReceiveData(USART2);
}
return String;
}

uint16_t usart2_Recieve(void){

while(USART_GetFlagStatus(USART2,USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USART2);
}

void usart2_confInterrupt(void){

NVIC_InitTypeDef NVIC_InitStruct;
/**
* Set Channel to USART1
* Set Channel Cmd to enable. That will enable USART1 channel in NVIC
* Set Both priorities to 0. This means high priority
*
* Initialize NVIC
*/
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
// 0 priority is the highest
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}

I had the same problem.
Look at the startup file (.s)
You should manually write .weak descriptions for all periphery-specific interrupts.
Previously I worked with Coocox and it did all this staff automatically.


Well, iam glad i found salution. Kinda easy and straightforward if you are familiar with the architecture.

All i had to do was provide the startup’s file vector table with the interrupt handlers i need. Of corse with proper layout.


 

Newest Forum Posts

  1. reservation car service Seattle by Jamesprede, 2025-05-01 10:06
  2. Last day: drone bonus by Danielrug, 2025-04-19 16:55
  3. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-25 07:37
  4. SPI on Nucleo_STMH533RE by royjamil, 2025-03-23 11:31
  5. SPI on Nucleo_STMH533RE by higginsa1, 2025-03-23 09:33
  6. Configuring DMA for ADC in SW? by sam.hodgson, 2025-03-04 12:58
  7. Insightful Perspectives on This Subject by davidsycle, 2025-03-04 05:45
  8. Build a project in "release" mode by info@creosrl.it, 2025-02-20 18:12
  9. Build a project in "release" mode by info@creosrl.it, 2025-02-20 17:05
  10. Build a project in "release" mode by tang, 2025-02-20 10:36

Last-Modified Blogs