Author Topic: STM32G0 freezes over time  (Read 7993 times)

0 Members and 1 Guest are viewing this topic.

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #25 on: December 28, 2023, 05:22:34 pm »
Toggle a LED in the SysTick ISR, another in the main loop.
If both stop completely it probably got a Hardfault, but if the systick led keeps working it's probably caused by you code being stuck somewhere by something you didn't account for.
In any case the debugger will show it instantly.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: Veketti

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8173
  • Country: fi
Re: STM32G0 freezes over time
« Reply #26 on: December 28, 2023, 05:41:21 pm »
If both stop completely it probably got a Hardfault

I always write a hardfault handler (and busfault, and the others) so that I don't need to guess. Something as simple as blinking an LED for 3 times for hardfault, 4 times for busfault, 5 times for "invalid handler" (to which all interrupt vectors are initialized to by default), instead of the "silent" while(1) loop. Doesn't take many minutes to write and you can reuse them across projects.
 
The following users thanked this post: thm_w, newbrain, Veketti, harerod

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #27 on: December 28, 2023, 06:14:40 pm »
That's also a very simple yet efficient approach, but my money is in a while(not_done) for the reasons I said earlier.
99.99% something is wrong around the UART code!
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #28 on: December 29, 2023, 07:54:19 am »
@ntnico
Much has happened in the meantime. I revised the power supply layout according to ArdWar’s comments. However there was no mention about issues with decoupling so didn’t touch that side.

@temperance
Good point. I noticed I missed the 100nF capacitor from the NRST pin which should filter out EMC resets. However any layout I’ve found does not include external pullup/pulldown resistors for NRST, SWDIO & SWCLK. It’s confusing, do they need or not?

@Everyone
I basically redesigned the PCB with the improvements I mentioned above. Also changed the display type from HD44780 parallel to SSD1306 and added HM-10 BTLE and noticed I ran out of flash & pins so I upgraded the MCU to STM32G070CBT6 which I recently ordered plenty of. I also added led to the new design so I could use that to indicate any error handler faults etc.

I also changed the uart communication from interrupt to direct and added the IWDG with 10 seconds timeout. Device goes to sleep in case no CO detected for five seconds and takes read and goes back to sleep. Now it has kept running for several days without freeze. Wakes up every day, when I burn some wood in the stove (commercial meters don’t even react yet). I don’t know whether it was the uart IT which was causing the freeze or what.

I’ve been also thinking my head around to save the energy on this. Now it draws 7.5mA with the display turned off which with AA batteries will last bit over a week. ZE07 sensor has heating time of 60 seconds so I cannot power it off every five seconds and have a read. It draws 4.5mA just doing nothing. I think I have no other possibility than add manual switch and power it on when I decide to burn some wood in the stove. Other times keep it turned off. The other approach I’ve been thinking is big LiPo battery and USB C charging module and plug it in every other week or so..

Sorry to ask again stupid questions, most likely this is also mentioned in some documentation which I haven’t found but do I need to declare these SWDIO and SWCLK pins like this or leave them at reset state? Before they were left to reset state and the debugging and programming worked ok. Maybe this way I don't need to remove the analog declaration each time I generate the code from these pins? What else might it do?
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #29 on: December 29, 2023, 11:30:10 am »
By default they're set to SWD but HAL might change them if Serial Wire isn't enabled under SYS tab.
Only required if you want to attach a debugger.

nRST has an internal pullup, read the RM.
A failure here would reset your system, not freeze it.

If you have to wait 60 seconds for the sensor, set LSI, start a low power timer and go to sleep, let the timer wake the system when it's over.

Are you enabling compiler optimizations? Set it to size optimization and you'll see a huge gain.

Are you using u8g2 for the oled?
If so and you're using large fonts, there're tools to make your own fonts, adding only the required chars, this saves a lot of memory, see this.
« Last Edit: December 29, 2023, 11:37:09 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #30 on: December 29, 2023, 11:52:58 am »
I enabled the "optimize for size" like you earlier suggested and it helped a lot. Otherwise I would have ran out of flash way earlier..  :phew:

For the SSD1306 I'm using https://github.com/afiskon/stm32-ssd1306 library which is based on 4ilo's library.
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #31 on: December 29, 2023, 12:12:13 pm »
Also your code seems to be pretty simple, maybe go LL and save more space?
Is it a commercial project or just for your own? That mcu might have double the flash like so many stm32.
The STM32G050F6 has DIE456, which means it's very much the same as all these, 99.99% it has 64Kb flash and can be unlocked, see this.

Quote
DIE456  STM32G050C6Tx
DIE456  STM32G050C8Tx
DIE456  STM32G050F6Px
DIE456  STM32G050K6Tx
DIE456  STM32G050K8Tx
DIE456  STM32G051C(6-8)Tx
DIE456  STM32G051C(6-8)Ux
DIE456  STM32G051F(6-8)Px
DIE456  STM32G051F8Yx
DIE456  STM32G051G(6-8)Ux
DIE456  STM32G051K(6-8)Tx
DIE456  STM32G051K(6-8)Ux
DIE456  STM32G061C(6-8)Tx
DIE456  STM32G061C(6-8)Ux
DIE456  STM32G061F(6-8)Px
DIE456  STM32G061F8Yx
DIE456  STM32G061G(6-8)Ux
DIE456  STM32G061K(6-8)Tx
DIE456  STM32G061K(6-8)Ux
« Last Edit: December 29, 2023, 12:17:29 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #32 on: December 29, 2023, 12:37:13 pm »
Hmm, interesting, 64kB would be plenty. Maybe I'll test that some time. However I accidentally while back ordered 40 pcs of the 128kB STM32G070CBT6 from LCSC due to first time ordering there and not checking how they multiply strangely the amount, so I think those will last for my personal projects for the rest of my life.  :-DD
This is just my hobby, I used to challenge myself to do the devices I can't find exactly what I'm looking for, so nothing commercial here.
« Last Edit: December 29, 2023, 12:41:08 pm by Veketti »
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #33 on: December 29, 2023, 12:46:38 pm »
So hobby & hacking it is! :)
Try u8g2, you might be surprised. Also I recall the font structure having some kind of data compression? Not sure!
I'm using it in a project with the HK32F030, also LL libs, it's only using 13KB of flash.
Though I'm using only one small font (u8g2_font_6x12_tr), a 0.91" 128x32 display can't display much :).
« Last Edit: December 29, 2023, 12:56:43 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #34 on: December 29, 2023, 04:25:18 pm »
I ported the custom LCD lib (Using u8g2) I was using for HK32/PY32 to STM32G0.
Works in my STM32G030.
Using LL, everything takes less than 8KB, including initialization, drawing routines, 9x15 font, test program...
1KB RAM is used for the local oled buffer (It's much better this way).

u8g2 is huge, so the files are too large to post here (10MB), uploaded to my Google drive.
(Oops minor bug in the example, updating screen twice, so it reported half the speed. Ensure your file timestamp is 18:12 or download again).

As you'll see I do my own OLED initialization instead using some existing u8g2 profile, I prefer it like that to make it easier to modify, also u8g2 has a thousand profiles I don't feel like trying until finding the correct one.
I just copied the display test from the STM32 soldering FW and modified it slightly.
PB0 is a led, will blink slowly is ok, fast if the display was not detected.
The good about CubeMX is you can remap any pin easily, just choose any other pin and name it "LED".
Other pins are mostly explained in display.h.

It uses Fast Mode (400KHz), this gives about 35FPS, you can try setting it to Fast Mode Plus (1MHz) for about 80FPS.
Worked for me but will heavily depend on the display, wires/traces and pullup resistors (If not working, replace the default 10K with 2K2 or 1K).

« Last Edit: December 30, 2023, 03:05:07 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: bingo600, thm_w, Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #35 on: December 29, 2023, 10:10:26 pm »
I ported the custom LCD lib (Using u8g2) I was using for HK32/PY32 to STM32G0.
Works in my STM32G030.
Using LL, everything takes less than 8KB, including initialization, drawing routines, 9x15 font, test program...
1KB RAM is used for the local oled buffer (It's much better this way).

u8g2 is huge, so the files are too large to post here (10MB), uploaded to my Google drive.
(Oops minor bug in the example, updating screen twice, so it reported half the speed. Ensure your file is timestamp is 18:12 or download again).
...

Thank you so much, I'll try that.

I always write a hardfault handler (and busfault, and the others) so that I don't need to guess. Something as simple as blinking an LED for 3 times for hardfault, 4 times for busfault, 5 times for "invalid handler" (to which all interrupt vectors are initialized to by default), instead of the "silent" while(1) loop. Doesn't take many minutes to write and you can reuse them across projects.

This is interesting, I'd like to try similar approach. Would you mind opening bit, how did you do that? Is it using timers for the LED blink? Like in error handler case for different HAL statuses and then call separate function for led blink and pass the times to it and start timer and blink the amount? Or in error handler just Hal_Delay_ms() and toggle pin state? Or something else? As I'm not sure what works in the fault state..
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #36 on: December 29, 2023, 11:14:18 pm »
A hard fault is a terminal, top priority interrupt, no other interrupts are allowed, so normally you'll make a software delay based in a for() loop or similar.
However you can still poll the SysTick timer, as it will keep running in the background:
Code: [Select]
void HardFault_Handler(void) {
  while (1)  {
        LED_GPIO_Port->ODR ^= LED_Pin;
        LL_mDelay(20);     
  }
}

From LL libs (Cleaned up):
Code: [Select]
#define LL_MAX_DELAY                  0xFFFFFFFFU   /* Max delay can be used in LL_mDelay */

void LL_mDelay(uint32_t Delay)
{
  SysTick->CTRL;                                    /* Clear the COUNTFLAG first */
  if (Delay  < LL_MAX_DELAY)                        /* Add a period to guaranty minimum wait */
    Delay ++;
  while (Delay  != 0U) {
    if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
      Delay --;
  }
}
« Last Edit: December 30, 2023, 02:42:54 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: Veketti

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8173
  • Country: fi
Re: STM32G0 freezes over time
« Reply #37 on: December 30, 2023, 08:47:19 am »
Is it using timers for the LED blink?

Just something super simple like this:
Code: [Select]
void hardfault_handler()
{
    RCC->... // enable GPIO ports, in case some other code disabled them or hardfault triggered before init
    GPIO->... // configure LED pin as output, for the same reason
    while(1)
    {
        for(int cnt=0; cnt<5; cnt++)
        {
            GPIO->BSRR = ... // turn LED on
            delay_simple(1000);
            GPIO->BSRR = ... // turn LED off
            delay_simple(1000);
        }
        delay_simple(2000);
    }
}

Code: [Select]
static void delay_simple(uint32_t i)
{
i *= 1024; // some random multiplier you experimentally find so that delay is suitable for the intended purpose, for the eye.
                   // depending on what the clock configuration registers happen to be at the time of fault, it might blink faster or slower,
                   // but will be visible
while(i--)
__asm__ __volatile__ ("nop");
}


Hardfault handler by definition cannot be pre-empted by any other interrupt source, but if you use same kind of terminal led blinker functions for other purposes, then you might want to make them disable the interrupts as the first thing.
« Last Edit: December 30, 2023, 08:50:33 am by Siwastaja »
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #38 on: January 10, 2024, 03:15:31 pm »
Update to this. I got new pcb's where I implemented led and added Error_Handler and HardFault_Handler led control. It seems it gets to the HardFault_Handler. Now even more, when the display is changed to be i2c ssd1306 variant. Sometimes it works and sometimes not. I need to study how to find out how can I see what was the command that caused the hardfault..
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: STM32G0 freezes over time
« Reply #39 on: January 10, 2024, 03:42:53 pm »
what was the command that caused the hardfault..
Follow ataradov's advice in  Reply #2: attach a debugger and look at the stack trace.
The trace will tell you where the hard fault was generated and any decent IDE will bring to the exact spot in the code.

But the same advice was repeated many times in the thread, is there a reason this is not possible?
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: Veketti

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8173
  • Country: fi
Re: STM32G0 freezes over time
« Reply #40 on: January 10, 2024, 04:53:31 pm »
With a debugger, you would look at Hardfault Status Register and others. If there is some actual reason not to use a debugger, you can just print those interesting registers to UART as well in your hardfault handler (make it an infinite loop which prints every second so that you don't miss the printout when it happens). You want to look at the content of HFSR, which reveals if this was an actual hardfault, or some other fault escalating into hardfault. You can usually find the address where the problem occurred in, and then, for example using arm-none-eabi-objdump list the symbols to find the function name this piece of code resides in, or disassemble (still with objdump) the code to find the exact instruction. All of this is of course somewhat quicker in an IDE&debugger once you have it set up.

Read this great tutorial: https://interrupt.memfault.com/blog/cortex-m-hardfault-debug
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #41 on: January 10, 2024, 07:08:33 pm »
Odd thing is that this seem to cause hardfault:
HAL_GPIO_WritePin(DISP_PW_O_GPIO_Port, DISP_PW_O_Pin, GPIO_PIN_RESET);

But this doesn't:
HAL_GPIO_WritePin(GPIOB, 13, GPIO_PIN_RESET);

 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11261
  • Country: us
    • Personal site
Re: STM32G0 freezes over time
« Reply #42 on: January 10, 2024, 07:21:31 pm »
How are DISP_PW_O_GPIO_Port and DISP_PW_O_Pin defined?

Also, disassemble both versions of the code and see what is the difference. It is possible that HF is not related to that code specifically, but the change in size moves something else in the address space.

Get a debugger and read the top 8 words of the stack when HF happens, it will tell you the exact PC value at the time of fault.
Alex
 
The following users thanked this post: Veketti

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: STM32G0 freezes over time
« Reply #43 on: January 11, 2024, 08:37:20 am »
You want to look at the content of HFSR, which reveals if this was an actual hardfault, or some other fault escalating into hardfault.

The STM32G0 series is a Cortex M0+, so the exception model is much simpler than the one in M3..7: there is only Hard Fault, and no detail registers, no cases where the (hard) fault is "imprecise", AFAIR.

It should be much easier to debug as the stack trace is more or less the only valuable piece of information, and the debugger/IDE can easily unravel it, though one lacks the details available with the more advance cores.
If the OP is using an RTOS, they should be aware of the MSP/PSP distinction, good IDE and debug servers are RTOS aware.
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: Siwastaja, Veketti

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: STM32G0 freezes over time
« Reply #44 on: January 11, 2024, 09:02:36 am »
If your DISP_PW_O_GPIO_Port is something like-
    #define DISP_PW_O_GPIO_Port GPIOB
then there is really nothing that could cause a hard fault using the same port (address).

The other two arguments could literally be anything, and the worse that can happen is you get the wrong bitmask and/or apply it to the wrong register (but still bsrr or brr), not a hard fault.

If your define is something else, then all bets are off. The function takes a GPIO_TypeDef*, and if not actually a gpio port address, then you will be writing somewhere not intended (for some reason the stm32 hal does not assert_param the port parameter, which is the most important thing to check in this function). You also have to enable the port in RCC, so if you somehow missed that you would get a fault of some kind, although if you were using the same define to init its pins you would run into a problem there first if the define was wrong.

How about telling this thread what you have available for debugging? If you do not have a debugger, at least no one has to repeatedly suggest using the debugger to help with your problem(s). There are ways to do without, but if you are already in an ide and are already using a programmer/debugger then its just a matter of learning how to use it.

I have a stm32 nucleo with g031 using command line only (not using gdb either), and have a small chunk of ram set aside in the linker script to store debug data. The startup file has an error function that runs for all unhandled exceptions, in which it stores the 8 words of stack data and any other useful info, then resets. When problems arise, the main function can check for sw reset, and dump out the 'debug' ram to the uart in use. Most problems seem to be beginner mistakes, and once you get familiar with the mcu you start to figure out what makes things break.

edit- I forgot to add, other mcu's I have using an ide w/ programmer/debugger are usually simpler/faster when odd problems arise, so although doing without is workable its not ideal.
« Last Edit: January 11, 2024, 10:00:51 am by cv007 »
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #45 on: January 11, 2024, 02:13:47 pm »
Definition for the DISP_PW_O is as follows from gpio.c:
Code: [Select]
  /*Configure GPIO pin : PtPin */
  GPIO_InitStruct.Pin = DISP_PW_O_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DISP_PW_O_GPIO_Port, &GPIO_InitStruct);

I'm starting to think that there is something very badly wrong with this setup. Could it be that the project has corrupted in cubeIDE? One thing fixed another mess up and causes hardfault. Now HAL_Delay causes hardfault and gets stuck in following:
Code: [Select]
__weak uint32_t HAL_GetTick(void)
{
  return uwTick; <- Stuck here
}

Or could the mcu be bad? Maybe I'll start new fresh project and copy the code between /*user code*/ from this and see whether that works. And maybe solder another pcb if the mcu is bad..
 

Online DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5912
  • Country: es
Re: STM32G0 freezes over time
« Reply #46 on: January 11, 2024, 02:29:13 pm »
I don't think so. Those are not the definitions, cubeMX places then in main.h.
« Last Edit: January 11, 2024, 04:24:58 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #47 on: January 11, 2024, 04:23:19 pm »
Yes, sorry. From main.h
#define DISP_PW_O_GPIO_Port GPIOB

I've been using that DISP_PW_O in other parts of the code as well. For example just before that pin write I check whether the pin is set or not:
Code: [Select]
if ( (HAL_GPIO_ReadPin(DISP_PW_O_GPIO_Port, DISP_PW_O_Pin)) == 1 )
And, sorry I missed to tell that I have the ST Link/V2 as a debugger connected to the board.

Does the following picture tell that what went wrong?
« Last Edit: January 11, 2024, 05:13:00 pm by Veketti »
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11261
  • Country: us
    • Personal site
Re: STM32G0 freezes over time
« Reply #48 on: January 11, 2024, 05:12:03 pm »
Your screenshots show LED_GPIO_Port, not  DISP_PW_O_GPIO_Port.

You need to find out the value of SP at the time of fault and then read the memory contents at that address. No idea how to do that with GDB.

Then 7th word from the top of the stack would contain the program counter of the instruction that caused this fault. Then you look at the disassembly and check what is at that address. Then you will know what other things to check.

Full stack would contain: r0, r1, r2, r3, r12, lr, pc, psr. Since you are stopped at the beginning of the HF handler, you can do a sanity check and verify that r0-r3 in the CPU registers and on the stack are the same. This will verify that you have the correct stack location.

Don't trust any symbolic names IDE tells you. Read the values from the registers and verify independently with the disassembly/map file. IDEs are easily confused when things go wrong.

When IDE tells you that you have a hard fault, verify that PC is at the location of the HF handler.
« Last Edit: January 11, 2024, 05:15:42 pm by ataradov »
Alex
 
The following users thanked this post: Veketti

Offline VekettiTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: fi
Re: STM32G0 freezes over time
« Reply #49 on: January 11, 2024, 05:18:33 pm »
I updated the previous post. I added also led on and breakpoint to NMI_Handler. It seems to go sometimes to the NMI as well. I added also picture of that.
When I press the button "View Disassembly...", nothing happens. Any idea why is it so?

That LED_GPIO_Port is from the fault handler where I lit up the led if it goes there.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf