Hi everybody!
If the watchdog is set to interrupt mode, what happens if the execution hangs in another interrupt?
The counter will expire, and triggers the watchdog interrupt, right? But can this interrupt be serviced?
Thanks,
Monica
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi everybody!
If the watchdog is set to interrupt mode, what happens if the execution hangs in another interrupt?
The counter will expire, and triggers the watchdog interrupt, right? But can this interrupt be serviced?
Thanks,
Monica
Hi Monica,
Yes. The WDINT can be serviced. But you have to allow the WDINT to interrupt to interrupt this other ISR. Typically when an interrupt is being serviced, the CPU disables IER so that no further interrupts can occur. (Not exaclty "OCCUR". They can occur but they will not be serviced till the current ISR execution has been completed). After servicing the current interrupt the CPU restores the IER.
So to enable one ISR to interrupt another ISR you have to explicitly enable it within the current ISR.
for eg. to Allow watchdod interrupt inside Timer Interrupt do this:
Timer_0_ISR()
{
DINT;
IER |= M_INT1; // Enable WD group within this ISR
PieCtrlRegs.PIEACK.all = 0xFFFF; // Allow all interrupts at the PIE level by acknowledging it
EINT;
// Timer_0_ISR body
{}
}
Vivek
Vivek is right, you can configure to get watchdog interrupt from another interrupt.
Did you already track down the instruction which triggers illegal ISR?
-Manoj
Hi!
I had this in my code:
interrupt void xint1_isr()
{
DINT;
IER |=M_INT1; // Enable WD group within this ISR
PieCtrlRegs.PIEACK.all = 0xFFFF; // Allow all interrupts at the PIE level by acknowledging it
EINT;
....
GpioDataRegs.GPASET.bit.GPIO20 = 1;
loop=0;
while(GpioDataRegs.GPADAT.bit.GPIO20 != 1 ) // Wait for CS1 to go 'H'...
{
loop++;
if(loop>=200)
{
SetCookie(HZ1_RESET);
EALLOW;
SysCtrlRegs.SCSR = 0x0000;
SysCtrlRegs.WDCR = 0x0038; // Immediate device reset WDCHK != 101
EDIS;
}
}
}
With this version I get an illegal ISR, the ISR is configured to store a value in RAM and then reset the device. I can see the device is in reset on the oscilloscope, and also in the debug window.
If I comment:
// DINT;
IER |=M_INT1; // Enable WD group within this ISR
PieCtrlRegs.PIEACK.all = 0xFFFF; // Allow all interrupts at the PIE level by acknowledging it
// EINT;
the execution is ok. But if I keep GPIO20 in 0, I get the reset, and I see on the oscilloscope that the device doesn't come back to normal operation when the error disappears. And I get an error in the debug window:
C28xx: Trouble Reading PC Register: (Error -1142 @ 0x0) Device blocked debug access because it is currently executing non-debuggable code. Choose 'Rude Retry' to disable polite mode and force the operation. (Release 5.0.429.0)
I need to flash again the device to make it start again, and I can check which was the reset reason - it comes from the while loop as expected.
If I comment also:
//loop++;
// if(loop>=200)
// {
// SetCookie(HZ1_RESET);
// EALLOW;
// SysCtrlRegs.SCSR = 0x0000;
// SysCtrlRegs.WDCR = 0x0038; // Immediate device reset WDCHK != 101
// EDIS;
// }
so I don't do anything in the while loop, I get a reset (caused this time by the watchdog as expected), but again the device doesn't return to normal execution and I get the same error in the debug window. This part I don't understand, why after reset, if there is no error, the device doesn't go to normal operation.
Monica
Something else that I've noticed now is that sometimes, the execution hangs in the while loop and I get the reset only after the error disappears.
Still, to be able to work, I must close the debug session.
Couple of questions:-
1) why acknowledge all the PIE interrupts inside XINT_ISR()? why can't you just acknowledge appropriate PIE group?
2) Also, I would acknowedge appropriate PIE interrupt before you enable IER |=M_INT1.
3) Did you already check XINT and watchdog interrupt belong to the same interrupt group?
Regards,
Manoj
I've tried this too.
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
IER |=M_INT1;
But I get the same error if I simulate an error on GPIO20. If I check the reset reason, I can see that the execution passed through the while loop where I check GPIO20. After reset, the device doesn't come back to normal execution. So, I see no improvement.
I know XINT and WDINT they are in the same interrupt group. So I actually acknowledge both.
Hi!
It seems the watchdog doesn't expires, or it's impossible to execute the WDINT as long as the execution is kept in the while loop. Only when I remove the error I get the reset. What else can I try to get the reset in 6.5ms?
Thanks,
Monica
GPASET register is EALLOW protected. Did you confirm whether GPASET is set to 1 after you execute the below instruction before you enter while loop?
GpioDataRegs.GPASET.bit.GPIO20 =1;
Regards,
Manoj
Hi!
That's actually the purpose of the while loop, to wait until the GPIO is set. If this doesn't happen, it indicates an error with the external circuit.
Are you sure GPASET is EALLOW protected? In SPRUH18 is not on the list, and I don't use EALLOW to set it or clear it and it works.
Regards,
Monica
Are you using GPIO20 as output pin (or) input pin? Either way, this instrucion " GpioDataRegs.GPASET.bit.GPIO20 =1;" should write '1' to this specific bit. If you had configured GPIO20 as output pin it should pull GPIO20 high. If it is input pin, it would set GPASET.GPIO20 bit but won't pull GPIO20 pin high.
Based on what you have been saying, it looks like you have an external circuit which would pull GPIO20, in that case you should use GPIO20 as input pin and you don't need to have " GpioDataRegs.GPASET.bit.GPIO20 =1;" instruction executed before the while loop
-Manoj
I'm using GPIO20 as an output. I must set the pin to low or high, but each time I must check that it was set as I want before I continue with the next step. It's the Chip Select line for an external circuit. I must be sure the circuit is selected before I read it or it went to high impedance before I select another circuit. If this doesn't happen I need to get a watchdog reset, coz this means something is wrong with the external hardware.
Monica
Okay.
Did you try to single step through the function and check whether GPIO20 goes high before it executes the while loop?
The execution works perfect. The idea is I need to implement something in case an error occurs. For example when I set GPIO20 to 1, the external circuit puts the line in 0, or settling to 1 takes too long. That's why I wait in the while loop until GPIO is 1. If this doesn't happen I want the watchdog to expire and exit from the current interrupt.
Inorder for you to do this, you need to do the following:
1) Configure GPIO20 as output pin
2) GPASET.bit.GPIO20 = 1 (pull GPIO20 high)
3) Change GPIO20 to work as input pin.
4) Check the state of GPIO pin using the while loop discussed.
Regards,
Manoj
I've tried this too. It works exactly as before.
The watchdog expires only after remove the error.
Regards,
Monica
Hi Monica,
What do you do in the WDINT? If you need to reset the device only in this condition (loop>= 200), then you don't need the watchdog module at all. You can just reset the part like you have done here and forget about WDINT.
(In case you are using watchdog as a timer, I would not recommend that. Use the Timer 0 module for that.
Vivek
Hi!
There are multiple conditions in which I should reset the device, or escape from the interrupt. It's not just checking the state of some GPIOs. What happens if the execution hangs in an interrupt? The system that I control will receive the last commands (for how long?) and this is not allowed. That's why I'm trying to prevent this by letting the watchdog expire and trigger the interrupt. In the interrupt I can send a command to the system to stop and then I generate the reset and restart the system.
Monica