历史上的今天
返回首页

历史上的今天

今天是:2025年10月14日(星期二)

正在发生

2022年10月14日 | mini2440 简单按键中断模式驱动程序

2022-10-14 来源:csdn

Makefile


KERN_DIR = /home/grh/kernel_source_code/linux-2.6.32.2

all : 

make -C $(KERN_DIR) M=`pwd` modules

arm-linux-gcc key_interrupt_app.c -o key_interrupt_app

clean :

make -C $(KERN_DIR) M=`pwd` modules clean

rm -rf modules.order

obj-m += key_interrupt.o

copy : 

cp key_interrupt.ko key_interrupt_app /nfs


驱动程序代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define GRH_MODULE_NAME "key_interrupt"

 

static int major;

static struct class *key_interrupt_class;

static struct class_device *key_interrupt_device; 

static int key_value;

 

//wait_event_interruptible函数需要的两个变量

static DECLARE_WAIT_QUEUE_HEAD(grh_wait_interrupt); //休眠的进程队列头

static volatile int sleep_for_interrupt; //这个变量为0的时候read函数会休眠,中断里面将其置1,read函数末尾将其设置为0

 

 

 

//pin_desc是对每一个按键中断的描述,不仅仅可以是整数,也可以是更复杂到的字段,这里用简单的按键值就行了

int pin_desc[6] = {

1, 2, 3, 4, 5, 6

};

 

 

//中断处理函数

static irqreturn_t grh_handle_key_eint(int irq, void *dev_id){

int *p;

p = dev_id;

 

//printk(KERN_EMERG"key pressed! key=%dn", *p);

key_value = *p;

 

//唤醒休眠的进程

sleep_for_interrupt = 1;

wake_up_interruptible(&grh_wait_interrupt);

 

return IRQ_HANDLED;

}

 

static void init_key(void){

//注册irq中断处理函数,将按键值和中断号绑定,所有清中断操作以及初始化中断相关寄存器的操作全部交给

//内核自动完成了,不再需要像裸机程序一样显式地对寄存器进行读写了,中断发生后会自动跳到grh_handle_key_eint

request_irq(IRQ_EINT8, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key1", pin_desc);

request_irq(IRQ_EINT11, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key2", pin_desc+1);

request_irq(IRQ_EINT13, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key3", pin_desc+2);

request_irq(IRQ_EINT14, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key4", pin_desc+3);

request_irq(IRQ_EINT15, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key5", pin_desc+4);

request_irq(IRQ_EINT19, grh_handle_key_eint, IRQ_TYPE_EDGE_BOTH, "key6", pin_desc+5);

}

 

static int key_interrupt_open(struct inode *inode, struct file *file){

printk(KERN_EMERG"DRIVER: OPENn");

sleep_for_interrupt = 0;

init_key();

return 0;

}

 

static ssize_t key_interrupt_write(struct inode *inode, const char __user *buf, size_t count, loff_t *ppos){

printk(KERN_EMERG"DRIVER: WRITEn");

return 0;

}

 

static ssize_t key_interrupt_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){

printk(KERN_EMERG"DRIVER: READn");

//根据sleep_for_interrupt的数值决定是否将驱动进程加进休眠队列grh_wait_interrupt中

wait_event_interruptible(grh_wait_interrupt, sleep_for_interrupt);

copy_to_user(buf, &key_value, 4);

 

//下一次进入read的时候继续休眠等待中断发生

sleep_for_interrupt = 0;

return 0;

}

 

int key_interrupt_release(struct inode *inode, struct file *file){

//注销中断

free_irq(IRQ_EINT8, pin_desc);

free_irq(IRQ_EINT11, pin_desc+1);

free_irq(IRQ_EINT13, pin_desc+2);

free_irq(IRQ_EINT14, pin_desc+3);

free_irq(IRQ_EINT15, pin_desc+4);

free_irq(IRQ_EINT19, pin_desc+5);

printk(KERN_EMERG"DRIVER: RELEASEn");

return 0;

}

 

 

static struct file_operations key_interrupt_fops = {

.owner = THIS_MODULE,

.open = key_interrupt_open,

.write = key_interrupt_write,

.read = key_interrupt_read,

.release = key_interrupt_release,

};

 

int key_interrupt_module_init(void){

printk(KERN_EMERG"INIT MODULE!n");

 

//register the driver with the device

major = register_chrdev(0, GRH_MODULE_NAME, &key_interrupt_fops);

 

//create my own device class

key_interrupt_class = class_create(THIS_MODULE, "key_interrupt_class");

//create my device of my own class

key_interrupt_device = device_create(key_interrupt_class, NULL, MKDEV(major,0), NULL, "key_interrupt_device");

 

return 0;

}

 

void key_interrupt_module_exit(void){

unregister_chrdev(major, GRH_MODULE_NAME);

device_unregister(key_interrupt_device);

class_destroy(key_interrupt_class);

printk(KERN_EMERG"EXIT MODULE!n");

}

 

module_init(key_interrupt_module_init);

module_exit(key_interrupt_module_exit);

 

MODULE_AUTHOR("GRH");

MODULE_VERSION("1.0");

MODULE_DESCRIPTION("KEY POLL DRIVER");

MODULE_LICENSE("GPL");



用户空间测试程序:

#include

#include

#include

#include

#include

#include

 

int main(void){

int fd;

int i, sum;

int key_value;

 

fd = open("/dev/key_interrupt_device", O_RDWR);

if(-1 == fd){

printf("open key device error!n");

return -1;

}

 

while(1){

read(fd, &key_value, 4);

printf("key pressed : %dn", key_value);

}

close(fd);

return 0;

}



按下按键之后的运行结果:

当没有按键按下的时候,测试程序进程在内核态处于休眠状态,这样比起轮询式的驱动而言,资源的消耗就小了太多了:



推荐阅读

史海拾趣

Davico Industrial Ltd公司的发展小趣事

Davico Industrial Ltd公司发展故事一:技术突破与创新

Davico Industrial Ltd公司自创立以来,始终将技术创新作为企业发展的核心动力。在公司成立初期,面对电子行业竞争激烈的局面,Davico凭借对市场的敏锐洞察和对技术的不断追求,成功研发出了一款具有划时代意义的电子元器件。这款产品以其高性能、低能耗的特点,迅速在市场中占据了一席之地。此后,Davico不断加大对研发的投入,通过引进高端人才、建立先进的研发实验室等举措,持续推出了一系列具有竞争力的新产品,为公司的发展奠定了坚实的基础。

Davico Industrial Ltd公司发展故事二:市场拓展与品牌建设

随着技术实力的不断增强,Davico开始积极拓展国内外市场。公司通过与国内外知名企业的合作,不断提升产品的知名度和美誉度。同时,Davico还积极参与各类行业展会和论坛,展示公司的最新成果和技术实力,赢得了广大客户的认可和信赖。在品牌建设方面,Davico注重塑造企业形象和文化内涵,通过广告宣传、公益活动等方式,提高了品牌的社会影响力和知名度。

Davico Industrial Ltd公司发展故事三:质量管理与持续改进

Davico深知产品质量对于企业生存和发展的重要性。因此,公司始终将质量管理放在首位,建立了完善的质量管理体系和检测手段。通过对生产过程的严格控制和对产品质量的不断追求,Davico的产品在市场中赢得了良好的口碑。同时,公司还积极开展持续改进活动,通过引进先进的生产设备和工艺、优化生产流程等措施,不断提高生产效率和产品质量。

Davico Industrial Ltd公司发展故事四:人才战略与团队建设

Davico高度重视人才队伍建设,通过制定合理的人才战略和激励机制,吸引了一批批优秀的人才加入公司。公司注重员工的培训和发展,通过定期的技能培训、知识更新等活动,不断提升员工的综合素质和专业技能。同时,Davico还建立了完善的团队协作机制,鼓励员工之间的沟通和合作,形成了一支高效、团结、富有战斗力的团队。

Davico Industrial Ltd公司发展故事五:绿色发展与社会责任

随着全球环保意识的不断提高,Davico积极响应国家绿色发展的号召,将环保理念融入到企业的生产经营中。公司通过引进环保设备、改进生产工艺等措施,降低了生产过程中的能耗和污染排放。同时,Davico还积极参与社会公益事业,通过捐款捐物、扶贫济困等方式,回馈社会、造福人民。这些举措不仅提升了企业的社会形象,也为公司的长远发展注入了新的动力。

Analog Power公司的发展小趣事

随着技术的不断进步,Analog Power公司始终保持着对技术创新的热情。他们不断研发新的电源管理技术和产品,推出了一系列具有高性能、高效率、低功耗特点的电源管理解决方案。这些创新产品不仅满足了客户的需求,也引领了市场的发展潮流,使得Analog Power在行业中逐渐崭露头角。

Connect-Tech Products Corp公司的发展小趣事

Connect-Tech Products Corp公司在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和节能技术,减少生产过程中的环境污染。此外,公司还积极参与公益事业,为社会做出贡献。这些举措不仅提升了公司的社会形象,也为其赢得了社会各界的广泛赞誉和支持。

请注意,以上故事是基于电子行业和公司发展的一般模式虚构的,并不代表Connect-Tech Products Corp公司的实际发展历程。如需了解该公司的真实情况,建议查阅相关新闻报道、公司年报或行业分析报告等资料。

Digital View公司的发展小趣事

Digital View公司成立于1995年,当时正值电子显示技术快速发展的时期。公司创始人凭借对数字显示技术的深刻理解和前瞻性的市场洞察力,决定专注于平板数字显示市场连接解决方案的研发和生产。在创业初期,公司面临资金短缺、技术瓶颈等多重困难,但团队凭借坚韧不拔的精神,成功开发出多款具有竞争力的产品,逐渐在市场上获得认可。

Fremont_Micro_Devices_USA公司的发展小趣事

为了进一步提升品牌影响力和市场竞争力,Digital View公司开始实施国际化战略。公司积极参加国际展览和论坛,与全球同行建立合作关系,引进先进技术和管理经验。同时,公司还在海外设立研发中心和生产基地,以便更好地服务全球客户。通过国际化战略的实施,Digital View的品牌知名度和市场份额均得到了显著提升。

Apex [Apex Microtechnology]公司的发展小趣事

在作为Cirrus Logic分公司运营了五年后,Apex Microtechnology于2012年重新回归独立私营状态。这次变革使得Apex Microtechnology能够更加灵活地应对市场变化,加速产品创新和研发。同时,公司也扩大了其业务范围,进一步巩固了在电子行业的地位。

问答坊 | AI 解惑

μC/OS—II的嵌入式串口通信模块设计

在嵌入式应用中,使用RTOS的主要原因是为了提高系统的可靠性,其次是提高开发效率、缩短开发周期。μC/OS-II是一个占先式实时多任务内核,使用对象是嵌入式系统,对源代码适当裁减,很容易移植到8~32位不同框架的微处理器上。但μC/OS-II仅是一个 ...…

查看全部问答>

不知道大家的示波器程序进展如何?

不知道大家的程序进展如何?是否可以和大家分享一下呢? [ 本帖最后由 daicheng 于 2009-8-13 16:45 编辑 ]…

查看全部问答>

【藏书阁】射频电路设计理论与应用

目录: 第1章 引言 .. 1.1 射频设计的重要性 .. 1.2 量纲和单位 .. 1.3 频谱 .. 1.4 无源元件的射频特性 .. 〖DW〗1.4.1 高频电阻 .. 〖DW〗1.4.2 高频电容 .. 〖DW〗1.4.3 高频电感 .. 1.5 片状元件及对电路板的考虑 . 1.5.1 片状电阻 ...…

查看全部问答>

监控摄像头监控蔬菜了

上海正全力加强158个迎世博重点蔬菜基地的建设,强化生产基地的监管,建立健全农产品质量安全可追溯体系。闵行区农委世博蔬菜基地除在场区实行全天候巡逻外,还在农田蔬菜大棚和装运车间安装了监控摄像头,实现世博重点蔬菜基地生产和运输过程的有 ...…

查看全部问答>

T9输入法 购买

问下大家:我们想购买T9输入法,但是http://www.t9.com/该产品根本没有提供联系方式呀,只要我留言,但是我留了又发不出去,真急人。有了解的朋友帮帮我哦:)…

查看全部问答>

请各位大侠们帮助,新装的WIN CE 5.0编译出现Invalid parameters passed to Wince.bat问题,怎么解决呀!急死人了,帮帮

小弟刚接触WIN CE ,刚装的WIN CE5.0安装后,新建工程编译出现Invalid parameters passed to Wince.bat问题,而且左边没有 OSDesign View标签.开始安装时因为有文件有2部分,WIN CE文件没有放在同一目录下,之后我将文件移动到了同一目录下,开始以 ...…

查看全部问答>

请版主给个STM32F105/107的USB的otg_fs的例程

                                 ST提供了USB的库,像我这种水平的人写不出程序来,还是要靠例程来理解熟悉的,版主能给个吗?最好是IAR下的.…

查看全部问答>

[提建议]建立一个语音教学及互动平台

[提建议]建立一个语音教学及互动平台 我相信在坛子里面的学生应该不少吧。想在EEWorld里学到一些实践的经验和如何做项目。 我们论坛中已经有了 但是,我觉得我们eeworld是还会有更多的想法和活动的. 如:     链接:https:/ ...…

查看全部问答>

TI ARM 产品全新拓展

TI旗下Cortex M3,A8及ARM9产品线,具有31种全新产品满足您不同的设计需求。 $(\'swf_W93\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\ ...…

查看全部问答>