Due resets in main

The code objective is to find out why Due resets when Arduino IDE Setup / Loop is not used.

In following example standard *.ino does what is expected - runs forever.

// #include "main.h"   main header bypassed 



void setup() {

  Serial.begin(115200);

  Serial.println(__FILE__);

  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, BIN );
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, HEX );
  //delay(1);
  //delay(1000); 
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, BIN );
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, HEX );

  while (1);        // no reset , runs forever 

}
void loop() {
  // put your main code here, to run repeatedly:

}

When main.h is included it runs this code:

[code]#ifndef MAIN_H
#define MAIN_H
#include <Arduino.h>
int main (void)
{
  init();      // initialize hardware 
  
  Serial.begin(115200);

  Serial.println(__FILE__);

  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, BIN );
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, HEX );
  //delay(1);
  
  //delay(1000);
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, BIN );
  Serial.print("\nSysTick->CTRL ");
  Serial.println(SysTick->CTRL, HEX );

  while (1);  // resets at about 10 seconds rate 


}
#endif

[/code]

This code resets at about 10 seconds rate.

As far as I can tell, both standard implementation of main , by IDE, and custom as in my case run SAME init() function.

Or do they?
There must be some difference.
I like to know what register does this "reset" - WDT or processor reset and how.
Any suggestion how to troubleshoot / solve this would be appreciated.
It seems that implementing sysTick may have something to do with it, but disabling sysTick->CR = 0 does not affect the reset.
Jim

char *resetTypes[] = { "general", "backup", "watchdog", "software", "user" };
uint32_t resetCause = rstc_get_reset_cause(RSTC) >> RSTC_SR_RSTTYP_Pos;

Addendum
disabling WDT stopped the reset. but the WDT status did not change.
That indicates WDT is not direct cause of the reset.
Problem just masked , not solved.

 Serial.print("\nWDT_GetStatus( WDT) ");
  Serial.println( WDT_GetStatus( WDT), BIN );
  Serial.print("\nWDT_GetStatus( WDT) ");
  Serial.println( WDT_GetStatus( WDT), HEX );
  Serial.print("\nWDT_Disable( WDT) ");
  WDT_Disable( WDT) ;
  Serial.print("\nWDT_GetStatus( WDT) ");
  Serial.println( WDT_GetStatus( WDT), BIN );
  Serial.print("\nWDT_GetStatus( WDT) ");
  Serial.println( WDT_GetStatus( WDT), HEX );

phr3ak:
char *resetTypes[] = { "general", "backup", "watchdog", "software", "user" };
uint32_t resetCause = rstc_get_reset_cause(RSTC) >> RSTC_SR_RSTTYP_Pos;

Thanks, works great.

Now to find out why WDT is activated and why the WDT status does not change when disable.
Perhaps direst WDT status register read is overdue.

anyways it is interesting because wdt disabled by default in watchdogSetup function and that's called before the setup function see main.cpp

Also uint32_t wdt_get_status ( Wdt * p_wdt ); does not exist in Arduino code.
The whole WDT business in ARM support code is just whatever the developer decided that day.
Thanks for your help.
Jim

see wdt.c

/**

  • \brief Watchdog get status.
    /
    extern uint32_t WDT_GetStatus( Wdt
    pWDT )
    {
    return (pWDT->WDT_SR & 0x3) ;
    }

phr3ak:
see wdt.c

/**

  • \brief Watchdog get status.
    /
    extern uint32_t WDT_GetStatus( Wdt
    pWDT )
    {
    return (pWDT->WDT_SR & 0x3) ;
    }

Yes, just went similar route.
Per SAM 3X(E doc reading SR resets the WDT counter back to whatever.
Tried int result = WDT->WDT_SR but it didn't work . .

..
Still cannot find which init() is in use and where is the WDt actually set using MR.

IT looks as the power reset sets the WDT to default but how?

Mainly because the WDT_Disable writes to MR which it cannot if it was already written to.
But that works - disabling the WDT timeout reset.

I think the issue is - the WDT works differently in different hardware and Arduino code does not reflects that.
There are some references to AVR WDT during compiling, but I did not follow that very far.

Do you know where is/ are the init() functions in use?
That would help.

Jim

After a Processor Reset, the value of WDV is 0xFFF, corresponding to the maximum value of the counter with the external reset generation enabled (field WDRSTEN at 1 after a Backup Reset). This means that a default
Watchdog is running at reset, i.e., at power-up. The user must either disable it (by setting the WDDIS bit in
WDT_MR) if he does not expect to use it or must reprogram it to meet the maximum Watchdog period the
application requires.

The Watchdog Mode Register (WDT_MR) can be written only once. Only a processor reset resets it. Writing the
WDT_MR register reloads the timer with the newly programmed mode parameters.

you can find the init function in variant.cpp file

The key is to find real init() .
The watchdogSetup is declared in watchdog. h / cpp as weak function and if the init() does not replace it the default is to run
WDT_Disable.
Again, since running WDT_Disable. in my code, (that would be the second time !,) stops the reset - the Arduino process is bogus until we get the init(). function.

BTW my main code has ONLY init() hence bypassing the watchdogSetup altogether.

I need to fix that first!

extern "C"
void _watchdogDefaultSetup (void)
{
WDT_Disable (WDT);
}
void watchdogSetup (void) attribute ((weak, alias("_watchdogDefaultSetup")));

/*

  • \brief Watchdog initialize hook. This function is called from init(). If the user does not provide
  • this function, then the default action is to disable watchdog.
    */
    void watchdogSetup (void);

you can find the init function in variant.cpp

Actually, it's main() (cores/arduino/main.cpp) that calls watchdogSetup(), which is defined in cores/arduino/watchdog.cpp (aliased to _watchdogDefaultSetup())
Naturally, if you replace main() with your own, watchdogSetup() is no longer called.

/*
 * \brief Main entry point of Arduino application
 */
int main( void )
{
    // Initialize watchdog
    watchdogSetup();
    init();
    initVariant();
extern "C"
void _watchdogDefaultSetup (void)
{
    WDT_Disable (WDT);
}
void watchdogSetup (void) __attribute__ ((weak, alias("_watchdogDefaultSetup")));

Why is the watchdog not initialized from init() instead, which I think would make more sense? I dunno.
I suspect that they're trying to make sure that the disable happens RIGHT AWAY.

we never write main function to the arduino code. back to the original problem. I don't understand why the wdt isn't disabled before your setup function.

westfw:
Actually, it's main() (cores/arduino/main.cpp) that calls watchdogSetup(), which is defined in cores/arduino/watchdog.cpp (aliased to _watchdogDefaultSetup())
Naturally, if you replace main() with your own, watchdogSetup() is no longer called.

/*
  • \brief Main entry point of Arduino application
    */
    int main( void )
    {
        // Initialize watchdog
        watchdogSetup();
        init();
        initVariant();






extern "C"
void _watchdogDefaultSetup (void)
{
    WDT_Disable (WDT);
}
void watchdogSetup (void) attribute ((weak, alias("_watchdogDefaultSetup")));




Why is the watchdog not initialized from init() instead, which I think would make more sense? I dunno.
I suspect that they're trying to make sure that the disable happens RIGHT AWAY.

This is getting more and more interesting.

After I replaced init() in my main() with current functions , the compiler flagged my main() t as multiple definition.
I also added some headers , mind you NOT included in my test *.ino so I need to have a clear *.ino with just one header including my main. But I am chasing another more pressing issue, so this has to wait.

The purpose of directing *.ino to header which has my own main() was to get away from many issues with IDE messing around with #define(s) . It has been working for me for few years and ALL my application are build that way.
Judging from the latest core main() it MAY not be necessary now, but was about two years ago.
Again, not a pressing issue right now.
Jim

Short and hopefully "closing argument".
As pointed out the issue was me using outdated approach to initialization in my version of main.
I suppose the benefit of the discussion, at least to me, was to untangle the WDT mess.

Subject of next discussion MAY be why initVariant(); is causing multiple definitions of main().

Jim