cancel
Showing results for 
Search instead for 
Did you mean: 

My code works when stepping in debug only, does not work in run mode

TombrownBottom
Associate III

I have an STM32F407 Discovery board. My project works fine using the dicovery board.

Now it is time to move it to my own PCB, using a STM32F405.

As a board "bring up" I tried to run a simple LED toggle program. When I flash the program I get a Download verified successfully message.

It does not work unless I step through it in debug mode. In run mode the output pin for the LED stays high. If I add a variable and increment it every time the LED toggles I can see it incrementing normally in debug mode.

I have an external resonator crystal at 8MHz. I can see it working at 8 MHz on the scope.

I have a 10K resistor pulling BOOT0 to ground. The two VCaps are present. A 10k resistor pulls NRST up to 3.3v rail.

All power and grounds ok with decoupling caps.

I have checked all settings in my .ioc file. Cant see any issues. (The settings are the same as for my discovery board program that works correctly).

Im sure one of you can help.

 

Thanks in advance...

1 ACCEPTED SOLUTION

Accepted Solutions

Need two delays otherwise it loops immediately and state changes over a handful of nanoseconds and you miss it. Add a delay in both states or use a scope.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

9 REPLIES 9

So code probably is running..

Your code would be only thing turning on 8 MHz

Instrument Error_Hander() and HardFault_Handler() so you know if it ends up there. 

Do you have a UART you can use? Different LEDs?

SysTick needs to be working for delays to function. You need a delay to see LEDs toggling.

Can you toggle a GPIO/LED from a TIM pin or TIM IRQ Handler?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi,

How do I implement: Instrument Error_Hander() and HardFault_Handler() so you know if it ends up there. 

Im using an oscilloscope to monitor the output pin, so no LEDS required.

Why do I need a UART?

I call HAL_Init(); in the main function so the Systick will be running.

Ive never done (toggle a GPIO/LED from a TIM pin or TIM IRQ Handler). I need help with this one.

>>Why do I need a UART?

So you have some idea what's going on inside the MCU without the debugger interfering?

>>How do I implement:

Perhaps by using __FILE__ and __LINE__ on the calling side so you can find where it came from, and print that out to a UART, or set a RED LED or something to alert you to failure.

This can be migrated to GNU/GCC

https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c

Step One is knowing that you died..

 

Also, you don't need to start the HSE, the MCU can continue running from the HSI is started running with.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for the help. This is where I run out of skill. This is too advanced for me. Maybe you could point me to some beginners literature to read?

What really is frustrating, is that this is a very simple program.

Could I have made a configuration error in the CubeIDE, the part where automated code generation takes place, define pins etc?

>>Could I have made a configuration error in the CubeIDE

I've got no visibility into anything you've done, or built.

You have BOOT0 set low, and have checked VCAP values, should see 1.25V there.

You can comment out the call to SystemClock_Config(); and the MCU should run fine, but slower

Illuminate one LED in Error_Handler(), the other in HardFault_Handler(), toggle in your primary loop w/delays

>>What really is frustrating, is that this is a very simple program.

Suggests the problem is pretty fundamental, as debugging works, likely faster execution or shorter time to run playing and issue.

Code is likely running, and then stuck in a while(1) loop somewhere.Trick here is to determine where, ideally by not being blind.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Here is my code:

 

 

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();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(Test_Pin_GPIO_Port, Test_Pin_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(Test_Pin_GPIO_Port, Test_Pin_Pin, GPIO_PIN_RESET);
x=x+1;
}
/* USER CODE END 3 */
}

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 72;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief GPIO Initialization Function
* @PAram None
* @retval None
*/
static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */



/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();



/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(Test_Pin_GPIO_Port, Test_Pin_Pin, GPIO_PIN_RESET);



/*Configure GPIO pin : Test_Pin_Pin */

GPIO_InitStruct.Pin = Test_Pin_Pin;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(Test_Pin_GPIO_Port, &GPIO_InitStruct);



/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}



/* USER CODE BEGIN 4 */



/* USER CODE END 4 */



/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}



#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @PAram file: pointer to the source file name

* @PAram line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t *file, uint32_t line)

{

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

 

 

Need two delays otherwise it loops immediately and state changes over a handful of nanoseconds and you miss it. Add a delay in both states or use a scope.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Today I have added some code to the error handler.

Aim: When in normal running mode, if an error is seen the error handler is called and sets a GPIO high.

Here is the code:

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

HAL_GPIO_WritePin(Error_GPIO_Port, Error_Pin, GPIO_PIN_SET);

}

/* USER CODE END Error_Handler_Debug */

}

Here is the code:

I can report that the pin never goes high.

 

 

 

I am worried that this stays low because it suffers from the original problem,

that is, all my GPIOS dont operate in run mode. Help!

 

 

Thanks for correcting the school boy error.