2022-07-15 01:03 PM
I am just about finished with my application I have been working on for a few months.
The processor is a STM32G051K8T and I have upgraded to STMCubeIDE 1.10.1 and am using the ST-LINK V2 (Blue pill) with my custom board.
All of a sudden it is hanging up in the main program.
At first it hung up in the middle of a sprintf() statement.
The statement was
char buf[120];
sprintf(buf,"Calibration Factor: %lu\r\n",ADC1->CALFACT); // dies on this statement
print_debug_str("Hello World\r\n");
char buf[120] was originally char buf[40] but I made it longer in the unlikely case it was overrunning the buffer. Made no difference.
I changed "ADC1-CALFACT" to "16l" or "(uint32_t) 16" made no difference. it just hung on that command.
Since I new sprintf probably used the heap, I went into STM32G051K8TX.ld to maje the minimum heap 0x300 from 0x200. And it made no difference.
My first thought was it is happening at a certain memory location. So I put 100 __NOP(); statements before the code that had the sprintf() in it. Did not matter, it still hung up on the sprintf()
I commented out the sprintf() statement and changed the print_debug_str(buf); to
print_debug_str("Hello World\r\n"); and it hung up in the print_debug str() routine.
void print_debug_str(void * s)
{
static uint8_t db[256];
volatile uint32_t i = 0;
volatile uint32_t j;
uint16_t len = strlen(s);
while (UART1Busy) i++;
memmove(db,s,len);
UART1Busy = true;
for (j=0;j<2500;j++) i++; // now stopping here
HAL_UART_Transmit_DMA(&huart1,db,len);
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
UART1Busy = false;
UNUSED(huart);
}
That made me wonder if it was not memory based but time based.
So I put the 100 __NOP(); in a for loop;
{
uint16_t i;
for (i=0;i<30000;i++)
{
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 20
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 40
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 60
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 80
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 100
}
}
Now it stops in this code before the sprintf() statement.
I am now guessing it is a time issue. It happens at a certain time.
I have never setup the watchdog timer and I do use three timers (TIM2, TIM3, TIM14) later in the program. So just incase they are now not working like they used to, I decided to comment them out, which caused a warning about the routines not being called.
Here is the current version of the code. Until it breaks:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_I2C1_Init();
//MX_TIM2_Init();
//MX_TIM3_Init();
//MX_TIM14_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
/*
ENCODER_POWER_OFF; // Make sure encoder is off so it can start correctly.
print_debug_str("Encoder Power Off\r\n");
TASK_PIN_L;
TP2_L;
DIO2_L;
DIO3_L;
DIO4_L;
if (isDebug(DEBUG_verify_memory_structures))
{
verify_memory_structures();
}
*/
__NOP();
{
uint16_t i;
for (i=0;i<30000;i++)
{
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 20
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 40
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 60
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 80
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 100
}
}
//ADC_init();
__NOP();
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
{
print_debug_str("Did not calibrate right!\r\n\r\n");
}
else
{
char buf[120];
sprintf(buf,"Calibration Factor: %lu\r\n",ADC1->CALFACT); // dies on this statement
//sprintf(buf,"Calibration Factor: %lu\r\n",(uint32_t) 0xA5A5A5A5); // dies on this statement
print_debug_str(buf);
}
Maybe I need to explain what happens.
I run the debugger to the __NOP(); on line 55 where I have a break point, I also have a break point at the __NOP(); on line 69. When I tell it to Resume after the first breakpoint, it never returns and breaks at line 69.
Suspend does not appear to really work. It goes off and resume turns on, but I cannot examine variables. When I try to look at i it says "Error: Multiple errors reported.\ Failed to execute MI command: -var-create - * i Error message from debugger back end: -var-create: unable to create variable object\ Unable to create variable object"
trying the reset button the resume button goes out, and the suspend button lights up, but it does not go back to the beginning of main() like normal,
As a result, I have to use the Terminate button to leave the debugger, then Run -> Debug to get back into the debugger.
I upgraded to STM32CubeIDE 1.10.1 recently. Is this one of those known problems for ST in this version?
Did version 1.10.1 turn on something like the watchdog timer by default?
Any suggestions how to get past this? This has been working everyday for the past 2-3 months.
I have attached the whole main.c code so you can see how the peripherals were setup before this code was executed.
I am at a loss as to what happened. This was working. Could have something happened to the processor? I do not want to swap processors if I do not need to.
Thanks,
Kip
Solved! Go to Solution.
2022-07-18 11:41 AM
stm32??xx_it.c is for me it file.
In your mx you call
/* USER CODE BEGIN I2C1_Init 2 */
initI2C();
/* USER CODE END I2C1_Init 2 */
but source dont show etc. All code started before your hang can produce it.
For example you rencoder power off is called before nop test in main and start DMA.
In parallel main continues to your test and maybe hangs because DMA etc.
2022-07-18 12:28 PM
Around iteration 155 it stops responding. I am pretty sure it is the SysTick interrupt. I have a breakpoint in the interrupt and it does not break in the interrupt.
If I comment out the initialization of the SysTic in the HAL_Init the problem does not happen.
HAL_StatusTypeDef HAL_Init(void)
{
HAL_StatusTypeDef status = HAL_OK;
/* Configure Flash prefetch, Instruction cache */
/* Default configuration at reset is: */
/* - Prefetch disabled */
/* - Instruction cache enabled */
#if (INSTRUCTION_CACHE_ENABLE == 0U)
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
#endif /* INSTRUCTION_CACHE_ENABLE */
#if (PREFETCH_ENABLE != 0U)
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE */
/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */
if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
{
status = HAL_ERROR;
}
else
{
/* Init the low level hardware */
HAL_MspInit();
}
/* Return function status */
return status;
}
When I comment out lines 19-23 I do not have a the debugger crash.
2022-07-18 12:29 PM
Here is what my code looks like at the moment:
/* USER CODE END 0 */
/**j
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/*
{
uint16_t i, j;
for (i=0;i<525;i++)
{
for (j=0;j<60000;j++) __NOP();
}
}
*/
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
//SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
// MX_GPIO_Init();
// MX_DMA_Init();
// MX_ADC1_Init();
// MX_I2C1_Init();
// MX_TIM2_Init();
// MX_TIM3_Init();
// MX_TIM14_Init();
// MX_USART1_UART_Init();
// MX_USART2_UART_Init();
/* Initialize interrupts */
// MX_NVIC_Init();
/* USER CODE BEGIN 2 */
//__disable_irq();
/*
ENCODER_POWER_OFF; // Make sure encoder is off so it can start correctly.
print_debug_str("Encoder Power Off\r\n");
TASK_PIN_L;
TP2_L;
DIO2_L;
DIO3_L;
DIO4_L;
if (isDebug(DEBUG_verify_memory_structures))
{
verify_memory_structures();
}
*/
__NOP();
{
uint16_t i;
for (i=0;i<157;i++)
{
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 20
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 40
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 60
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 80
__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // 100
if (i == 151)
{
__NOP();
}
}
}
//ADC_init();
__NOP();
2022-07-18 02:03 PM
Somehow I missed your input.
I thought the sprintf type of routines needed the heap for space to do the formatting. That is good if they do not. I think heap is a bad idea for an embedded system.
The ST-LINK-V2 is plugged directly into my laptop. No hub or cable in between.
I am just used to uint16_t for loops because I have spent so many years on 16-bit processors. And the sprintf lets you use %u as opposed to %lu. to show the variables.
I do not know what a Hard Fault Handler is or where to put it. Can you send me a link for more info?
I am using just under 30% of my RAM. So I should have plenty of stack if ST starts the stack at the top of memory and puts variables at the bottom. I increased the minimum stack by 0x100. I am not using the heap, but they have a default heap length.
Al that is good except this happens at the very beginning of the program before I call any of my routines. Right now I am just doing HAL_Init() and looping on 100 __NOP(); statements about 152 times and it crashes. No other calls. No use of the stack except for the uint16_t i; used in the loop variable. No heap. No other initializations.
And it crashes at what I believe is a call to SysTick_Handler() interrupt. It makes the debugger unusable except to terminate. And restart. I cannot pause and look at variables or anything once it crashes.
I tried single stepping and it just stops single stepping with no message in the debugger.
If I comment out the SysTic_Init the problem goes away. If I disable interrupts the problem goes away. That makes me think it is the SysTick_Handler() interrupt. But it never enters it, or the debugger does not stop at the breakpoint.
2022-07-20 06:30 AM
With help from KnarfB and Piranha we finally figured out the issue in another question.
To make a long story short KnarfB noticed in one of my debugging logs that PC was wrong.
Download verified successfully
------ Switching context -----
COM frequency = 4000 kHz
Target connection mode: Under reset
Reading ROM table for AP 0 @0xf0000fd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V2J40S7
Device ID: 0x456
PC: 0x1fff1654
And that was in system memory not flash.
So somehow the fuses got changed. I had to load the STM32CubeProgrammer and it lets you change the fuses. Unfortunately that did not work.
Piranha noticed the fuse descriptions in the Programmer were wrong and sent me to the right place in RM0444 Paragraph 2.5, Table 8. I set the fuses based on that info and it started working. And the PC was in the right memory space.
Download verified successfully
------ Switching context -----
COM frequency = 4000 kHz
Target connection mode: Under reset
Reading ROM table for AP 0 @0xf0000fd0
Hardware watchpoint supported by the target
ST-LINK Firmware version : V2J40S7
Device ID: 0x456
PC: 0x8006398
Thanks all for the help.