Hello
In the last 7 months, I have been developing a proprietary board using an MK02FN128VLH10 MCU, everything works perfect, and intensive tests have been done. It has bootloader and program space, due to the critical application, it also has an external watchdog (push-pull) to the reset line in case the firmware hangs. In some circumstances, like firmware update, config update etc. the system must restart. Again, it was tested and fine-tuned until no issues where found in laboratory and field while debugging using both P&E and J-link probes using SWD interface.
The project went into production last week, and the first time a firmware update was performed, the boards succesfully downloaded the new package in an external flash, but the boards didn’t restarted, and the behavior was exactly when the board has no firmware programed, after taking the battery off and the external power form one board, the bootloader started and programmed the board but again it didn’t restarted, I power cycled again and the new firmware started with no issues.
I found that while I am debugging the board restarts with no issues, but when not debugging, it simply cannot restart and stays in a (no programed board like state), also I made the firmware to do SW restart after 4 seconds with the reset register with the VECTKEY=0x05FA and SYSRESETREQ=1, but does not restart, also I made an infinite loop (no internal watchdog enabled) and the external watch dog reacted asserting a momentary low signal, but same result.
I took off from the board the external watchdog IC and put a 10K resistor pullup between VCC (3.3V) and RESET pin and tried two types of capacitor (1.0uf and 0.1uf) but same result. I checked with a multimeter and something is pulling down the reset signal, but nothing else is in the PCB track that may pull down the RESET signal, except the watchdog IC. Also happened when measuring the voltage that never drops from 3.27V, touching with the multimeter tip random board points, the board restarts.
Finally, I used an oscilloscope while the situation persists and can notice that there is a momentary 3.3 volts peak about every 1ms, then the signal is pulled down and keeps this until touching a part on the board and rises to 3.3 volts. (The test was done with a 10K pullup to the RESET pin).
I have no idea what may be happening, I have been developing boards for more than 12 years, with HCS-08, HCS-12, ColdFire V1 and various Kinetis, (K10, K22, K64 and K66) and never had issues restarting, just this time, but also is the first time I use an external watchdog instead of internal, but for this test I use the same circuit I used in previous designs for the reset pin.
Thanks
Solved! Go to Solution.
Hi Juan
What is the level on your NMI input when the external reset occurs?
Does your boot loader disable the NMI function?
Non-volatile flash configuration option set to FTFL_FOPT_NMI_ENABLED or FTFL_FOPT_NMI_DISABLED?
If the NMI is low and the option is not disabled the NMI will be taken, which will cause the processor to hang unless there is an NMI handler directly installed in the vector table.
Could this be a cause?
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hi Juan
What is the level on your NMI input when the external reset occurs?
Does your boot loader disable the NMI function?
Non-volatile flash configuration option set to FTFL_FOPT_NMI_ENABLED or FTFL_FOPT_NMI_DISABLED?
If the NMI is low and the option is not disabled the NMI will be taken, which will cause the processor to hang unless there is an NMI handler directly installed in the vector table.
Could this be a cause?
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hello Mark
I just disabled the NMI, and in fact this was the cause, maybe for sharing this pin to the external watchdog, not sure, but now the firmware update works and the external watchdog now restarts the board during infinite loop, all without the debugger connected.
Thanks
Many thanks to @Mark Butcher reminding me about the NMI. Because myself and my students have been bumping into the NMI issue to many times. In general I recommend disabling the NMI pin if that pin is used otherwise: Disabling NMI (Non Maskable Interrupt) Pin | MCU on Eclipse
I hope this helps,
Erich
Erich
Both the NMI and EzPort enable pins are two catch-me's that often cause problems and, as you have noted, the easiest thing to do is usually to disable them (although EzPort enable can be more serious since it doesn't allow programming at all if it is incorrectly set to '0' on a new layout).
If the NMI is needed it needs to be handled out of reset (as you have noted) but since it is a level sensitive input a continuous '0' will still block the processor if the handler is an empty routine
This is the solution used in the uTasker project:
1. Disable:
Each project has definitions for the flash configurations that are easily readable (not just hex values):
#define KINETIS_FLASH_CONFIGURATION_NONVOL_OPTION (FTFL_FOPT_LPBOOT_CLK_DIV_1 | FTFL_FOPT_RESET_PIN_ENABLED | FTFL_FOPT_BOOTSRC_SEL_FLASH | FTFL_FOPT_BOOTPIN_OPT_DISABLE | FTFL_FOPT_NMI_DISABLED)
whereby the NMI disabled state is the default. The user doesn't need to know which bits means what and where to find the configuration values can be change between DISABLED and ENABLED as required.
2. Handle at reset and use later:
The project enables this with the define NMI_IN_FLASH
const _RESET_VECTOR __vector_table
= {
{
(void *)(RAM_START_ADDRESS + (SIZE_OF_RAM - NON_INITIALISED_RAM_SIZE)), // stack pointer to top of RAM
(void (*)(void))START_CODE, // start address
#if defined NMI_IN_FLASH
irq_NMI // if the NMI is not disabled and the input is 0 out of reset this will be immediately taken
#endif
..
which adds a default handler in the flash based reset vector (later vectors will be moved to SRAM). This is needed by any boot loader that is used since an application can't influence this.
The NI handler reconfigures the NMI pin (note that the actual pin changes with Kinetis part) so that the interrupt is negated and the normal start-up can continue, even if there is initially a continuous '0' on the pin:
static void irq_NMI(void)
{
#if defined PB_4_NMI // set the NMI line to an input to remove the NMI function and allow the processor to continue
_CONFIG_PORT_INPUT_FAST_LOW(B, PORTB_BIT4, PORT_PS_UP_ENABLE);
#elif defined PB_18_NMI // set the NMI line to an input to remove the NMI function and allow the processor to continue
_CONFIG_PORT_INPUT_FAST_HIGH(B, PORTB_BIT18, PORT_PS_UP_ENABLE);
#else
_CONFIG_PORT_INPUT_FAST_LOW(A, PORTA_BIT4, PORT_PS_UP_ENABLE); // set the NMI line to an input to remove the NMI function and allow the processor to continue
#endif
}
Later, when the NMI is to be enabled for its application usage the user enters its handler and re-enables the NMI input function with (the vectors will always be in SRAM)
// Allow the user to enter an NMI handler, ensuring that the NMI pin is configured as NMI function
// - note that the NMI may not have been disabled to allow this to work
//
extern void fnEnterNMI(void (*_NMI_handler)(void))
{
VECTOR_TABLE *ptrVect = (VECTOR_TABLE *)VECTOR_TABLE_OFFSET_REG;
ptrVect->reset_vect.ptrNMI = _NMI_handler; // enter interrupt handler
#if defined PB_4_NMI // set the NMI pin function
_CONFIG_PERIPHERAL(B, 4, (PB_4_NMI | PORT_PS_UP_ENABLE));
#elif defined PB_18_NMI // set the NMI pin function
_CONFIG_PERIPHERAL(B, 18, (PB_18_NMI | PORT_PS_UP_ENABLE));
#elif defined PB_5_NMI // set the NMI pin function
_CONFIG_PERIPHERAL(B, 5, (PB_5_NMI | PORT_PS_UP_ENABLE));
#else
_CONFIG_PERIPHERAL(A, 4, (PA_4_NMI | PORT_PS_UP_ENABLE));
#endif
}
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hi Mark,
thank you for all the details!
Erich
Hello Mark
Thanks
I have the FTFL_FOPT_NMI_ENABLED in bootloader, but also I am using this output to re-triger the external watchdog and LED.
Will try to disabling the NMI in bootloader.
Regards
Juan