2020-06-24 09:16 AM
Hello,
I've designed a board based on an STM32F091CBU.
I needed CAN bus support, one SPI and one I2C and a timer interrupt.
When I tested my program, it hanged during the initialization of the IMU (an LSM6DSM) due to HAL_delays I ordinary set between SPI messages (paranoïd habit I must admit).
I've read on this forum that HAL_delay could hang due to a bad NVIC priority parameter. So after some tries, I decided to get rid of HAL_delays and the program was finally able to finish initialisation of the IMU. Then I activate an Interuption on a GPIO to know when data is available.
The program was supposed to send CAN frames every second through a CAN-PHY component so I've linked a CAN shield from seedstudio to it to monitor what is happening there. Dead silence.
After some checks with breakpoints, I discovered that my program never go inside the infinite loop. I've checked every peripherial interrupt handler with breakpoints and no-one seem to be called. And I suppose that my NVIC priorities could be responsible for that.
I would be very happy if someone could check my NVIC priorities and tell me if I did wrong.
Thank you.
2020-06-24 12:38 PM
Error_Handler and HardFault_Handler are silent places to die.
If it doesn't get to main() check SystemInit()
Would recommend getting a UART to work early in Reset_Handler, and output characters along the way to see where it passes through or where it hangs up.
An uncleared interrupt with loop indefinitely, blocking foreground code.
Stop in the debugger, see where the processor is currently executing.
2020-06-29 09:40 AM
Hello Clive and thank you for your answer.
I finally had the time to come back to this project and decided to set Breakpoints at every interrupt handler.
It was inefficient, so I used the "step into" button to understand where does it hang.
The program turned mad when reaching the while(1) loop. I got:
Reading all registers
Performing single step...
...Breakpoint reached @ address 0x08005946
Reading all registers
Performing single step...
In loop until I paused the program. Then I saw the arrow just in front of the "while(1)".
So I took a look at disassembly:
127 LSM6_INIT();
0800593c: bl 0x8005d18 <LSM6_INIT>
129 HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
08005940: movs r0, #7
08005942: bl 0x800114e <HAL_NVIC_EnableIRQ>
135 while (1)
08005946: b.n 0x8005946 <main+46>
149 {
SystemClock_Config:
08005948: push {r4, r7, lr}
0800594a: sub sp, #100 ; 0x64
0800594c: add r7, sp, #0
150 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
0800594e: movs r4, #44 ; 0x2c
08005950: adds r3, r7, r4
08005952: movs r0, r3
08005954: movs r3, #52 ; 0x34
08005956: movs r2, r3
08005958: movs r1, #0
0800595a: bl 0x8006928 <memset>
151 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
The arrow is in front of the line 7. I didn't studied assembly instrutions much, but "b.n" instruction looked particularly odd. So I checked and someone on a forum say it's a non maskable interrupt.
Still investigating at the moment...
2020-06-29 11:00 AM
b.n is your while(1) loop.
> So I checked and someone on a forum say it's a non maskable interrupt.
Yeah. they write a lot of stupid things out there.
-- pa
2020-06-30 07:20 AM
Hello,
Yes Pavel, indeed. I posted my message a little bit too fast and figured out what b.n mean minutes after.
So after constating that my GPIO interrupt handler never fire (the LSM6 should send something on INT2 due to his FIFO), I've put a reading of the amount of stored values inside the IMU. This reading happen everytime the main loop happen. With a breakpoint to check the retrieved value.
uint8_t addresse[2];
uint8_t quantity[2];
uint16_t quant_maxi = 0;
addresse[0]= 0X3A | 0b10000000; //FIFO_STATUS1 read
while (1)
{
/* USER CODE END WHILE */
//HAL_Delay(50);
//On demande combien de bytes sont stockés
HAL_GPIO_WritePin(CS_IMU_GPIO_Port, CS_IMU_Pin, RESET);
HAL_SPI_Transmit(&hspi1, (uint8_t*)addresse, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(&hspi1, (uint8_t *)quantity, 2, HAL_MAX_DELAY);
HAL_GPIO_WritePin(CS_IMU_GPIO_Port, CS_IMU_Pin, SET);
quant_maxi = (quantity[0] << 8) + quantity[1];
/* USER CODE BEGIN 3 */
}
First turn, quant_maxi = 0. Nothing really surprising. My ODR is pretty slow (26 Hz)
Second turn quant_maxi = 16. Pretty believable. But i get 16 at every check. Whatever time I spend betweend the "Resume debugging". Isn't the IMU supposed to live by himself? So I could get a higher number when I wait longer to resume?
Third turn: quant_maxi = 16 again???. That's when I'm lost.
Fourth turn: the program hang.
Still loking for paths to follow. I've already "breakpointed" every interrupt handlers and nothing suspicious seem to get out of the burrow.