Author Topic: STM32 interrupt source (edit : programmer flakiness)  (Read 6106 times)

0 Members and 1 Guest are viewing this topic.

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
STM32 interrupt source (edit : programmer flakiness)
« on: April 19, 2017, 08:42:35 pm »
so, I have the el-cheapo STM32F334 demo board (amazing value!) and TrueStudio installed, and I am getting myself used to the whole shebang.

I have used this Cube business to basically configure the board,  and can get a crude blinky up and running, which is a start.

What I want to do is implement a simple scheduler,  using the SysTick to trigger the scheduler via a flag. So I have added  code to the handler for SysTick and the basic code I need in main(). I also tried turning off SysTick until my scheduler is loaded and ready tofly. But then I get an unexpected interrupt - but I don't know from where.

How do i check out registers to see where it came from? I am looking at the STM32 programming and hardware manuals, but don't find out how to determine the interrupt source. I guess some generated code somewhere is doing stuff I don't know about - but what?


« Last Edit: April 20, 2017, 02:05:20 pm by danmcb »
 

Offline TNorthover

  • Contributor
  • Posts: 42
  • Country: us
Re: STM32 interrupt source
« Reply #1 on: April 19, 2017, 08:58:44 pm »
I think you should be looking in the ARM Architecture Reference Manual (for v7M). The interrupt controller memory mapping and function is specified there. The NVIC_IABRn registers look particularly interesting (starting at 0xE000E300 accoring to Table B3-35).

Edit: link: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403e.b/index.html

Edit2: and the value you get looks like it matches up with Table 34 in the chip manual, which may (or hopefully not) lead you into querying the EXTI configuration if it's an external interrupt.
« Last Edit: April 19, 2017, 09:23:38 pm by TNorthover »
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source
« Reply #2 on: April 19, 2017, 09:42:49 pm »
holy crap. that is a serious reference manual. thank you!
 

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source
« Reply #3 on: April 19, 2017, 10:00:01 pm »
actually I probably asked the wrong question. A better one would  be "can I use STMCube to configure the SysTick? if so, how?"
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: STM32 interrupt source
« Reply #4 on: April 19, 2017, 10:03:42 pm »
Somewhere in your build are a bunch of "weak" interrupt handler definitions that map everything you haven't specifically written code for to the same "unhandled" vector. Stick a breakpoint in that unhandled handler so the core stops:

Code: [Select]
void Unhandled_Handler() {
  asm volatile ("bkpt #1");
}

... and when you get there, use your debugging environment to examine the IPSR register in the core. In Segger's ozone debugger, it'll look like the attached screen grab.

The number in IPSR is the number of the exception that just happened. Since you'll be in an "unhandled" exception, you'll know that's the troublemaker. The first 16 interrupts are standard for all Cortex-M chips. Higher interrupt numbers vary with the chip, so you'll have to look it up.[/code]
 
The following users thanked this post: danmcb

Offline TNorthover

  • Contributor
  • Posts: 42
  • Country: us
Re: STM32 interrupt source
« Reply #5 on: April 19, 2017, 10:39:08 pm »
... and when you get there, use your debugging environment to examine the IPSR register in the core. In Segger's ozone debugger, it'll look like the attached screen grab.

Now that's quite a bit simpler than my suggestion! I assume the Table 34 values are the external interrupt numbers so you just add 16 to get the IPSR-reported value?
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source
« Reply #6 on: April 19, 2017, 11:23:33 pm »
You guys are great. Thank you. I am really feeling my way with this at the moment.

I seem to have some kind of weirdness going on. I am not even convinced that the connection to the debugger is good. It seems flaky.

I took out any attempts to disable/enable interrupts, and went into STMCube again and turned off all IOs except the LEDs and  switch (all I want now). I also found interrupts were enabled for TIM1, I removed those. now there are only interrupts for things that look important, and SYSTICK.

If I load and start and hit main I have this:
Code: [Select]
int main(void)
{

  /* USER CODE BEGIN 1 */
timer_flag = 0;

#define NUM_TASKS 1
task tasks[NUM_TASKS];
// define tasks
tasks[0].elapsedTime = 0;
tasks[0].period = 1000;
tasks[0].TickFct = &T_blink;

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
     // Scheduler
      for (unsigned char t = 0; t < NUM_TASKS; ++t) {
         if (tasks[t].elapsedTime >= tasks[t].period) { // Ready
            tasks[t].TickFct(); // Go
            tasks[t].elapsedTime = 0;
         }
         tasks[t].elapsedTime++;
      }
      timer_flag = 0;
      while (!timer_flag) {}

  }
  /* USER CODE END 3 */

}

timer_flag is just a global, all the SysTick ISR should  do (for now) is set it:
Code: [Select]
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  if (timer_flag){
  // error! tasks not completed,  handle this better later on
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // red light on
  } else {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // red light off
  }
  timer_flag = 1; // must be reset by scheduler
  /* USER CODE END SysTick_IRQn 1 */
}


When I step through, my debugger seems to  lose it at the end of MX_GPIO_Init()
Code: [Select]
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LD_U_Pin|LD_D_Pin|LD_L_Pin|LD_R_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B_USER_Pin */
  GPIO_InitStruct.Pin = B_USER_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B_USER_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LD_U_Pin LD_D_Pin LD_L_Pin LD_R_Pin */
  GPIO_InitStruct.Pin = LD_U_Pin|LD_D_Pin|LD_L_Pin|LD_R_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

When it gets the last instruction, instead of going back to main() it seems to hang. In fact I seem to now end up here:
Code: [Select]
   .section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex-M4.  Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
  .section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors



which I think is the default handler Andy mentioned. but if I break here, and look at registers - no IPSR register ... (see screenshot attached).

Meh. this is obviously something silly, but it's late and I am gonna get some sleep. Sorry if this is confused or silly - but if you can give me some pointers, that will be appreciated.

cheers!





 

Offline TNorthover

  • Contributor
  • Posts: 42
  • Country: us
Re: STM32 interrupt source
« Reply #7 on: April 20, 2017, 01:06:08 am »
The xpsr is sensible and seems to contain the IPSR data Andy mentioned. Specifically the low byte is 0x29, which indicates the 0x29 - 16 = 25th external interrupt. Looking at the CPU reference that's a "TIM1" signal, which sounds very plausible given that you've been playing around with that component.

So I suspect you may not have quite managed to disable TIM1 everywhere. Unfortunately I'm not familiar enough with the software to tell you how to do it properly. But someone who is might find the "Generate Report" pdf output very useful in telling you where things have gone wrong.
« Last Edit: April 20, 2017, 01:08:59 am by TNorthover »
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source
« Reply #8 on: April 20, 2017, 07:19:45 am »
OK,  that was helpful. Thanks. It turns out that there was in fact a place to set SysTick as the timebase - not TIM1. Once I did that TIM1 ints are gone.

But I still have this odd issue that the thing hangs before it gets to my main loop - at the end of the MX_GPIO_Init() call. See screenshot. WHat happens is that it gets to the end of this function, and then loops infinitely on the instruction in the Disassembly pane - ( "b.n ... " etc)

What is this and where does it come from?

This is the STCube report - I think it is clean now.

Code: [Select]
Configuration Blinky
STM32CubeMX 4.20.1
Date 04/20/2017
MCU STM32F334C8Tx



PERIPHERALS MODES FUNCTIONS PINS
SYS SysTick SYS_VS_Systick VP_SYS_VS_Systick



Pin Nb PINs FUNCTIONs LABELs
10 PA0 GPIO_EXTI0 B_USER [B1 Blue PushButton]
42 PB6 GPIO_Output LD_U [LD3 Red Led]
43 PB7 GPIO_Output LD_D [LD6 Blue Led]
45 PB8 GPIO_Output LD_L [LD4 Orange Led]
46 PB9 GPIO_Output LD_R [LD5 Green Led]



SOFTWARE PROJECT

Project Settings :
Project Name : Blinky
Project Folder : C:\STM32\work\blinky\Blinky
Toolchain / IDE : TrueSTUDIO
Firmware Package Name and Version : STM32Cube FW_F3 V1.7.0


Code Generation Settings :
STM32Cube Firmware Library Package : Copy only the necessary library files
Generate peripheral initialization as a pair of '.c/.h' files per peripheral : No
Backup previously generated files when re-generating : No
Delete previously generated files when not re-generated : Yes
Set all free pins as analog (to optimize the power consumption) : No


Toolchains Settings :
Compiler Optimizations : Balanced Size/Speed


 

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source
« Reply #9 on: April 20, 2017, 07:57:21 am »
Woah. I fixed it.

I went into project settings and TURNED OFF all compiler optimisations  (it was set to optimise for size).

The thing that made me suspicious was that when I single-stepped - things seemed to be running out of sequence - like jumping three steps ahead, then back two ... then ... and also when I looked at the disassembly, I could see that it seemed to be in-lining things.

Turned off the opts altogether, and now the debugger seems to step as I would expect. I though I was losing the plot for a bit there.

But -- WTF? what so(u)rcery is this ... ? Is this the fault of attollic or the GNU compiler? this strikes me as very flakey - no? what the hell kind of compiler "optimisation" hangs the chip in an infinite loop at the end of a basic function call?

« Last Edit: April 20, 2017, 08:04:01 am by danmcb »
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: STM32 interrupt source
« Reply #10 on: April 20, 2017, 10:54:35 am »
Woah. I fixed it.

I went into project settings and TURNED OFF all compiler optimisations  (it was set to optimise for size).

The thing that made me suspicious was that when I single-stepped - things seemed to be running out of sequence - like jumping three steps ahead, then back two ... then ... and also when I looked at the disassembly, I could see that it seemed to be in-lining things.

Turned off the opts altogether, and now the debugger seems to step as I would expect. I though I was losing the plot for a bit there.

But -- WTF? what so(u)rcery is this ... ? Is this the fault of attollic or the GNU compiler? this strikes me as very flakey - no? what the hell kind of compiler "optimisation" hangs the chip in an infinite loop at the end of a basic function call?

I'd put GCC or Attollic being at fault very low on the list of probabilities

 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #11 on: April 20, 2017, 11:17:55 am »
well, it is their code, compiling with their default setup.
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #12 on: April 20, 2017, 11:40:12 am »
I also estimate the problem to be somewhere else than gcc.
Cube MX, possible.
User code possible too, especially if it goes away removing optimizations.
Can we see the whole thing?
To name just one point: there's exchange of information from SysTick ISR and the main loop through flags, have they been declared as volatile?
That's the first thing that bites when switching on optimizations.
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: danmcb

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #13 on: April 20, 2017, 12:26:01 pm »
If you lose debug connectivity during initialization of GPIO you're overwriting the default GPIO config of the SWD/JTAG pins in a way that they don't support the debug channel anymore.

Also, add this line somewhere early on.
Code: [Select]
CoreDebug->DEMCR |= CoreDebug_DEMCR_VC_HARDERR_Msk;It makes the code throw a breakpoint when entering the hardfault handler. (eg: when you've done something terribly wrong)
You can use the following series of if's to know what you did wrong.
Code: [Select]
uint32_t cfsr = SCB->CFSR;
if(cfsr & SCB_CFSR_DIVBYZERO  )
if(cfsr & SCB_CFSR_...)
« Last Edit: April 20, 2017, 12:28:13 pm by Jeroen3 »
 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #14 on: April 20, 2017, 12:51:00 pm »
thank you again, people for the suggestions.

Mea culpa - no I didn't declare the flag volatile. I will see if putting the optimisation back in has the same results now, with and without that. But, of course, it should be. Will also post code.

I'm a bit sceptical about whether this is it though - the last b jump statement at the end of the GPIO_Init was basically jumping to itself I think (OK, I didn't work out the physical address, but stepping, it was stuck at that location. Never went back to main(). But I will try and see.

The debug crash has completely stopped since I took out the optimisation.
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #15 on: April 20, 2017, 01:50:05 pm »
thank you again, people for the suggestions.

Mea culpa - no I didn't declare the flag volatile. I will see if putting the optimisation back in has the same results now, with and without that. But, of course, it should be. Will also post code.

I'm a bit sceptical about whether this is it though - the last b jump statement at the end of the GPIO_Init was basically jumping to itself I think (OK, I didn't work out the physical address, but stepping, it was stuck at that location. Never went back to main(). But I will try and see.

The debug crash has completely stopped since I took out the optimisation.

with flag not volatile and optimizing the compiler concludes  that flag never changes so the codes nothing but init IO and loop forever

seems to be correct and expected

 
The following users thanked this post: danmcb

Offline danmcbTopic starter

  • Regular Contributor
  • *
  • Posts: 128
  • Country: be
  • if it ain't bust, I didn't test it yet.
    • McBee Audio Labs
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #16 on: April 20, 2017, 02:00:29 pm »
you are absolutely right. With the flag volatile, it works, with optimisation.

Mea Culpa, and I hereby apologise to Gnu, Atollic,  B. Kernighan and D. Ritchie ;-)

Thanks for helping! (It IS good to know the *why* instead of just the *what*.)

« Last Edit: April 20, 2017, 02:06:02 pm by danmcb »
 

Offline TNorthover

  • Contributor
  • Posts: 42
  • Country: us
Re: STM32 interrupt source (edit : compiler optimisation flakiness)
« Reply #17 on: April 20, 2017, 02:15:04 pm »
you are absolutely right. With the flag volatile, it works, with optimisation.

You might want to consider C11 atomics instead, since this is more of an inter-thread communication issue than what volatile was designed for (memory-mapped IO basically). Volatile is probably safe for what you have so far though.
 
The following users thanked this post: danmcb, newbrain


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf