cancel
Showing results for 
Search instead for 
Did you mean: 

IWDG with long timeout

TConl.1
Associate II

Hi everyone, I'm writing a program for a STM8L152R8 that sends data over UART to another mcu that should respond to me though I have a timeout on the transaction of five seconds using timer 4. I'd also like to include a watchdog however the max timeout we can get with IDWG is 1.7s.

What would be the best approach here to ensure the watchdog doesnt reset the system while waiting for a UART response?

It's a similar question to https://community.st.com/s/question/0D50X00009Xka0TSAR/watchdog-timer-problem however I feel the last question in this thread is very important and unanswered though.

Thanks for the help.

1 ACCEPTED SOLUTION

Accepted Solutions

I cannot see what is behind some of the function names, so I am assuming.

The feed_watchdog() in the while loop looks dangerous, I would call it only on a trigger event.

Further assuming a watchdog period of 1 second, I would set up a counter (e.g. with value 5), decrement it in the timer interrupt, and set a WD trigger flag (and set the counter back to 5).

The main loop feeds the watchdog upon the flag. A safety factor of 2 should suffice.

You might need to read the IWDG spec carefully, how you are supposed to feed it. Windowed WDGs will trigger if fed too early.

This looks dangerous as well:

send_uart_message() {

while (waiting_for_uart);

A busy-wait ?

I used to handle asynchronous communication separate from any main code, mostly using interrupts.

Transmission via TxE, which needs to be disabled before sending the last character (and thus enabled when initiating a transmission).

Reception via RxNE interrupt. The respective handler buffers Rx data, and again sets a flag if an end-of-message character is received (e.g. '\n').

The main loop processes Rx data upon said flag. You might need to copy the Rx data, or else the might get overwritten by new characters/messages.

View solution in original post

7 REPLIES 7
Ozone
Lead

Either organise your code in a way that the WDG is triggered regularly even when waiting for a response, or do not activate the WDG until you need it.

I don't have experience with the IWDG of the STM8, but assume it is similar to STM32 - once activated, it cannot be turned off again.

But organising your code with UART interrupts and timer interrupts so that both can be served quasi-simultaneously is not hard.

TConl.1
Associate II

Thanks @Ozone​  . For 'organise your code in a way that the WDG is triggered regularly even when waiting for a response' if i do this there is no way to distinguish an actual hang here though is there? Yes i have timer and uart interrupts that can detect if the response comes or not but if this gets clobbered in any way I'd like to have a watchdog that can reset things

Not easy to understand exactly what you mean.

But a WDG (including the IWDG) will reset the MCU, i.e. the whole application including RAM initalisation.

A WDG is not intended as device to regularly rely upon in your code, but only a measure of last resort.

I don't know how your code is organized, but I assume a kind of while(1) main loop that processes regura tasks sequentially.

Your timer (interrupt) should update time time base, and create the events (counter values) that trigger the IWDG write and the duration of the response timeout.

Both counter values could be separate.

Thanks for all the help @Ozone​ but i'm not sure were on the same page. I'll share a structure of my code which might help.

//main loop
//event_happened is set in exti interrupt
while(1) {
	if (event_happened) {
		send_uart_message();
	};
	feed_watchdog();
}
 
send_uart_message() {
	while (waiting_for_uart);
	//send message code
}
 
//timer every 100ms for uart and other timeouts
timer_interrupt() {
	waiting_for_uart += 1;
	if (waiting_for_uart == 50) {
		discard_transaction();
		go_to_next_transaction();
	}
}

I need to be able to distinguish between actually waiting for a uart response and a hung system which I can't see how to do with a IWDG timeout less than the uart timeout.

I cannot see what is behind some of the function names, so I am assuming.

The feed_watchdog() in the while loop looks dangerous, I would call it only on a trigger event.

Further assuming a watchdog period of 1 second, I would set up a counter (e.g. with value 5), decrement it in the timer interrupt, and set a WD trigger flag (and set the counter back to 5).

The main loop feeds the watchdog upon the flag. A safety factor of 2 should suffice.

You might need to read the IWDG spec carefully, how you are supposed to feed it. Windowed WDGs will trigger if fed too early.

This looks dangerous as well:

send_uart_message() {

while (waiting_for_uart);

A busy-wait ?

I used to handle asynchronous communication separate from any main code, mostly using interrupts.

Transmission via TxE, which needs to be disabled before sending the last character (and thus enabled when initiating a transmission).

Reception via RxNE interrupt. The respective handler buffers Rx data, and again sets a flag if an end-of-message character is received (e.g. '\n').

The main loop processes Rx data upon said flag. You might need to copy the Rx data, or else the might get overwritten by new characters/messages.

Thanks @Ozone​ ! I've taken youre advice on setting WD trigger flags in the sections of my code and using a counter and timer interrupt to get the longer timeout.

And I'm going to rework the UART to a seperate task queue to avoid the busy wait as you pointed out is bad practice. I already use innterrupts to handle reception and copy to a buffer however the reason why i was blocking was so that I knew the response I recieved correlated to the last command sent.

Thanks for the help!

> TxE, which needs to be disabled before sending the last character

It doesn't need such a restriction. When TIEN is disabled, the interrupt is not generated regardless of TXE state.