zoukankan      html  css  js  c++  java
  • liunx驱动----系统滴答时钟的使用

    2019-3-12系统滴答定时器中断使用

    1. 定义一个timer

    其实就是使用系统的滴答定时器产生一个中断。

    1. 初始化timer
    2.   init_timer函数 实现如下
    void fastcall init_timer(struct timer_list *timer)
    {
    timer->entry.next = NULL;
    timer->base = __raw_get_cpu_var(tvec_bases);
    ifdef CONFIG_TIMER_STATS
    timer->start_site = NULL;
    timer->start_pid = -1;
    memset(timer->start_comm, 0, TASK_COMM_LEN);
    endif
    }
    EXPORT_SYMBOL(init_timer);
     
    从这个结构的内容中可以看出,必须要设置 entry:链表相关 expires:保存超时时间 function :指向当超时事件发生后进入那个处理函数 data:需要传递给这个函数的参数 *base :保存当前的基地址
    1. 在按键中断中修改 超时时间

     

     

     

    jiffies :当前系统滴答值 HZ:默认为100 10ms一个节拍
     
     
     
    实现功能:当按键中断发生后等待10ms后才去处理,获取到的值。
    初始化函数:
    static int sixth_drv_init(void)
    {
    
        /*初始化  timer  定义的这个软件定时器*/  
        init_timer(&buttons_timer);
        buttons_timer.function = buttons_timer_function;
        add_timer(&buttons_timer);//告诉内核有这样一个定时器
        
        major = register_chrdev(0, "sixth_drv", &sencod_drv_fops);
    
        sixthdrv_class = class_create(THIS_MODULE, "sixth_drv");
    
        sixthdrv_class_dev = class_device_create(sixthdrv_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 irqreturn_t buttons_irq(int irq, void *dev_id)
    {
        irq_pd = (struct pin_desc *)dev_id;
        //修改定时器的超时时间  HZ = 100  jiffies 当前时钟  10ms后进入中断处理函数
        mod_timer(&buttons_timer, jiffies+HZ/100);//jiffies  是一个全局变量  系统每隔10ms就会产生一个系统时钟中断 过100个10ms进入中断  
        return IRQ_RETVAL(IRQ_HANDLED);
    }

    超时事件处理函数:

    static void buttons_timer_function(unsigned long data)
    {
        
        struct pin_desc * pindesc = irq_pd;
        unsigned int pinval;
        if(!pinval)return ;//如果为空直接返回0
        pinval = s3c2410_gpio_getpin(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);
    }
  • 相关阅读:
    问卷调查
    20145104张家明 《Java程序设计》第6周学习总结
    20145104张家明 《Java程序设计》第2周学习总结
    20145104张家明 《Java程序设计》第一周学习总结
    20145104张家明 《Java程序设计》第3周学习总结
    socketserver OSError:[Errno 98] Address already in use
    psycopg2.OperationalError: FATAL: password authentication failed for user "postgres"
    nginx 配置nginx.conf
    css 一些常用属性总结
    在ie中用滤镜 (filter:progid:DXImageTransform.Microsoft.gradient)会触发overflow:hidden?
  • 原文地址:https://www.cnblogs.com/hjxzjp/p/10520031.html
Copyright © 2011-2022 走看看