历史上的今天
返回首页

历史上的今天

今天是:2024年09月16日(星期一)

2019年09月16日 | 驱动-按键-中断模式

2019-09-16 来源:eefocus

驱动-按键-中断模式




eint_drv.c


/*******驱动代码************/

 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

 

static struct class *eintdrv_class;

static struct class_device *eintdrv_class_dev;

 

volatile unsigned long *gpfcon;

volatile unsigned long *gpfdat;

 

volatile unsigned long *gpgcon;

volatile unsigned long *gpgdat;

 

/*声明等待队列头,名字为button_waitq*/

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

 

/* 中断事件标志, 中断服务程序将它置1,eint_drv_read将它清0 */

static volatile int ev_press = 0;

 

 

struct pin_desc{

unsigned int pin;

unsigned int key_val;

};

 

 

/* 键值: 按下时, 0x01, 0x02, 0x03, 0x04 */

/* 键值: 松开时, 0x81, 0x82, 0x83, 0x84 */

static unsigned char key_val;

 

struct pin_desc pins_desc[4] = {

{S3C2410_GPF0, 0x01},

{S3C2410_GPF2, 0x02},

{S3C2410_GPG3, 0x03},

{S3C2410_GPG11, 0x04},

};

 

 

/*

  * 确定按键值

  */

static irqreturn_t buttons_irq(int irq, void *dev_id)

{

struct pin_desc * pindesc = (struct pin_desc *)dev_id;

unsigned int pinval;

pinval = s3c2410_gpio_getpin(pindesc->pin);

 

if (pinval)

{

/* 松开 */

key_val = 0x80 | pindesc->key_val;

printk("pinval1=%dn", pinval);

 

}

else

{

/* 按下 */

key_val = pindesc->key_val;

printk("pinval2=%dn", pinval);

}

 

  /* 表示中断发生了 */

  ev_press=1;

 

  /* 唤醒休眠的进程 */

  wake_up_interruptible(&button_waitq);

 

 

return IRQ_RETVAL(IRQ_HANDLED);

}

 

static int eint_drv_open(struct inode *inode, struct file *file)

{

/* 配置GPF0,2为输入引脚 */

//*gpfcon &= ~((3<<4)|(3<<0));

*gpfcon &=~((1<<0)|(1<<2));

 

/* 配置GPG3,11为输入引脚 */

//*gpgcon &= ~((3<<6)|(3<<22));

*gpgcon &= ~((1<<3)|(1<<11));

/*request_irq(中断类型,响应函数,触发方式,名称,数据)*/ 

request_irq(IRQ_EINT0, buttons_irq, IRQT_BOTHEDGE, "S2", &pins_desc[0]);

    request_irq(IRQ_EINT2, buttons_irq, IRQT_BOTHEDGE, "S3", &pins_desc[1]);

    request_irq(IRQ_EINT11, buttons_irq, IRQT_BOTHEDGE, "S4", &pins_desc[2]);

    request_irq(IRQ_EINT19, buttons_irq, IRQT_BOTHEDGE, "S5", &pins_desc[3]);  

 

 

 

return 0;

}

 

ssize_t eint_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)

{

if (size != 1)

return -EINVAL;

 

/* 如果没有按键动作, 休眠 */

wait_event_interruptible(button_waitq,ev_press);

 

/* 如果有按键动作, 返回键值 */

copy_to_user(buf, &key_val, 1);

ev_press = 0;

return 1;

}

 

 

int eint_drv_close(struct inode *inode, struct file *file)

{

/*free_irq*/

free_irq(IRQ_EINT0,&pins_desc[0]);

free_irq(IRQ_EINT2,&pins_desc[1]);

free_irq(IRQ_EINT11,&pins_desc[2]);

free_irq(IRQ_EINT19,&pins_desc[3]);

 

return 0;

}

 

 

static struct file_operations sencod_drv_fops = {

    .owner   =  THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

    .open    =  eint_drv_open,     

.read = eint_drv_read,    

.release =  eint_drv_close,    

};

 

 

int major;

static int eint_drv_init(void)

{

major = register_chrdev(0, "eint_drv", &sencod_drv_fops);

 

eintdrv_class = class_create(THIS_MODULE, "eint_drv");

 

eintdrv_class_dev = class_device_create(eintdrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); /* /dev/buttons */

 

gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);

gpfdat = gpfcon + 1;

 

gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16);

gpgdat = gpgcon + 1;

 

return 0;

}

 

static void eint_drv_exit(void)

{

unregister_chrdev(major, "eint_drv");

class_device_unregister(eintdrv_class_dev);

class_destroy(eintdrv_class);

iounmap(gpfcon);

iounmap(gpgcon);

return 0;

}

 

 

module_init(eint_drv_init);

 

module_exit(eint_drv_exit);

 

MODULE_LICENSE("GPL");

 


eintTest.c



#include

#include

#include

#include

#include

 

/* thirddrvtest 

  */

int main(int argc, char **argv)

{

int fd;

unsigned char key_val;

fd = open("/dev/eintTest", O_RDWR);//O_RDWR 读、写打开。

if (fd < 0)

{

printf("can't open!n");

}

 

while (1)

{

read(fd, &key_val, 1);

printf("key_val = 0x%xn", key_val);

sleep(5);

}

return 0;

}

 


makefile

KERN_DIR = /work/system/linux-2.6.22.6

 

all:

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

 

clean:

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

rm -rf modules.order

 

obj-m += eint_drv.o

推荐阅读

史海拾趣

Davies Molding公司的发展小趣事

Davies Molding公司在追求经济效益的同时,始终关注社会责任和可持续发展。公司积极参与环保公益活动,推动绿色生产,降低对环境的影响。此外,Davies Molding公司还注重员工福利和社会公益事业,为员工提供良好的工作环境和发展空间,为社会做出积极贡献。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实基础。

Elytone Electronics Co Ltd公司的发展小趣事

在技术创新取得突破后,Elytone公司开始积极拓展国内外市场。他们通过参加国际电子展、建立海外销售网络等方式,不断扩大产品的影响力。同时,公司还加强了与国内外知名企业的合作,共同研发新产品,进一步提升了市场竞争力。

ETI Systems公司的发展小趣事

随着公司业务的不断发展壮大,ETI Systems开始将目光投向国际市场。公司积极参加国际电子产品展览和技术交流活动,与来自世界各地的客户和合作伙伴建立了紧密的联系。同时,ETI Systems也加大了在海外市场的投入力度,通过设立分公司和办事处等方式,进一步拓宽了国际市场渠道。这种国际化战略的实施,为ETI Systems的持续发展注入了新的活力。

BRIGHT公司的发展小趣事

除了无线耳机和太阳能领域,BRIGHT公司还在健康技术领域取得了重要的突破。他们成功筹集了60万美元的资金,用于推动健康技术的持续增长和扩张。这笔资金使得BRIGHT公司能够在其成功的基础上,进一步研发和推广基于科学的认知健康解决方案。他们的产品,如40赫兹灯,无需医生处方即可普遍使用,为广大消费者提供了更加便捷和科学的健康管理方式。

国炬(GOOGLL)公司的发展小趣事
OCL电路能够驱动低阻抗的负载,提高了系统的整体效率。
Hexawave公司的发展小趣事
静态工作点的设置对功放电路的性能有重要影响。需要确保静态工作点稳定且适当,以避免出现交越失真等问题。

问答坊 | AI 解惑

keil下ARM的调试程序

uc/os的成功例程,也是从网上下的分享哈…

查看全部问答>

菜鸟参加电子设计大赛感悟!

本帖最后由 paulhyde 于 2014-9-15 08:54 编辑 今年暑假,我有幸参加了全国大学生电子设计大赛的培训.在学校提供的实验室里,我度过了紧张而又刺激的两个月时间.在有限的时间里,我学到了无穷的知识, 仿佛胜过两年的大学学业.在实验室,我感受到了前所 ...…

查看全部问答>

关于嵌入式

各位好! 我呢,以后想学嵌入式,但是对于嵌入式的学习路线还不是很明白。比如说哪些课程特别重要,主要学习什么语言还有就是中国高校目前对于该门课程制定的学习路线是什么,请各位参照自己的情况,给我指点迷津,谢谢!…

查看全部问答>

怎样利用数据分级来提高存储的准确率?

一、利用离线存储来提高设备的使用寿命。    存储在磁带设备上的数据一般可能很少用到。如企业需要对数据库等应用软件的数据进行备份。此时可以将数据备份到磁带设备上。根据惯例,一般一天24个小时这个磁带设备可能就只需要半个小时。 ...…

查看全部问答>

JTAG调试后怎么自动复位MCU

我在MDK下用Ulink2调试STM32,调试一次退出后,再进入调试模式就提示有问题,必须复位MCU才行。 烧写也是,烧写后必须复位MCU才能进入调试或者再烧写。 复位电路是参照的万利的板子,不知道要设置哪里。 谢谢了。…

查看全部问答>

求助M3程序下载问题

M3没法下载程序了  显示 Could not initialize target device!Please power cycle the board and try again!  哪位朋友知道为什么啊?非常感谢…

查看全部问答>

提示:你有新短消息,可又进不去,怎回事?

提示:你有新短消息,可又进不去,怎回事? 点击“您有新消息”,要求登录,因为已经登录,再登录不成,所以进不去。…

查看全部问答>

Sitara AM335x通用EVM硬件用户指南 CN_PDF

介绍 本文档介绍了AM335x评估模块(EVM)(TMDXEVM3358)这是基于德州仪器AM335x处理器的硬件体系结构。该EVM通常也被称为AM335x通用(GP)EVM。描述 AM335x通用EVM是一个独立的测试,开发和评估模块系统,它使开发人员能够编写周围的AM335x处理 ...…

查看全部问答>

nios2运行效率问题

搭建的CPU使用的时钟为100MHz,软件中连续使用IO_WR()直接对IO操作(赋值1和0)发现运行的时间不是10ns,而是1us左右,程序放在DDR中跑得,效率怎么会这么低,将程序放在片内跑,同样的程序,跑出来也不是10ns,而是接近200ns,相当于5M时钟在运行 ...…

查看全部问答>