datasheet

Tiny210按键互斥锁、原子变量驱动

2018-10-12来源: eefocus 关键字:Tiny210  按键互斥锁  原子变量驱动

sixth_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"

#include "linux/poll.h"

static struct class *sixthdrv_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,sixth_drv_read将它清0 

static volatile int ev_press = 0;

static struct fasync_struct *button_async;

struct pin_desc{

    unsigned int pin;

    unsigned int key_val;

};

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

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

static unsigned char 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 atomic_t canopen = ATOMIC_INIT(1); //定义原子变量并初始化为1

static DECLARE_MUTEX(button_lock);             //定义互斥锁

// 确定按键值

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);   // 唤醒休眠的进程 

    

    kill_fasync (&button_async, SIGIO, POLL_IN);

    

    return IRQ_RETVAL(IRQ_HANDLED);

}

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

{

#if 0    

    if (!atomic_dec_and_test(&canopen))

    {

        atomic_inc(&canopen);

        return -EBUSY;

    }

#endif        

    if (file->f_flags & O_NONBLOCK)

    {

        if (down_trylock(&button_lock))

            return -EBUSY;

    }

    else

    {

        // 获取信号量 

        down(&button_lock);

    }

    // 注册中断 

    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 sixth_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)

{

    if (size != 1)

        return -EINVAL;

    if (file->f_flags & O_NONBLOCK)

    {

        if (!ev_press)

            return -EAGAIN;

    }

    else

    {

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

        wait_event_interruptible(button_waitq, ev_press);

    }

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

    copy_to_user(buf, &key_val, 1);

    ev_press = 0;

    

    return 1;

}

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

{

    //atomic_inc(&canopen);

    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]);

    up(&button_lock);

    return 0;

}

static unsigned sixth_drv_poll(struct file *file, poll_table *wait)

{

    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait); // 不会立即休眠

    if (ev_press)

        mask |= POLLIN | POLLRDNORM;

    return mask;

}

static int sixth_drv_fasync (int fd, struct file *filp, int on)

{

    printk("driver: sixth_drv_fasync\n");

    return fasync_helper (fd, filp, on, &button_async);

}

static struct file_operations sencod_drv_fops = {

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

    .open     =  sixth_drv_open,     

    .read      =  sixth_drv_read,       

    .release =  sixth_drv_close,

    .poll      =  sixth_drv_poll,

    .fasync  =  sixth_drv_fasync,

};

int major;

static int sixth_drv_init(void)

{

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

    sixthdrv_class = class_create(THIS_MODULE, "sixth_drv");

    device_create(sixthdrv_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 sixth_drv_exit(void)

{

    unregister_chrdev(major, "sixth_drv");

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

    class_destroy(sixthdrv_class);

    iounmap(gph2con);

    iounmap(gph3con);

    return 0;

}

module_init(sixth_drv_init);

module_exit(sixth_drv_exit);

MODULE_LICENSE("GPL");

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

sixthdrvtest.c测试程序:

#include "sys/types.h"

#include "sys/stat.h"

#include "fcntl.h"

#include "stdio.h"

#include "poll.h"

#include "signal.h"

#include "sys/types.h"

#include "unistd.h"

#include "fcntl.h"

// sixthdrvtest 

  

int fd;

void my_signal_fun(int signum)

{

    unsigned char key_val;

    read(fd, &key_val, 1);

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

}

int main(int argc, char **argv)

{

    unsigned char key_val;

    int ret;

    int Oflags;

//signal(SIGIO, my_si

[1] [2]

关键字:Tiny210  按键互斥锁  原子变量驱动

编辑:什么鱼 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news101241703.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:Tiny210按键阻塞访问驱动
下一篇:Tiny210驱动之按键异步通知

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

Tiny4412友善之臂ARM开发板静态IP设置(重启有效)

刚入手Tiny4412开发板,发现它的ip地址不是192.168.1.230,老是自动跳变,今天是192.168.1.7,明天开机就变成了192.168.1.8,所以就决定将其设为静态ip地址:192.168.1.240。首先参考网上提供的一个常见的方案: 要修改arm开发板的IP,如果是yaffs2文件,可以1、首先要修改/etc/init.d/rcS文件,在/sbin/ifconfig lo 127.0.0.0下添加一行/sbin/ifconfig eth0 192.168.1.20 up注:192.168.1.20 只是举例,可以改成你想要修改的IP地址本来这样修改之后就可以的,但是我发现仍然不行,使用
发表于 2018-10-14
Tiny4412友善之臂ARM开发板静态IP设置(重启有效)

Tiny4412和PC传文件(含挂载NFS文件系统)方法

=Device+TreeTiny4412裸机程序汇总地址:http://www.100ask.org/bbs/forum.php?mod=viewthread&tid=11778&highlight=tiny4412iTOP-4412实现NFS网络文件系统启动(包括安装Ubuntu NFS服务、编译配置内核)http://www.oschina.net/question/2371345_2158782==================================================================驱动测试搭建开发环境:由于采用nfs作为文件系统启动失败,所以在内核启动后在把服务器的/home/book
发表于 2018-10-14

tiny4412的Uboot启动流程

基于友善之臂tiny4412开发板,uboot版本是2010.12:一般我们将UBOOT分为2个阶段,第一阶段主要为汇编代码,用于初始化必要的硬件并将UBOOT copy到SDRAM中并跳转到SDRAM执行,第二阶段主要为c代码,主要作用是加载kernel到SDRAM,准备启动kernel的参数最后跳转到kernel处执行,当然uboot里也可以有许多扩展功能,比如下载功能,实现各种驱动程序等.第一阶段:1.首先就是uboot的入口的地址是arch/arm/cpu/armv7/start.S, 这可以从相同路径下的连接脚本u-boot.lds 中知道,如下
发表于 2018-10-14

Tiny4412的MMU解析

1、Tiny4412的MMU和S3C6410都是一样的,以前的程序都可以运行,因为MMU有两个特点:  ①MMU实在cp15协处理器里面操作的,协处理器由ARM公司统一设计,不会轻易变化,这部分代码和Samsung没有关系;  ②MMU的功能就是把虚拟地址映射物理地址上去。2、为什么裸机要讲MMU?  因为中断,ARM地址的布局。现在三星处理器地址的布局和以前不一样,以前S3C6410的0地址是可以选的,比如nand flash启动的时候0地址对应片内内存;nor flash启动的时候0地址对应nor flash的0地址。也就是0地址我们可以选择是ROM或者RAM
发表于 2018-10-14

Tiny4412异常处理

=0x70003000  test.o  -o test    arm-linux-objcopy  -O binary  test  test.binclean:    rm -f test.o  test  test.bin   *~ ===================================================================烧写测试参考:“Tiny4412从SD卡启动u-boot用linux的DNW烧写裸板程序”说明: 
发表于 2018-10-14

Tiny4412的MMU映射代码示例

;                   段映射只用到一级页表,页映射用到一级页表和二级页表。3、关于映射粒度:段映射的映射粒度有两种,1M section和16M supersection;                      
发表于 2018-10-14

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved
pt type="text/javascript" src="//v3.jiathis.com/code/jia.js?uid=2113614" charset="utf-8">