📄 misc-watchdog-1.c
字号:
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(10);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(5);
}
udelay(20);
cmd=add2;
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(10);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(5);
}
udelay(20);
for( j=0;j<len;j++ )
{
//Read DATA
for( i=1;i<=8;i++ )
{
read_data=read_data<<1;
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
//Data in
if( (AT91_SYS->PIOC_PDSR&FM_SI) != 0 )
read_data|=1;
else
read_data&=0xfe;
udelay(10);
}
p[j]=read_data;
}
AT91_SYS->PIOD_SODR=FM_CS1;
//printk("\nread data= %d,%d,%d,%d,%d,%d,%d,%d\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7] );
return( j );
}
//-----------------------------------------------------------------------------------------------------
//----------------write data to Fram 2
//-----------------------------------------------------------------------------------------------------
static void write_to_fm_2( unsigned char add1,unsigned char add2,unsigned char len,unsigned char *p )
{
int i,j;
unsigned char bit;
unsigned char cmd=0x05;
unsigned char read_data=0;
//write write-enabe command
cmd=0x06;
AT91_SYS->PIOD_SODR=FM_CS1;
AT91_SYS->PIOD_CODR=FM_CS2;
udelay(10);
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(5);
}
AT91_SYS->PIOD_SODR=FM_CS2;
udelay(20);
//write command
cmd=0x02;
AT91_SYS->PIOD_CODR=FM_CS2;
udelay(10);
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(5);
}
udelay(20);
cmd=add1;
AT91_SYS->PIOD_CODR=FM_CS2;
udelay(10);
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(5);
}
udelay(20);
cmd=add2;
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(5);
}
udelay(20);
for( j=0;j<len;j++ )
{
cmd=*p;
p++;
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(5);
}
}
AT91_SYS->PIOD_SODR=FM_CS2;
udelay(20);
}
//------------------------------------------------------------------------------------------------------------
//------------read data from Fram 2
//------------------------------------------------------------------------------------------------------------
static unsigned char read_from_fm_2( unsigned char add1,unsigned char add2,unsigned char len,unsigned char *p )
{
int i,j;
unsigned char bit;
unsigned char cmd=0x05;
unsigned char read_data=0;
unsigned char read[10];
//write read command
cmd=0x03;
AT91_SYS->PIOD_SODR=FM_CS1;
AT91_SYS->PIOD_CODR=FM_CS2;
udelay(10);
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(10);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(5);
}
udelay(20);
cmd=add1;
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(10);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(5);
}
udelay(20);
cmd=add2;
for( i=0;i<=7;i++ )
{
//CMD Output
bit=( cmd<<i )&0x80;
if( bit )
AT91_SYS->PIOC_SODR=FM_SO;
else
AT91_SYS->PIOC_CODR=FM_SO;
udelay(5);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
udelay(10);
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(5);
}
udelay(20);
for( j=0;j<len;j++ )
{
//Read DATA
for( i=1;i<=8;i++ )
{
read_data=read_data<<1;
//CLK High
AT91_SYS->PIOC_SODR=FM_SCK;
udelay(10);
//CLK Low
AT91_SYS->PIOC_CODR=FM_SCK;
//Data in
if( (AT91_SYS->PIOC_PDSR&FM_SI) != 0 )
read_data|=1;
else
read_data&=0xfe;
udelay(10);
}
p[j]=read_data;
}
AT91_SYS->PIOD_SODR=FM_CS2;
//printk("\nread data= %d,%d,%d,%d,%d,%d,%d,%d\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7] );
return( j );
}
static struct my_data_of_fram do_fm( struct my_data_of_fram mm )
{
if( mm.flag_of_which_fram==0x01 )//fram 1
{
if( mm.flag_of_command==0x01 )//write
{
write_to_fm_1( mm.add1,mm.add2,mm.len,mm.data_buffer );
}
else
if( mm.flag_of_command==0x02 )//read
{
read_from_fm_1( mm.add1,mm.add2,mm.len,mm.data_buffer );
}
}
else
if( mm.flag_of_which_fram==0x02 )//fram 2
{
if( mm.flag_of_command==0x01 )//write
{
write_to_fm_2( mm.add1,mm.add2,mm.len,mm.data_buffer );
}
else
if( mm.flag_of_command==0x02 )//read
{
read_from_fm_2( mm.add1,mm.add2,mm.len,mm.data_buffer );
}
}
return mm;
}
static void watchdog_ping(void)
{
if( aaa==0x00 )
{
AT91_SYS->PIOA_CODR=USER_LED1;
aaa=0xff;
}
else
{
AT91_SYS->PIOA_SODR=USER_LED1;
aaa=0x00;
}
}
/*
* Allow only one person to hold it open
*/
//wdt设备打开操作
static int wdt977_open(struct inode *inode, struct file *file)
{
// if(timer_alive) //计数器,当wdt被启用后进制重复打开!
// return -EBUSY;
#ifdef CONFIG_WATCHDOG_NOWAYOUT
MOD_INC_USE_COUNT;
#endif
timer_alive++;
//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
if( timeout>255 )
timeout=255;
// printk("Watchdog: active, current timeout %d min.\n",timeout);
return 0;
}
//wdt的关闭操作
static int wdt977_release(struct inode *inode, struct file *file)
{
/*
* Shut off the timer.
* Lock it in if it's a module and we defined ...NOWAYOUT
*/
#ifndef CONFIG_WATCHDOG_NOWAYOUT
lock_kernel();
timer_alive=0;
unlock_kernel();
// printk("Watchdog: shutdown.\n");
#endif
// printk("Watchdog: shutdown.\n");
timer_alive=0;
return 0;
}
ads7843_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
// DECLARE_WAITQUEUE(wait, current);
// struct ads7843_ts *ts = filp->private_data;
char *ptr = buffer;
int err = 0;
/*
add_wait_queue(&ts->read_wait, &wait);
while (count >= sizeof(struct ts_event))
{
err = -ERESTARTSYS;
if (signal_pending(current))
break;
if (ads7843_ts_evt_pending(ts))
{
struct ts_event *evt = ads7843_ts_evt_get(ts);
err = copy_to_user(ptr, evt, sizeof(struct ts_event));
ads7843_ts_evt_pull(ts);
if (err)
break;
ptr += sizeof(struct ts_event);
count -= sizeof(struct ts_event);
continue;
}
set_current_state(TASK_INTERRUPTIBLE);
err = -EAGAIN;
if (filp->f_flags & O_NONBLOCK)
break;
schedule();
}
current->state = TASK_RUNNING;
remove_wait_queue(&ts->read_wait, &wait);
*/
return ptr == buffer ? err : ptr - buffer;
}
//在这里wdt的写就是“喂狗”操作
static ssize_t wdt977_write(struct file *file, const char *data, size_t len, loff_t *ppos)
{
//max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog.
if (timeout>255)
timeout=255;
/*
* Refresh the timer.
*/
//we have a hw bug somewhere, so each 977 minute is actually only 30sec
//as such limit the max timeout to half of max of 255 minutes...
// if (timeout>126)
// timeout = 126;
return 1;
}
struct wd
{
int a;
int b;
int c;
};
static struct wd wd2;
//wdt的ioctl函数
static int watchdog_ioctl( struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg )
{
int i, new_margin;
struct my_time m_time;
struct my_date m_date;
struct my_data_of_fram my_fram1;
int ret=0;
switch( cmd )
{
case 10:
m_date=my_read_date();
return copy_to_user((void *) arg, &m_date, sizeof(m_date));
case 11:
m_time=my_read_time();
return copy_to_user((void *) arg, &m_time, sizeof(m_time));
case 12:
if (copy_from_user(&m_date, (struct my_date *) arg, sizeof(m_date)))
ret = -EFAULT;
write_rtc_date( m_date );
return 0x00;
case 13:
if (copy_from_user(&m_time, (struct my_time *) arg, sizeof(m_time)))
ret = -EFAULT;
write_rtc_time( m_time );
return 0x00;
case 14:
if (copy_from_user(&my_fram1, (struct my_data_of_fram *) arg, sizeof(my_fram1)))
ret = -EFAULT;
my_fram1=do_fm( my_fram1 );
if( my_fram1.flag_of_command==0x02 )
return copy_to_user( (void *) arg, &my_fram1, sizeof(my_fram1) );
return my_fram1.len;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
case WDIOC_KEEPALIVE:
watchdog_ping();
return 0;
default:
return -ENOTTY;
}
}
//定义fops结构,开发驱动对struct file_operations 再熟悉不过了。
//函数的入口很简单,这就是为什么采用misc的原因了
static struct file_operations wdt977_fops=
{
owner: THIS_MODULE,
write: wdt977_write,
read: ads7843_ts_read,
open: wdt977_open,
ioctl: watchdog_ioctl,
release: wdt977_release,
};
//根据misc驱动模型要求,定义miscdevice 结构体
static struct miscdevice wdt977_miscdev=
{
minor: WATCHDOG_MINOR,
name: "wd",
fops: &wdt977_fops,
};
static int __init nwwatchdog_init(void)
{
// if (!machine_is_netwinder())
// return -ENODEV;
AT91_SYS->PIOA_PER=USER_LED1;//用作通用IO
AT91_SYS->PMC_PCER = 0x0000001c;
AT91_SYS->PIOA_OER=USER_LED1;//用作输出
AT91_SYS->PIOA_SODR=USER_LED1;//输出高电平
AT91_SYS->PIOD_PER=TOUCH_CS1|TOUCH_CS2|FM_CS1|FM_CS2;
AT91_SYS->PIOD_OER=TOUCH_CS1|TOUCH_CS2|FM_CS1|FM_CS2;
AT91_SYS->PIOD_SODR=TOUCH_CS1|TOUCH_CS2|FM_CS1|FM_CS2;
AT91_SYS->PIOC_PER=FM_SCK|FM_SI|FM_SO;
AT91_SYS->PIOC_OER=FM_SCK|FM_SO;
AT91_SYS->PIOC_ODR=FM_SI;
AT91_SYS->PIOC_SODR=FM_SO;
AT91_SYS->PIOC_CODR=FM_SCK;
AT91_SYS->PIOB_PER=MY_RTC_CS|MY_RTC_SCK|MY_RTC_IO;
AT91_SYS->PIOB_OER=MY_RTC_CS|MY_RTC_SCK|MY_RTC_IO;
AT91_SYS->PIOB_CODR=MY_RTC_CS|MY_RTC_SCK|MY_RTC_IO;
misc_register(&wdt977_miscdev); //注册设备驱动
// printk("NetWinder Watchdog sleeping.\n");
return 0;
}
static void __exit nwwatchdog_exit(void)
{
misc_deregister(&wdt977_miscdev); //卸载设备驱动
}
EXPORT_NO_SYMBOLS;
module_init(nwwatchdog_init);
module_exit(nwwatchdog_exit);
//MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -