About Watchdog - Could anyone tell me what is difference between them

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, 

I wanted to use watchdog and followed instructions. 

 

First I tried to make other function to initialize watchdog init part, 

And then initialize directly in main function. 

 

I can't say in detail, but I feel something wrong when I code it as function. 

for example, debugging step is not going over the function. 

 

Could anyone tell me what is difference between them? or What I'm doing wrong? 

 

 

void WatchdogInit(void)
{
  MCUSR = 0x00;
  wdt_enable(WDTO_2S);
  return;
}

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
int main(void)
{
  
  mcusr_mirror = MCUSR;
  //WatchdogInit();
  MCUSR = 0x00;
  wdt_enable(WDTO_2S);
  

 

and main.h

void WatchdogInit(void) __attribute__((naked)) __attribute__((section(".init3")));

 

Thanks in advance

 

This topic has a solution.
Last Edited: Tue. Jan 8, 2019 - 06:17 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One is a function attribute and the other is a data attribute

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I got a hint from this link. 

https://stackoverflow.com/questi...

 

Actually below code is from the link. 

void WatchdogInit(void) __attribute__((naked)) __attribute__((section(".init3")));

 

so .init3 section code is start before main() function. 

that may make some problem. 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As the manual tells you:

 

https://www.nongnu.org/avr-libc/...

 

There are these memory sections in "text":

 

    KEEP(SORT(*)(.ctors))
    KEEP(SORT(*)(.dtors))
    /* From this point on, we don't bother about wether the insns are
       below or above the 16 bits boundary.  */
    *(.init0)  /* Start here after reset.  */
    KEEP (*(.init0))
    *(.init1)
    KEEP (*(.init1))
    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
    KEEP (*(.init2))
    *(.init3)
    KEEP (*(.init3))
    *(.init4)  /* Initialize data and BSS.  */
    KEEP (*(.init4))
    *(.init5)
    KEEP (*(.init5))
    *(.init6)  /* C++ constructors.  */
    KEEP (*(.init6))
    *(.init7)
    KEEP (*(.init7))
    *(.init8)
    KEEP (*(.init8))
    *(.init9)  /* Call main().  */
    KEEP (*(.init9))
    *(.text)
    . = ALIGN(2);
     *(.text.*)
    . = ALIGN(2);
    *(.fini9)  /* _exit() starts here.  */
    KEEP (*(.fini9))
    *(.fini8)
    KEEP (*(.fini8))
    *(.fini7)
    KEEP (*(.fini7))
    *(.fini6)  /* C++ destructors.  */
    KEEP (*(.fini6))
    *(.fini5)
    KEEP (*(.fini5))
    *(.fini4)
    KEEP (*(.fini4))
    *(.fini3)
    KEEP (*(.fini3))
    *(.fini2)
    KEEP (*(.fini2))
    *(.fini1)
    KEEP (*(.fini1))
    *(.fini0)  /* Infinite loop after program termination.  */
    KEEP (*(.fini0))
     _etext = . ;

 

So there are 10 potential .initN sections before .text and 10 potential .finiN sections after it. The manual further tells you that the even numbered sections are/may be used by the C library but that leaves .ini1, init3, init5 etc for your own use to "inject" code sequences amongst the code that the C library may also be performing.

 

The manual tells you that .init4 is used "  the code which takes care of copying the contents of .data from the flash to SRAM " - this can be a lengthy process which could take so long that a watchdog might re-trigger so if you have some watchdog configuration that needs to happen very soon after power on there are the user sections .init1 and .init3 for that purpose. So when you write:

__attribute__((naked, section(".init3")) void early(void) {
   // stuff
}

You are simply adding this code early in the startup.

 

Your other thing:

uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); 

is something completely different - that is simply saying that a variable called mcusr_mirror should be located in the .noinit section. Usually a global with no initial value will be located in the .bss section (block started by symbol) and the C run time will write 0 to it at start up (in section .init4 in fact!) but this arranges to create it in a place where the previous value will not be wiped.