特殊按键--休眠键驱动
这是一个关于休眠和关机的按键驱动。板子:pxa31X系列 内核:2.6.25这个驱动用到了内核文件操作,内核线程,等待队列,异步通知,并介绍了一种调试驱动的方法。
[cpp]
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/pxa3xx-regs.h>
#include <asm/arch/mfp-pxa300.h>
#include <asm/arch/gpio.h>
#include <asm/uaccess.h> //用于内核线程
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <asm/semaphore.h>
#include "pmb.h"
#define PB_DEVICE_NAME "william_pmb"
//#define DEBUG
#ifdef DEBUG
#define pr_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg)
#else
#define pr_debug(fmt, arg...) printk(KERN_INFO fmt, ##arg)
#endif
/*
用于调试驱动的一种方法。
其中printk函数中的参数,定义于<linux/kernel.h>。
#define KERN_EMERG "<0>" /* system is unusable紧急事件消息,系统崩溃前提示,表示系统不可用*/
#define KERN_ALERT "<1>" /* action must be taken immediately 报告消息,表示必须马上采取措施*/
#define KERN_CRIT "<2>" /* critical conditions临界情况,通常用于涉及严重的硬件或软件操作失败*/
#define KERN_ERR "<3>" /* error conditions错误情况,驱动程序常用来报告硬件错误*/
#define KERN_WARNING "<4>" /* warning conditions警告,对可能出现问题的情况进行警告*/
#define KERN_NOTICE "<5>" /* normal but significant condition正常但又重要的情况,常用于提醒与安全相关的消息*/
#define KERN_INFO "<6>" /* informational提示信息*/
#define KERN_DEBUG "<7>" /* debug-level messages调试级别消息*/
*/
/*硬件上的一些定义*/
#define PECR_E0IS (1 << 29) // EXT_WAKEUP<0> Interrupt Status
#define PECR_E0IE (1 << 28) // EXT_WAKEUP<0> Pin Interrupt Enable
#define PECR_DIR0(1 << 4) //Direction for EXT_WAKEUP<0>: 0/1= input/output
#define PECR_IVE0 (1 << 0) //Input Value for EXT_WAKEUP<0>
//Currently we have
#define IRQ_WAKEUP0 PXA_IRQ(49) /* EXT_WAKEUP0 */
#define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */
//一个重要的全局结构体
static struct powerkey_t pwk;
/*
struct powerkey_t
{
int ifopen; //check if device is opened
unsigned int pressed; //current key state [0/1=release/press]
int event; //event: [0/1/2/3=narmal/sleep/deepsleep/wakeup]
wait_queue_head_t keywaitq; //powerkey queue
struct tast_struct *p_thread;
int checkforsleep; //check if which event for sleep
int ifhandshake; //check if need to handshake with app[]
int handshake;
struct fasync_struct *pwrkey_async_queue;
int ifreleasehandshakecnt; //0: you can release handshake. >0: can't release handshake
};
*/
static int pb_handshake(int sig,int mode);
static int wakeup_init(void)
{
PECR |= PECR_E0IE; //enable wakeup0 interrupt
PECR &= ~PECR_DIR0; //as input
return 0;
}
static int disable_wakeup(void)
{
PECR &= ~PECR_E0IE; //disable wakeup0 interrupt
return 0;
}
static int wakeup_ack_irq(void)
{
PECR |= PECR_E0IS; //interrupt state, write 1 to clear
return 0;
}
static int pb_sleep_exe(int sleep)
{
int ret;
struct file *fd;
mm_segment_t old_fs;
//printk("%s\n",__FUNCTION__);
fd = filp_open("sys/power/state",O_RDWR,0);
if(IS_ERR(fd))
{
printk("Open sys/power/state fail,ret = %ld \n",IS_ERR(fd));
return -1;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
switch(sleep)
{
case SLEEP_EVENT:
printk("sleep!\n");
ret = fd->f_op->write(fd,"mem",3,&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)
补充:软件开发 , C++ ,
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊