特殊按键--休眠键驱动(二)
,&fd->f_pos);
if(ret != 3)
{
printk("Write to sleep fail!\n");
}
//printk("sleep write ok!\n");
break;
case DEEPSLEEP_EVENT:
ret = fd->f_op->write(fd,"deepsleep",9,&fd->f_pos);
if(ret != 9)
{
printk("Write to deepsleep fail!\n");
}
break;
default:
break;
}
set_fs(old_fs);
filp_close(fd ,NULL);
return 0;
}
/*
内核文件操作
strcut file* filp_open(const char* filename, int open_mode, int mode);
该函数返回strcut file*结构指针,供后继函数操作使用,该返回值用IS_ERR()来检验其有效性。
操作之前先要定位
void set_fs(mm_segment_t fs);
该函数的作用是改变kernel对内存地址检查的处理方式,其实该函数的参数fs只有两个取值:USER_DS,KERNEL_DS,分别代表用户空间和内核空间
get_fs(); 取得当前的设置
off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
offset是偏移量。
若origin是SEEK_SET(0),则将该文件的位移量设置为距文件开始处offset 个字节。
若origin是SEEK_CUR(1),则将该文件的位移量设置为其当前值加offset, offset可为正或负。
若origin是SEEK_END(2),则将该文件的位移量设置为文件长度加offset, offset可为正或负。
ret = fd->f_op->write(fd,"mem",3,&fd->f_pos); 文件读写函数
最后关闭文件 int filp_close(struct file*filp, fl_owner_t id);
*/
static int wait_wakeup_handshake(void)
{
int ret;
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
ppwk->event = WAKEUP_EVENT;
if(ppwk->ifopen > NOOPENED)
{
if(ppwk->ifhandshake == REQUESTHANDSHAKE)
{
if(pb_handshake(SIGIO,POLL_IN))
{
printk("Posting Handshake fail\n");
return -1;
}
else
{
ppwk->handshake = NONEEDHANDSHAKE;
ret = wait_event_interruptible_timeout(ppwk->keywaitq, ppwk->handshake == HANDSHAKE_EVENT_OK, (20*HZ));
if( ret == 0)
{
printk("Wake up handshake timeout\n");
}
}
}
else
{
ppwk->handshake = NONEEDHANDSHAKE;
ret = wait_event_interruptible_timeout(ppwk->keywaitq, ppwk->handshake == HANDSHAKE_EVENT_OK, (20*HZ));
if( ret == 0)
{
printk("Wake up handshake timeout\n");
}
}
}
ppwk->handshake = NONEEDHANDSHAKE;
return 0;
}
static irqreturn_t extwakeup_handle(int irq, void *dev_id)
{
int readreg;
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
wakeup_ack_irq();
readreg = PECR;
if(readreg & PECR_IVE0)
{
//printk("key is pressed !\n");
ppwk->checkforsleep = NEEDCHECKSLEEP;
ppwk->pressed = KEYPRESSED;
}
else
{
//printk("key released!\n");
ppwk->pressed = KEYRELEASE;
}
wake_up_interruptible(&ppwk->keywaitq);
wakeup_ack_irq();
return IRQ_HANDLED;
}
static int pb_irq_init(void)
{
int err;
//printk("%s\n",__FUNCTION__);
err = request_irq(IRQ_WAKEUP0, &extwakeup_handle,NULL,
"ext_wakeup0_detect", NULL);
return err;
}
static int preevent_sleep(const int sleepevent)
{
int ret;