The watchdog device drive of ~linux equipment drive

Source: Internet
Author: User
Tags int size

the watchdog (watchdog) is divided between the hardware watchdog and the software watchdog. Hardware watchdog is the use of a timer circuit, its timing output is connected to the reset end of the circuit, the program in a certain time range to the timer 0 (commonly known as "feed the Dog"), if the program fails, not reset the watchdog during the scheduled period, Causes the watchdog timer overflow to generate a reset signal and restart the system. The software watchdog principle is just the same as the timer on the hardware circuit is replaced by the processor's internal timing device.

1 watchdog three registers

1.1 Watchdog principle

  The s3c2410 is internally integrated with the watchdog, providing 3 registers to operate on the watchdog, the 3 registers are WTCON (watchdog control Register), WTDAT (watchdog data Register), and WTCNT (watchdog Count register) The s3c2440 of the watchdog is as follows:

As can be seen, the frequency of the watchdog timer is provided by PCLK, its prescaler maximum value is 255+1, in addition, through the MUX, can further reduce the frequency. The timer is in descending mode, and once it is 0, it can trigger the watchdog interrupt and reset signal. The frequency of the watchdog timer is calculated as follows:

T_watchdog = 1/[pclk/(prescaler value + 1)/division_factor]

1.2 Opening the s3c2410 watchdog

void enable watchdog ()      {                       Rwtcon = Wtcon DIV64 | Wtcon RSTEN;//64 crossover, open reset signal        Rwtdat = 0x8000;//count target                        rwtcon |= wtcon enable;//turn on watchdog       

1.3 s3c2410 's Watchdog "Feed the dog."

void Feed Dog () {    

1.4 Watchdog usage Routines

void Main ()      {           init system ();        ...                   Enable watchdog ();//start watchdog ...        while (1)        {           ...                      Feed Dog (); Feed the Dog       }     

2 data knots in the watchdog

One type of device is called a "platform device", and a separate peripheral unit that is typically integrated in the SoC system is treated as a platform device

2.1 Platform_device Structural Body

struct platform      device {        const char  * name;//unit name        u32      ID;        struct device dev;                   U32      number of resources used by NUM resources;//devices        struct resource * resource;//resources      

2.2 Platform devices in the s3c2410

struct platform device *s3c24xx UART devs[];struct platform device s3c device USB;// USB controller struct platform device s3c device LCD; LCD controller struct Platform device s3c device WDT; Watchdog 2 struct platform device s3c Dev Ice i²c; I C controller struct platform device s3c device IIS; IIS struct platform device s3c device RTC; Real Time clock ... the platform device used by the/*SMDK2410 Development Board */static struct platform device *smdk2410 Devic                        Es[] InitData = {&s3c device USB,//usb &s3c device LCD,//LCD                      &S3C device WDT,//watchdog &S3C device i²c,//i C &S3C device IIS,//iis}; 

2.3 s3c2410 watchdog's platform_device structure

struct platform Device s3c device WDT =       {         . Name = "S3C2410-WDT",  //device name         . id =  -1,.          num resources = ARRAY SIZE (s3c WDT Resource),  //resource quantity                          . Resource = s3c WDT resource,  //Resources used by the watchdog       

2.4 int platform_add_devices () function

int platform add devices (struct platform device **devs, int num)       {         int i, ret = 0;         for (i = 0; i < num; i++)          {ret = Platform device register (devs[i]);/* Register Platform Device */           if (ret)/* Registration failed */           {            while (-i >= 0)                  platform device unregister (devs[i]);/* Unregister the registered platform device */break            ;          }         }        return ret;      

2.5 Platform_driver Structural Body

struct platform driver       {                                                int (*probe) (struct platform device *);//Probe                                         int (*remove) (struct platform device *) ;//Remove                                            void (*shutdown) (struct platform device *);//close                                            int (*suspend) (struct platform device *, PM message T State) ;//suspend                            Int (*resume) (struct platform device *);//restore the                    struct device driver driver;        

2.6 s3c2410 watchdog's platform_driver structure

static struct platform driver S3C2410WDT Driver =       {                                 . Probe      = S3C2410WDT probe,//s3c2410 watchdog detection                                         . Remove     = S3C2410WDT remove,//s3c2410 watchdog removed                                         . Shutdown   = S3C2410WDT shutdown,//s3c2410 watchdog off                                         . Suspend    = S3C2410WDT suspend,//s3c2410 watchdog hangs. Resume     = S3C2410WDT Resume,//s3c2410 watchdog recovery         . Driver     = {                                 . Owner  = This MODULE,            . Name   = "S3C2410-WDT",//device name       },};

Resources used by the 2.7 s3c2410 watchdog

static struct resource s3c WDT resource[] =        {          [0] =         {           . start = s3c24xx PA WATCHDOG,     //watchdog I/O memory start position 
   .end = s3c24xx PA WATCHDOG + s3c24xx SZ WATCHDOG-1,               //watchdog I/O memory end location           . Flags = Ioresource MEM,  //i/o memory Resources 
   },         [1] =        {          . start = IRQ WDT,//watchdog start IRQ number          . end = IRQ WDT,//watchdog end IRQ Number          . flags = Ioresource IRQ ,  //IRQ Resources         }       

2.8 s3c2410 watchdog-driven miscdevice structural body

static struct Miscdevice S3c2410wdt Miscdev =  {                              . minor      = WATCHDOG minor,//secondary device number         . Name       = " Watchdog ",        . FoPs       

2.9 s3c2410 watchdog-driven file operation structure

Static struct file operations S3c2410wdt fops = {                     . Owner      = this MODULE,                . Llseek     = no llseek,    //seek
   .write      = S3c2410wdt Write,     //write function                                     . IOCTL      = S3C2410WDT ioctl,//ioctl function                               . Open       = S3C2410WDT Open,  //Opening function                              . release    

3 Loading and unloading functions

The load and unload functions of the driver module are registered and unregistered with platform_driver_register () and Platform_driver_ unregister () respectively Platform_driver

3.1 s3c2410 watchdog driver

static int     __init watchdog__init (void)       {        printk (banner);                 Return   Platform Driver register (&S3C2410WDT driver);//       Register platform driver       }             static void     exit Watchdog exit (void)        {platform driver unregister (&S3C2410WDT driver);//          injection  PIN platform driver      

4 Detection and removal functions

4.1 Detection function

static int S3C2410WDT probe (struct platform device *pdev) {struct resource *res;         int started = 0;         int ret;              int size;              DBG ("%s:probe=%p\n", _ _function_ _, Pdev);        /* Get the memory area of the watchdog */res = platform Get resource (Pdev, Ioresource MEM, 0);          if (res = = NULL) {PRINTK (KERN INFO PFX "failed to get memory region resouce\n");         Return-enoent;        } size = (Res->end-res->start) + 1;                    Request I/o memory WDT mem = Request Mem Region (Res->start, size, pdev->name);          if (wdt mem = = NULL) {PRINTK (KERN INFO PFX "failed to get memory region\n");         Return-enoent; WDT base = Ioremap (Res->start, size); Device memory, virtual address if (wdt base = = 0) {PRINTK (KERN INFO PFX "failed To Ioremap () region\n ");         Return-einval;              } DBG ("Probe:mapped wdt base=%p\n", WDT base);        /* Get the watchdog interrupt */RES = platform Get resource (Pdev, Ioresource IRQ, 0);          if (res = = NULL) {PRINTK (KERN INFO PFX "failed to get IRQ resource\n");         Return-enoent;        }//Request interrupt RET = Request IRQ (Res->start, S3C2410WDT IRQ, 0, Pdev->name, Pdev);          if (ret! = 0) {PRINTK (KERN INFO PFX "failed to install IRQ (%d) \ n", ret);         return ret; WDT Clock = CLK get (&pdev->dev, "watchdog"); Get watchdog clock source if (wdt clock = = NULL) {PRINTK (KERN INFO PFX "failed to fin          D watchdog clock source\n ");         Return-enoent;              } CLK enable (WDT clock); /* See if you can setThe timeout for the timer is the desired value, and if not, use the default value */if (S3C2410WDT set heartbeat (TMR margin)) { started = S3c2410wdt set Heartbeat (CONFIG s3c2410 Watchd          OG DEFAULT time); if (started = = 0) {PRINTK (KERN INFO PFX "TMR margin value out of range, defaul          T%d used\n ", CONFIG s3c2410 WATCHDOG DEFAULT time); } else {PRINTK (KERN INFO PFX "Default timer value is out          of range, cannot start\n ");        }}//register miscdevice RET = Misc Register (&AMP;S3C2410WDT Miscdev);                                 if (ret) {PRINTK (KERN ERR PFX "Cannot registermiscdev on minor=%d (%d) \ n",          WATCHDOG MINOR, ret);         return ret;                           } if (TMR atboot && started = = 0) {PRINTK (KERN INFO PFX "Starting Watchdog Ti                         Mer\n ");         S3C2410WDT start ();      } return 0;  }

4.2 Detection function

static int S3C2410WDT Remove (struct platform device *dev)       {            if (WDT mem! = NULL)         {                  release resource (WDT MEM); Release Resource                               Kfree (WDT mem);//Free memory            WDT mem = NULL;        }       Release Interrupt                if (WDT IRQ! = NULL)        {free                 IRQ (WDT irq->start, dev);                WDT IRQ = NULL; }        //disable clock source        if (WDT clock! = NULL)        {          clk disable (WDT clock);          CLK put (WDT clock);          WDT Clock = NULL;         }     Misc deregister (&S3C2410WDT miscdev);//logout Miscdevice        return 0;     

5 Suspend and Resume functions

5.1 Suspend function

static   int  S3C2410WDT suspend (struct    platform device   *dev, PM message T State)       {/         * save watchdog status, Stop it *                   /Wtcon save = READL (WDT base + s3c2410 Wtcon);                  Wtdat save = READL (WDT base + s3c2410 wtdat);                            S3c2410wdt stop ();               return 0;      

5.2 Restore function

static int S3C2410WDT Resume (struct platform device *dev)       {         /* restore watchdog status *                        /Writel (Wtdat Save, WDT base + S 3c2410 wtdat);                          Writel (Wtdat save, WDT base + s3c2410 wtcnt);                         Writel (Wtcon save, WDT base + s3c2410 Wtcon);                                 PRINTK (KERN INFO PFX "Watchdog%sabled\n", (Wtcon save                           &s3c2410 wtcon ENABLE)? "en": "dis");             return 0;      

6 opening and releasing functions

6.1 Opening functions

static int S3C2410WDT open (struct inode *inode, struct file *file)       {                       if (down Trylock (&open Lock))  //Get Hit Unlock           return  -ebusy;              if (nowayout)         {                     module get (this module);         }        Else         {Allow                          close = Close state allow;         }              /* Start watchdog *                           /S3C2410WDT start ();                                 Return nonseekable open (inode, file);      

6.2 Release function

static int S3C2410WDT release (struct inode *inode,struct file *file)       {/         * stop watchdog *                         /if (allow close = = Close S TATE allow)         {                           s3c2410wdt stop ();        }         else         {                               PRINTK (KERN crit  PFX  "Unexpected  close,  not  stopping watchdog!\n");                     S3C2410WDT keepalive ();         }                          Allow close = Close is not;                     Up (&open lock);  Release Open lock        return 0;      

7 Start-stop watchdog functions and write functions

7.1 Start-stop watchdog function

/* Stop watchdog */static int s3c2410wdt stop (void) {unsigned long wtcon;         Wtcon = Readl (WDT base + s3c2410 Wtcon); Stop watchdog, disable reset Wtcon &= ~ (s3c2410 wtcon ENABLE |                                s3c2410 Wtcon Rsten);               Writel (Wtcon, WDT base + s3c2410 Wtcon);       return 0;                           }/* Turn on Watchdog */static int s3c2410wdt start (void) {unsigned long wtcon;                                      S3c2410wdt Stop ();         Wtcon = Readl (WDT base + s3c2410 Wtcon); Enable watchdog, 128-way Wtcon |= s3c2410 Wtcon Enable |                             s3c2410 Wtcon DIV128;                                   if (soft noboot) {Wtcon |= s3c2410 wtcon inten;//Enable interrupt Wtcon &= ~s3c2410 Wtcon rsten;               Disable Reset} else {                   Wtcon &= ~s3c2410 Wtcon inten; Prohibit interruption Wtcon |= s3c2410 Wtcon rsten;                      Enable reset} DBG ("%s:wdt count=0x%08x, wtcon=%08lx\n", FUNCTION,                           WDT count, Wtcon);                        Writel (WDT count, WDT base + s3c2410 wtdat);                            Writel (WDT count, WDT base + s3c2410 wtcnt);               Writel (Wtcon, WDT base + s3c2410 Wtcon);       return 0;  }

7.2 Write function

Static Ssize t S3C2410WDT write (struct file *file, const char      user *data,                size t len, Loff t *ppos)        {/         * Refresh Watchdog */         if (len)          {           if (!nowayout) {             size t i;                         Allow close = Close is not;            for (i = 0; I! = Len; i++)            {              char C;                               if (get User (c, data + i))//user space, kernel                space  , return-efault;              if (c = = ' V ')  //If a ' V ' is written, allow closing allowed close = Close state allows                               ;}          }                      S3C2410WDT keepalive ();         }        return Len;      

  

The watchdog device drive of ~linux equipment drive

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.