Skip to main content
Rub�n Acerete Halli
Associate II
February 23, 2017
Question

IWDG short period (125 us) problem

  • February 23, 2017
  • 7 replies
  • 5132 views
Posted on February 23, 2017 at 13:04

Hello,

We are developing a PV converter and we have choose an STM32F407VGT microcontroller in order to controlling its power electronics and communications. 

We are using the

in order to ensuring that the software works properly and if not reset the system and initialize in a safe state. Mainly stopping the PWM modules and stop triggering the Mosfets. We would like configuring the IWDG at minimum period (125us). We carries out the IWDG reset in a timer (TIM2) update event interrupt each 50us. For reseting de WDG we are using the HAL function HAL_IWDG_Refresh(&hiwdg). Following is the IWDG initialization code:

hiwdg.Instance = IWDG;

hiwdg.Init.Prescaler = IWDG_PRESCALER_4;

hiwdg.Init.Reload = 0;

if (HAL_IWDG_Init(&hiwdg) != HAL_OK)

{

  Error_Handler();

}

We have tested 3 different values for hiwdg.Init.Reload, 0, 1, and 2. If we use 0 or 1 the systems restarts continuously. If we use 2 the watchdog works, but four application the watching time is too long and produce that some converter components could explode. How can we configuring the IWGD in order to having a WD period of 125us as told in the manual reference?

#iwdg #stm-32 #stm32f407 #problem
This topic has been closed for replies.

7 replies

waclawek.jan
Super User
February 23, 2017
Posted on February 23, 2017 at 13:27

We carries out the IWDG reset in a timer (TIM2) update event interrupt each 50us.

Putting apart the question whether it's a good idea to kick the dog in an interrupt, are you sure it happens *every* 50us? Can you toggle an output an observe it using a logic analyzer, instead of kicking the dog?

JW

Rub�n Acerete Halli
Associate II
February 23, 2017
Posted on February 23, 2017 at 13:32

 ,

 ,

Yes we did it. The kick happens each 50 us we are monitoring the interrupt code with a GPIO.

De: waclawek.jan

Enviado el: jueves, 23 de febrero de 2017 13:29

Para: Rubén Acerete Halli <,racerete@fcirce.es>,

Asunto: Re: - Re: IWDG short period (125 us) problem

<,https://community.st.com/?et=watches.email.thread>, STMicroelectronics Community

Re: IWDG short period (125 us) problem

reply from waclawek.jan <,https://community.st.com/0D70X000006STu4SAG

AvaTar
Senior III
February 23, 2017
Posted on February 23, 2017 at 15:00

I'm not an expert in this field, but turning off H-bridges via watchdog (IWDG) seems not feasible to me.

Proper motor control (H-bridge control) driver peripherals use to have an emergency shutoff feature, with nanoseconds reaction time.

You never get at that level with software or interrupts.

Rub�n Acerete Halli
Associate II
February 23, 2017
Posted on February 23, 2017 at 15:32

I could be agree with you but for as if the IWDG works with 125us will be suitable and does not need additional external hardware. From de point of view of cost and space for our application it is important. Which you are proposing requires an external circuit.

AvaTar
Senior III
February 23, 2017
Posted on February 23, 2017 at 16:55

The hardware (motor control peripheral of the MCU) must have such an emergency-shutoff feature.

From de point of view of cost and space for our application it is important. Which you are proposing requires an external circuit.

To be brutally honest - then you get what you deserve. Software cannot do everything.

I have seen several device prototypes blowing up because of exactly such decisions by project management and / or HW design. But you are free to try, anyway.

Andrei Chichak
Lead
February 23, 2017
Posted on February 23, 2017 at 16:47

Wait, what? You're strobing the watchdog in a timer interrupt? That is exactly the situation that should never be used for a watchdog.

A watchdog is intended to reset the processor when your code screws up. So if your code is off doing something unexpected (infinite loop), the watchdog will fire and reset your processor.

If you put the strobe of the watchdog into a timer interrupt, your code can be completely broken and the timer will continue to tick, right on time since it is hardware, and the interrupt will fire and the watchdog will get cleared. EVEN THOUGH YOUR CODE IS BORKED!

A safer method is, in your super loop, do all of your calculations and finally strobe the watchdog. If any of your calculations cause the processor to miss its deadline, the processor gets reset.

The IWDG is a safety device to reset your processor, not to keep it running.

Second, the IWDG is based on an oscillator that has very poor frequency control. Not only is it 32000Hz, but it is 32768Hz, and 40000Hz, all at the same time. One of your machines may work correctly, but another will reset, just due to the variation in the oscillator. The 'I' in IWDG indicates that it runs independently of the rest of the processor, they don't share oscillators. That way the IWDG cannot get into lockstep with the processor and if there is a clock chain failure (due to executing data and reprogramming the clocks) the IWDG will still be able to reset the processor.

Rub�n Acerete Halli
Associate II
February 23, 2017
Posted on February 23, 2017 at 17:24

The real system is not so simple as I told in my previous explanation because there is a software mechanism that ensure that the rest of the code less priority than the interruption is working. Apart from the right use or not of the IWGD in my application, my real problem is that I resets the IWDG each 50us and when the IWDG period is configured at 125us and 250us seems that the watchdog reset does not works and the system restart. I am reseting the WD at the double of frequency than it works. I does not think that the internal clock could varies enough

to reach 80 kHz.

Furthermore I have just test to reseting the watchdog in the main loop with no more code something similar that:

int main(void){

   hiwdg.Instance = IWDG;

   hiwdg.Init.Prescaler = IWDG_PRESCALER_4;

   hiwdg.Init.Reload = 0;

   if (HAL_IWDG_Init(&hiwdg) != HAL_OK)

{

      Error_Handler();

   }

  while (1)

  {

      HAL_IWDG_Refresh(&hiwdg);

  }

}

It does not work. How can I configuring the IWGD for running as fast as possible?

waclawek.jan
Super User
February 23, 2017
Posted on February 23, 2017 at 17:33

What do you mean by 'it does not work'?

For such a minimal code, couldn't you simply drop Cube and write directly to registers?

JW

Rub�n Acerete Halli
Associate II
February 23, 2017
Posted on February 23, 2017 at 19:40

Sorry I have just remark that in the last results, the system clock was configured at 16MHz. I am going to repeate the tests with 168MHz but I think that from the point of view of the WD I will continue need reseting it 7 times faster. Is it normal?

Rub�n Acerete Halli
Associate II
February 23, 2017
Posted on February 23, 2017 at 20:08

Configuring the clock at 168MHz and doing the reset as fast as possible (5,56MHz each 219ns) and with    hiwdg.Init.Reload = 0, the system continuous restarting. With 

hiwdg.Init.Reload = 1 the system do a restart if I do not reset the IWDG at a frequency higer than 30kHz (each 33,3us).

Any one knows if this performance is normal?

Why the manual reference (

http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf

 ) in the page 712 sais that minimum timeout are 0,125us if it do not work?

Furthermore I have check too that the registers are right configured:

0690X00000606LoQAI.png
waclawek.jan
Super User
February 23, 2017
Posted on February 23, 2017 at 20:24

What hardware do you use?

If it's a custom board:

  • Is VDDA absolutely stable and connected/close to VDD?
  • All grounds properly connected?
  • Can you reproduce the problem on a Nucleo or Disco (or EVAL) board?

JW

Rub�n Acerete Halli
Associate II
February 24, 2017
Posted on February 24, 2017 at 08:52

The last tests have been done with a STM32F407VGT evaluation board even using 2 different boards.

AVI-crak
Senior
February 23, 2017
Posted on February 24, 2017 at 00:29

The timer IWDG shall be dumped in a cycle of a feedback loop of a contour of management. It is a general contour of management, its tasks include calculation of the current speed of rotation of an anchor of the engine, more precisely than its vector. The processor shall manage to execute this piece of a code till the moment when calculations are still urgent. If isn't in time - means there was an accident. Dumping of IWDG shall be program, start of an operation cycle of a feedback loop - on the timer.

Protection of power cascades is carried out at the level of simple logic, the more simply - the more reliably.

Rub�n Acerete Halli
Associate II
February 24, 2017
Posted on February 24, 2017 at 09:24

More or less this is the performand of the real code. But my problem is that I can not dump the IWDG when it is configures at 125us even if no more code is excuted. Only writing the register continuousli in the main to carry out the IWDG reload. 

AVI-crak
Senior
February 24, 2017
Posted on February 24, 2017 at 10:59

Then it is necessary to use more predictable mechanism of protection, on WWDG (a step from PCLK) + NMI_Handler ().

In this case there is a possibility of correct end of an emergency. Iron dumping - it isn't always ideal. Sometimes it is required to establish quickly legs мк in a necessary state which differs from dumping.

NMI_Handler () - all timers (except a dog) will automatically stop. It is impossible to work normally further already, it is necessary to finish correctly operation of the device + the ravine of an event on the independent carrier.

WWDG - a step from PCLK + normal interruption in which it is possible to finish accurately work of a cycle forcibly - transfer of a task to other prepared address, or in a forehead - start of an emergency task. For example the stop of the engine can lasts minutes and more. It is necessary to hold мк to a full stop of the engine, otherwise there can be problems.

It is simple to stamp a huge number of a code in interruption - it won't turn out. All environment is simpler to kill (this interruption very strong) - and to start only resolved. The stop of timers and installation of legs мк in a safe state is the simplest and bystry, remains in the interruption.
Rub�n Acerete Halli
Associate II
February 24, 2017
Posted on February 24, 2017 at 09:53

Hear is the Code wich fails I have remaked the relevant parts:

/* Includes ------------------------------------------------------------------*/

#include 'stm32f4xx_hal.h'

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

IWDG_HandleTypeDef hiwdg;

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

void Error_Handler(void);

static void MX_GPIO_Init(void);

static void MX_IWDG_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

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();

/* Configure the system clock */

SystemClock_Config();

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_IWDG_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_TogglePin (GPIOD,GPIO_PIN_12);

HAL_IWDG_Refresh(&hiwdg);

}

/* USER CODE END 3 */

}

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.LSIState = RCC_LSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 336;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 4;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

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_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)

{

Error_Handler();

}

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

/* IWDG init function */

static void MX_IWDG_Init(void)

{

hiwdg.Instance = IWDG;

hiwdg.Init.Prescaler = IWDG_PRESCALER_4;

hiwdg.Init.Reload = 0;

if (HAL_IWDG_Init(&hiwdg) != HAL_OK)

{

Error_Handler();

}

}

/** Configure pins as

* Analog

* Input

* Output

* EVENT_OUT

* EXTI

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

/*Configure GPIO pins : PD12 PD13 PD14 PD15 */

GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

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

* @param None

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler */

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

while(1)

{

}

/* USER CODE END Error_Handler */

}

#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

/**

* @}

*/

/**

* @}

*/