ARM-Linux驱动--Watch Dog Timer(看门狗)驱动分析
时间:11-20
来源:互联网
点击:
- rtbeat(inttimeout)
- {
- unsignedintfreq=clk_get_rate(wdt_clock);
- unsignedintcount;
- unsignedintdivisor=1;
- unsignedlongwtcon;
- if(timeout<1)
- return-EINVAL;
- freq/=128;
- count=timeout*freq;
- /*ifthecountisbiggerthanthewatchdogregister,
- thenworkoutwhatweneedtodo(andif)wecan
- actuallymakethisvalue
- */
- //如果计时的时间过大,则适当加大预分频值
- if(count>=0x10000)
- {
- for(divisor=1;divisor<=0x100;divisor++)
- {
- if((count/divisor)<0x10000)
- break;
- }
- //若预分频最大仍不能满足计时周期,则报错
- if((count/divisor)>=0x10000)
- {
- dev_err(wdt_dev,"timeout%dtoobig\n",timeout);
- return-EINVAL;
- }
- }
- tmr_margin=timeout;
- count/=divisor;
- wdt_count=count;
- /*updatethepre-scaler*/
- wtcon=readl(wdt_base+S3C2410_WTCON);
- wtcon&=~S3C2410_WTCON_PRESCALE_MASK;
- wtcon|=S3C2410_WTCON_PRESCALE(divisor-1);
- writel(count,wdt_base+S3C2410_WTDAT);//是指WTDAT寄存器
- writel(wtcon,wdt_base+S3C2410_WTCON);//设置预分频值
- return0;
- }
- /*
- */dev/watchdoghandling
- */
- staticints3c2410wdt_open(structinode*inode,structfile*file)
- {
- if(test_and_set_bit(0,&open_lock))//测试并设置open_lock第0位为1
- return-EBUSY;
- if(nowayout)
- __module_get(THIS_MODULE);
- allow_close=CLOSE_STATE_NOT;
- /*startthetimer*/
- s3c2410wdt_start();//启动watchdog
- returnnonseekable_open(inode,file);
- }
- staticints3c2410wdt_release(structinode*inode,structfile*file)
- {
- /*
- *Shutoffthetimer.
- *Lockitinifitsamoduleandwesetnowayout
- */
- if(allow_close==CLOSE_STATE_ALLOW)
- s3c2410wdt_stop();
- else
- {
- dev_err(wdt_dev,"Unexpectedclose,notstoppingwatchdog\n");
- s3c2410wdt_keepalive();
- }
- allow_close=CLOSE_STATE_NOT;
- clear_bit(0,&open_lock);//清楚open_lock第0位
- return0;
- }
- staticssize_ts3c2410wdt_write(structfile*file,constchar__user*data,
- size_tlen,loff_t*ppos)
- {
- /*
- *Refreshthetimer.
- */
- if(len)
- {
- if(!nowayout)
- {
- size_ti;
- /*Incaseitwassetlongago*/
- allow_close=CLOSE_STATE_NOT;
- for(i=0;i!=len;i++)
- {
- charc;
- if(get_user(c,data+i))//从用户空间copy数据
- return-EFAULT;
- if(c==V)//当输入V时,关闭watchdog
- allow_close=CLOSE_STATE_ALLOW;
- }
- }
- //注意:这里要手动喂狗一次?!
- s3c2410wdt_keepalive();//由于将allow_close设置成CLOSE_STATE_ALLOW后,当release时无法再次喂狗
- }
- returnlen;
- }
- #defineOPTIONSWDIOF_SETTIMEOUT|WDIOF_KEEPALIVEPING|WDIOF_MAGICCLOSE
- staticconststructwatchdog_infos3c2410_wdt_ident=
- {
- .options=OPTIONS,
- .firmware_version=0,
- .identity="S3C2410Watchdog",
- };
- //IO控制接口函数
- staticlongs3c2410wdt_ioctl(structfile*file,unsignedintcmd,
- unsignedlongarg)
- {
- void__user*argp=(void__user*)arg;
- int__user*p=argp;
- intnew_margin;
- switch(cmd){
- caseWDIOC_GETSUPPORT:
- returncopy_to_user(argp,&s3c2410_wdt_ident,
- sizeof(s3c2410_wdt_ident))?-EFAULT:0;
- caseWDIOC_GETSTATUS:
- caseWDIOC_GETBOOTSTATUS:
- returnput_user(0,p);
- caseWDIOC_KEEPALIVE:
- s3c2410wdt_keepalive();
- return0;
- caseWDIOC_SETTIMEOUT:
- if(get_user(new_margin,p))
- return-EFAULT;
- if(s3c2410wdt_set_heartbeat(new_margin))
- return-EINVAL;
- s3c2410wdt_keepalive();
- returnput_user(tmr_margin,p);
- caseWDIOC_GETTIMEOUT:
- returnput_user(tmr_margin,p);
- default:
- return-ENOTTY;
- }
- }
- /*kernelinterface*/
- //文件操作结构体
- staticconststructfile_operationss3c2410wdt_fops=
- {
- .owner=THIS_MODULE,
- .llseek=no_llseek,//屏蔽seek操作
- .write=s3c2410wdt_write,//写方法
- .unlocked_ioctl=s3c2410wdt_ioctl,//控制方法
- .open=s3c2410wdt_open,//代开设备方法
- .release=s3c2410wdt_release,//关闭设备方法
- };
- staticstructmiscdevices3c2410wdt_miscdev=
- {
- .minor=WATCHDOG_MINOR,
- .name="watchdog",
- .fops=&s3c2410wdt_fops,
- };
- /*interrupthandlercode*/
- staticirqreturn_ts3c2410wdt_irq(intirqno,void*param)
- {
- //dev_info(wdt_dev,"watchdogtimerexpired(irq)\n");
- s3c2410_gpio_setpin(S3C2410_GPB10,(count++)%2);
- s3c2410wdt_keepalive();
- returnIRQ_HANDLED;
- }
- /*deviceinterface*/
- //注册设备时执行
- staticints3c2410wdt_probe(structplatform_device*pdev)
- {
- structresource*res;
- structdevice*dev;
- unsignedintwtcon;
- intstarted=0;
- intret;
- intsize;
- dev=&pdev->dev;
- wdt_dev=&pdev->dev;
- /*getthememoryregionforthewatchdogtimer*/
ARMLinux驱动看门 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)