Ok24403看门狗驱动代码详细分析Word下载.docx

上传人:b****5 文档编号:20630290 上传时间:2023-01-24 格式:DOCX 页数:18 大小:21.79KB
下载 相关 举报
Ok24403看门狗驱动代码详细分析Word下载.docx_第1页
第1页 / 共18页
Ok24403看门狗驱动代码详细分析Word下载.docx_第2页
第2页 / 共18页
Ok24403看门狗驱动代码详细分析Word下载.docx_第3页
第3页 / 共18页
Ok24403看门狗驱动代码详细分析Word下载.docx_第4页
第4页 / 共18页
Ok24403看门狗驱动代码详细分析Word下载.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

Ok24403看门狗驱动代码详细分析Word下载.docx

《Ok24403看门狗驱动代码详细分析Word下载.docx》由会员分享,可在线阅读,更多相关《Ok24403看门狗驱动代码详细分析Word下载.docx(18页珍藏版)》请在冰豆网上搜索。

Ok24403看门狗驱动代码详细分析Word下载.docx

linux/miscdevice.h>

linux/watchdog.h>

linux/fs.h>

linux/init.h>

linux/platform_device.h>

linux/interrupt.h>

linux/clk.h>

linux/uaccess.h>

linux/io.h>

mach/map.h>

#undefS3C_VA_WATCHDOG

#defineS3C_VA_WATCHDOG(0)

asm/plat-s3c/regs-watchdog.h>

#definePFX"

s3c2410-wdt:

"

#defineCONFIG_S3C2410_WATCHDOG_ATBOOT(0)

#defineCONFIG_S3C2410_WATCHDOG_DEFAULT_TIME(15)

staticintnowayout=WATCHDOG_NOWAYOUT;

staticinttmr_margin=CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;

staticinttmr_atboot=CONFIG_S3C2410_WATCHDOG_ATBOOT;

staticintsoft_noboot;

staticintdebug;

module_param(tmr_margin,int,0);

module_param(tmr_atboot,int,0);

module_param(nowayout,int,0);

module_param(soft_noboot,int,0);

module_param(debug,int,0);

MODULE_PARM_DESC(tmr_margin,"

Watchdogtmr_margininseconds.default="

__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME)"

)"

);

MODULE_PARM_DESC(tmr_atboot,

"

Watchdogisstartedatboottimeifsetto1,default="

__MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));

MODULE_PARM_DESC(nowayout,"

Watchdogcannotbestoppedoncestarted(default="

__MODULE_STRING(WATCHDOG_NOWAYOUT)"

MODULE_PARM_DESC(soft_noboot,"

Watchdogaction,setto1toignorereboots,0toreboot(defaultdependsonONLY_TESTING)"

MODULE_PARM_DESC(debug,"

Watchdogdebug,setto>

1fordebug,(default0)"

typedefenumclose_state{

CLOSE_STATE_NOT,

CLOSE_STATE_ALLOW=0x4021

}close_state_t;

staticunsignedlongopen_lock;

staticstructdevice*wdt_dev;

/*platformdeviceattachedto*/

staticstructresource*wdt_mem;

staticstructresource*wdt_irq;

staticstructclk*wdt_clock;

staticvoid__iomem*wdt_base;

staticunsignedintwdt_count;

staticclose_state_tallow_close;

staticDEFINE_SPINLOCK(wdt_lock);

/*watchdogcontrolroutines*/

#defineDBG(msg...)do{\

if(debug)\

printk(KERN_INFOmsg);

\

}while(0)

/*functions*/

staticvoids3c2410wdt_keepalive(void)//喂狗,即将计数值赋给WTCNT寄存器

{

spin_lock(&

wdt_lock);

writel(wdt_count,wdt_base+S3C2410_WTCNT);

spin_unlock(&

}

staticvoid__s3c2410wdt_stop(void)

unsignedlongwtcon;

wtcon=readl(wdt_base+S3C2410_WTCON);

wtcon&

=~(S3C2410_WTCON_ENABLE|S3C2410_WTCON_RSTEN);

writel(wtcon,wdt_base+S3C2410_WTCON);

//将WTCON寄存器的位[5]和位[0]清零,不输出复位信号,停止看门狗

staticvoids3c2410wdt_stop(void)//关看门狗

__s3c2410wdt_stop();

staticvoids3c2410wdt_start(void)

//关看门狗

wtcon|=S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV128;

/*#defineS3C2410_WTCON_ENABLE(1<

<

5)

#defineS3C2410_WTCON_DIV128(3<

3)

开启看门狗,设置分频系数为128(这里并没有将其写入控制寄存器,只是设置值而已)

if(soft_noboot){

wtcon|=S3C2410_WTCON_INTEN;

//#defineS3C2410_WTCON_INTEN(1<

2)使能看门狗中断

wtcon&

=~S3C2410_WTCON_RSTEN;

//#defineS3C2410_WTCON_RSTEN(0x01),不输出复位信号

}else{

=~S3C2410_WTCON_INTEN;

//禁止看门狗中断

wtcon|=S3C2410_WTCON_RSTEN;

//允许输出复位信号

}

DBG("

%s:

wdt_count=0x%08x,wtcon=%08lx\n"

__func__,wdt_count,wtcon);

writel(wdt_count,wdt_base+S3C2410_WTDAT);

//写入计数值

//写WTCON寄存器,前面的设置会生效

staticints3c2410wdt_set_heartbeat(inttimeout)

unsignedintfreq=clk_get_rate(wdt_clock);

//获得时钟,这里的时钟应该是系统初始化时设置好了的。

就是pclk的值

unsignedintcount;

unsignedintdivisor=1;

if(timeout<

1)

return-EINVAL;

freq/=128;

//这个地方有点不明白了,在前面没有设置WTCON寄存器的[4:

3]位,怎么就直接采用了128分频呢?

难道也是系统初始化时的设置?

count=timeout*freq;

//将看门时间timeout(秒)乘以freq,根据count的值确定是否需要设置看门狗的预分配项。

count=%d,timeout=%d,freq=%d\n"

__func__,count,timeout,freq);

/*ifthecountisbiggerthanthewatchdogregister,

thenworkoutwhatweneedtodo(andif)wecan

actuallymakethisvalue

*/

if(count>

=0x10000){

for(divisor=1;

divisor<

=0x100;

divisor++){

if((count/divisor)<

0x10000)

break;

}

//因为WTDAT寄存器为16位,因此当计数值count>

=0x10000时必须采用与分频项,经过这个循环后,divisor的值即为与分频因子。

if((count/divisor)>

dev_err(wdt_dev,"

timeout%dtoobig\n"

timeout);

return-EINVAL;

//如果count/divisor)>

=0x10000,则说明看门狗时间设得太大了,将会退出。

tmr_margin=timeout;

timeout=%d,divisor=%d,count=%d(%08x)\n"

__func__,timeout,divisor,count,count/divisor);

count/=divisor;

//得到采用预分频后看门狗的计数脉冲数

wdt_count=count;

/*updatethepre-scaler*/

=~S3C2410_WTCON_PRESCALE_MASK;

wtcon|=S3C2410_WTCON_PRESCALE(divisor-1);

//计算看门狗预分配因子

writel(count,wdt_base+S3C2410_WTDAT);

//设置看门狗计数脉冲数

//设置看门狗预分频因子

return0;

/*

*/dev/watchdoghandling

staticints3c2410wdt_open(structinode*inode,structfile*file)

if(test_and_set_bit(0,&

open_lock))//上锁,因此同时只有一个进程打开看门狗设备文件,该函数的功能为:

设置&

open_lock的位0为1,返回原来位0的值。

return-EBUSY;

if(nowayout)

__module_get(THIS_MODULE);

allow_close=CLOSE_STATE_NOT;

//这个状态用来干什么的呢?

/*startthetimer*/

s3c2410wdt_start();

//启动看门狗

returnnonseekable_open(inode,file);

staticints3c2410wdt_release(structinode*inode,structfile*file)

/*

*Shutoffthetimer.

*Lockitinifit'

samoduleandwesetnowayout

if(allow_close==CLOSE_STATE_ALLOW)

s3c2410wdt_stop();

else{

dev_err(wdt_dev,"

Unexpectedclose,notstoppingwatchdog\n"

s3c2410wdt_keepalive();

}

clear_bit(0,&

open_lock);

//释放锁

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))//用户空间到内核空间

return-EFAULT;

if(c=='

V'

)//如果写入了V,允许关闭

allow_close=CLOSE_STATE_ALLOW;

}

returnlen;

#defineOPTIONSWDIOF_SETTIMEOUT|WDIOF_KEEPALIVEPING|WDIOF_MAGICCLOSE

staticconststructwatchdog_infos3c2410_wdt_ident={

.options=OPTIONS,

.firmware_version=0,

.identity="

S3C2410Watchdog"

};

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:

return0;

caseWDIOC_SETTIMEOUT:

if(get_user(new_margin,p))

return-EFAULT;

if(s3c2410wdt_set_heartbeat(new_margin))

returnput_user(tmr_margin,p);

caseWDIOC_GETTIMEOUT:

default:

return-ENOTTY;

/*kernelinterface*/

staticconststructfile_operationss3c2410wdt_fops={

.owner=THIS_MODULE,

.llseek=no_llseek,

.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"

s3c2410wdt_keepalive();

//喂狗

returnIRQ_HANDLED;

/*deviceinterface*/

staticints3c2410wdt_probe(structplatform_device*pdev)

/*入口参数

structplatform_devices3c_device_wdt={

s3c2410-wdt"

.id=-1,

.num_resources=ARRAY_SIZE(s3c_wdt_resource),

.resource=s3c_wdt_resource,

#defineARRAY_SIZE(x)(sizeof(x)/sizeof((x)[0]))

说明:

num_resources:

设备占用的资源数量

staticstructresources3c_wdt_resource[]={

[0]={

.start=S3C24XX_PA_WATCHDOG,

S3C24XX_PA_WATCHDOG等于(0x53000000)

WTCON寄存器的物理地址即为0x53000000

.end=S3C24XX_PA_WATCHDOG+S3C24XX_SZ_WATCHDOG-1,

S3C24XX_SZ_WATCHDOG等于0x00100000

.flags=IORESOURCE_MEM,

该标志用来资源的类型

},

[1]={

.start=IRQ_WDT,

.end=IRQ_WDT,

#defineIRQ_WDT17/*0x00020000*/

.flags=IORESOURCE_IRQ,

structresource*res;

structdevice*dev;

unsignedintwtcon;

intstarted=0;

intret;

intsize;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1