历史上的今天
返回首页

历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2018年10月12日 | Tiny210驱动之按键中断实验

2018-10-12 来源:eefocus

third_drv.c驱动源码:

#include "linux/device.h"

#include "linux/interrupt.h"

#include "linux/module.h"

#include "linux/kernel.h"

#include "linux/fs.h"

#include "linux/init.h"

#include "linux/delay.h"

#include "linux/irq.h"

#include "asm/uaccess.h"

#include "asm/irq.h"

#include "asm/io.h"

#include "mach/gpio.h"

static struct class *thirddrv_class;

volatile unsigned long *gph2con;

volatile unsigned long *gph2dat;

volatile unsigned long *gph3con;

volatile unsigned long *gph3dat;

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

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

static volatile int ev_press = 0;

struct pin_desc{

    unsigned int pin;

    unsigned int key_val;

};

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

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

static unsigned char key_val;

struct pin_desc pins_desc[5] = {

    {S5PV210_GPH2(3), 0x01},

    {S5PV210_GPH3(0), 0x02},

    {S5PV210_GPH3(1), 0x03},

    {S5PV210_GPH3(2), 0x04},

    {S5PV210_GPH3(3), 0x05},

};

// 确定按键值 

static irqreturn_t buttons_irq(int irq, void *dev_id)

{

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

    unsigned int pinval;

    

    pinval = gpio_get_value(pindesc->pin);

    if (pinval)

    {

        // 松开 

        key_val = 0x80 | pindesc->key_val;

    }

    else

    {

        // 按下 

        key_val = pindesc->key_val;

    }

    ev_press = 1;                           // 表示中断发生了 

    wake_up_interruptible(&button_waitq);   // 唤醒休眠的进程 

    

    return IRQ_RETVAL(IRQ_HANDLED);

}

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

{

    // 注册中断 

    request_irq(IRQ_EINT(19),  buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                        "K4", &pins_desc[0]);

    request_irq(IRQ_EINT(24),  buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                        "K5", &pins_desc[1]);

    request_irq(IRQ_EINT(25), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                         "K6", &pins_desc[2]);

    request_irq(IRQ_EINT(26), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 

                         "K7", &pins_desc[3]);    

    request_irq(IRQ_EINT(27), buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,

                         "K8", &pins_desc[4]);    

    return 0;

}

ssize_t third_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 third_drv_close(struct inode *inode, struct file *file)

{

    free_irq(IRQ_EINT(19), &pins_desc[0]);

    free_irq(IRQ_EINT(24), &pins_desc[1]);

    free_irq(IRQ_EINT(25), &pins_desc[2]);

    free_irq(IRQ_EINT(26), &pins_desc[3]);

    free_irq(IRQ_EINT(27), &pins_desc[4]);

    return 0;

}

static struct file_operations sencod_drv_fops = {

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

    .open    =  third_drv_open,     

    .read     =  third_drv_read,       

    .release =  third_drv_close,       

};

int major;

static int third_drv_init(void)

{

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

    thirddrv_class = class_create(THIS_MODULE, "third_drv");

    device_create(thirddrv_class, NULL, MKDEV(major, 0), NULL, "buttons"); // /dev/buttons 

    gph2con = (volatile unsigned long *)ioremap(0xe0200c40, 16);

    gph2dat = gph2con + 1;

    gph3con = (volatile unsigned long *)ioremap(0xE0200C60, 16);

    gph3dat = gph3con + 1;

    return 0;

}

static void third_drv_exit(void)

{

    unregister_chrdev(major, "third_drv");

    device_destroy(thirddrv_class, MKDEV(major, 0));

    class_destroy(thirddrv_class);

    iounmap(gph2con);

    iounmap(gph3con);

    return 0;

}

module_init(third_drv_init);

module_exit(third_drv_exit);

MODULE_LICENSE("GPL");

===================================================================

thirddrvtest.c测试程序:

#include "sys/types.h"

#include "sys/stat.h"

#include "fcntl.h"

#include "stdio.h"

// thirddrvtest 

int main(int argc, char **argv)

{

    int fd;

    unsigned char key_val;

    

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

    if (fd < 0)

    {

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

    }

    while (1)

    {

        read(fd, &key_val, 1);

        printf("key_val = 0x%x\n", key_val);

    }

    

    return 0;

}


推荐阅读

史海拾趣

Amkor公司的发展小趣事

Amkor Technology是一家全球领先的半导体封装和测试服务提供商。以下是关于Amkor公司发展的五个相关故事:

  1. 成立与早期发展:Amkor Technology成立于1968年,总部位于美国亚利桑那州的钱德勒市。公司最初是一家小型半导体封装服务提供商,专注于为集成电路制造商提供先进的封装解决方案。在成立初期,Amkor致力于技术创新和质量控制,赢得了客户的信任和认可。

  2. 技术创新与产品多样化:随着电子行业的发展和技术的进步,Amkor不断进行技术创新,并扩展了产品线。公司推出了一系列新的封装技术和解决方案,包括先进的3D封装、薄型封装、系统封装等。这些技术创新和产品多样化使得Amkor能够满足不同客户的需求,并保持在市场竞争中的领先地位。

  3. 全球布局与生产基地建设:为了更好地服务全球客户,Amkor在全球范围内建立了多个生产基地和分销中心。除了在美国的设施外,公司还在亚洲、欧洲和其他地区建立了生产工厂和研发中心。这种全球布局有助于降低生产成本、提高生产效率,并加强了在全球市场的竞争力。

  4. 合作伙伴关系与客户服务:Amkor与全球各种半导体制造商建立了紧密的合作伙伴关系,共同推动技术创新和产品发展。公司致力于为客户提供优质的封装和测试解决方案,并与客户密切合作,开发定制化的解决方案。Amkor的客户服务团队提供全方位的技术支持和服务,确保客户的满意度和业务成功。

  5. 持续发展与业绩表现:Amkor持续实现了稳健的增长和良好的业绩表现。公司不断投入研发,并提升生产效率和管理水平,以提高盈利能力和市场竞争力。Amkor的业绩稳步增长,为股东创造了可观的价值,并使得公司成为半导体封装和测试服务领域的领先企业之一。

这些故事展示了Amkor Technology从成立初期到如今在技术创新、产品多样化、全球布局、合作伙伴关系建设和持续发展等方面取得的重要进展。

成都芯进(CrossChip)公司的发展小趣事

2023年6月,成都芯进电子宣布完成超1亿元A轮融资。这一轮融资的成功,不仅为公司的发展提供了充足的资金保障,也吸引了更多知名产业机构和投资基金的关注。公司借此机会扩大了研发团队和生产规模,进一步提升了产品的研发和生产能力。

Elec & Eltek公司的发展小趣事

随着市场需求的不断变化,Elec公司意识到单一产品已无法满足客户的多样化需求。于是,Elec公司开始寻求与同行业公司的合作。在一次行业交流会上,Elec公司的代表与Eltek公司的代表相识,并发现双方的产品具有很强的互补性。经过多次深入交流,Elec公司与Eltek公司决定开展合作,共同研发具有更高性能、更广泛应用的电子产品。这一合作不仅增强了双方的竞争力,也为客户提供了更多样化的选择。

Eurotech公司的发展小趣事

随着全球对环保问题的日益关注,Eurofarad公司也积极响应这一趋势。公司注重环保理念在产品设计和生产过程中的应用,努力减少对环境的影响。同时,公司还积极推动可持续发展战略,通过优化生产流程和采用环保材料等方式,降低能源消耗和废弃物排放。这些努力不仅符合了社会的期望,也为公司的长期发展提供了有力保障。

Charcroft Electronics Ltd公司的发展小趣事

在竞争激烈的电子行业中,供应链管理是企业成功的关键之一。Charcroft Electronics Ltd公司注重优化供应链管理,通过与供应商建立长期稳定的合作关系,确保原材料的质量和供应的稳定性。同时,公司还采用先进的供应链管理技术,实现库存的精准控制和物流的高效运作,提高了运营效率和市场响应速度。

和芯润德(CoreChips)公司的发展小趣事

和芯润德深知产品质量对于企业发展的重要性。因此,公司建立了严格的质量管理体系,从原材料采购到生产过程的每一个环节都进行严格把关。此外,公司还引进了先进的检测设备和技术手段,确保产品的可靠性和稳定性。这种对质量的严格把控使和芯润德的产品在市场上赢得了良好的口碑。

问答坊 | AI 解惑

组装好仪器后液晶屏花屏

我的仪器组装好后,就是把板子和液晶装到外壳后,液晶在过一段时间后就会花屏,不装到外壳里就没事,弄了好长时间了也不知道怎么回事,请大家帮忙。…

查看全部问答>

WinCE5.0挂接IDE硬盘的疑惑?

WinCE5.0挂接IDE硬盘的疑惑? 有个项目,想使用IDE44pin接口挂接最少64GB的外部存储器,现有如下问题和大家讨论: 1.工作电压: 现在手头上的IDE电路是直接从S3C2440上IO口引出,鉴于3.3V的IO电压,似乎不能正常驱 ...…

查看全部问答>

本人大四学生

已经学习了c51单片机,想问下各位老师,如果以后要从事单片机开发的话,需要再学习哪些大学未传授的知识,谢谢…

查看全部问答>

求binArrayStart和binArrayEnd的定义的线索

问题描述:         大家好。我最近在修改Boot程序。在bootinit.c文件中有如下定义: IMPORT UCHAR        binArrayStart [];                    & ...…

查看全部问答>

问个mfc应用的问题??

在dialog中有个tab control,在每个tab的dialog中有个group box, group box中有个按钮。 现在的现实结果是tab control和group box都显示正常,按钮没有显示,什么原因? app方面菜鸟一个,期待大家指点…

查看全部问答>

单片机的问题

提高单片机 WR,RD 驱动能力一般用什么芯片啊…

查看全部问答>

【芯币兑换】AVR单片机学习板及编程器最详细元器件清单

一、USB型51/AVR单片机编程器元器件清单   二、AVR ATmega16单片机学习板元器件清单           [ 本帖最后由 tiankai001 于 2010-8-8 15:35 编辑 ]…

查看全部问答>

一个2407产生对称PWM的问题````

因为刚学DSP,做的是用2407产生6路3对对称PWM,一开始摸索的时候程序老是编译有问题,今天才把程序搞好``却发现我的板子出了问题,因为编的第一个程序所以没有把挖想放上来大家帮我看看这样写是不是能产生6路3对对称PWM``` 主程序如下 #include \\" ...…

查看全部问答>

求一可用的串口通讯程序

折腾了好几天,实在弄不出来了,哪位有好使的串口程序赏一个,谢谢了。…

查看全部问答>

基于LED点阵显示屏9路抢答器的设计制作程序

基于LED点阵显示屏9路抢答器的设计制作程序…

查看全部问答>