zoukankan      html  css  js  c++  java
  • Linux的 标准GPIO及中断API函数


    #include<linux/gpio.h> // 标准 GPIO_API

       intgpio_request(unsigned gpio, const char *label);

       获得并占有 GPIO>。在/proc/mem应该会有地址占用表描述。

    这种用法的保护作用前提是大家都遵守先申请再访问,有一个地方没遵守这个规则,这功能就失效了。好比进程互斥,必需大家在访问临界资源的时候都得先获取锁一样,其中一个没遵守约定,代码就废了。

    例1:void gpio_free(unsignedgpio);//释放 GPIO port 的使用权,由gpio 指定具体 port。

    例2:gpio_free(RK29_PIN0_PA0);//释放GPIO0_A0

    int gpio_direction_input(unsignedgpio);//返回0

    例3:gpio_direction_input (RK29_PIN0_PA0);//把GPIO0_A0设置为输入

    int gpio_direction_output(unsigned gpio, intvalue);//返回0

           例4:gpio_direction_output(RK29_PIN0_PA0,GPIO_LOW);//把GPIO0_A0设置为输出口,且其电平拉低。   intgpio_get_value(unsigned gpio);//返回value

           例5:ret = gpio_get_value (RK29_PIN0_PA0);//读取GPIO0_A0的电平,并赋值给变量ret。

    void gpio_set_value(unsigned gpio, intvalue);

    例6:gpio_set_value (RK29_PIN0_PA0, GPIO_HIGH);//设置RK29_PIN0_PA0电平为高。

           int gpio_pull_updown(unsigned gpio,unsigned value);

           value = 0, normal

           value = 1, pull up

           value = 2, pull down

           例7:gpio_pull_updown(RK29_PIN0_PA0,1)上拉

          int gpio_cansleep(unsigned gpio);

    支持这种gpio的平台为了通过在这个函数中返回非零来区分其它类型的gpio(需要一个已经被 gpio_request申请的gpio号)为了访问这些端口,定义了另一组函数接口:

          int gpio_get_value_cansleep(unsigned gpio);

          voidgpio_set_value_cansleep(unsigned gpio, int value);

           只能在允许睡眠的上下文中访问这些端口,比如线程化的中断中,

          static inline int gpio_is_valid(intnumber)//判断GPIO是否有效,有效返回0

          int gpio_export(unsigned gpio, booldirection_may_change);//返回0成功

           voidgpio_unexport();  //返回0成功

           intgpio_export_link(struct device *dev, const char *name, unsignedgpio) 

    //创建到导出GPIO的 sysfs link ,第一个参数是在哪个dev下创建,第二个是参数名字,第三个是gpio编号 

    中断部分的API:

      static inlineint gpio_to_irq(unsigned gpio)

        例8:gpioToIrq = gpio_to_irq (RK29_PIN0_PA0);//把GPIO0_A0的PIN值转换为相应的IRQ值,并赋值给变量gpioToIrq。

      gpio_to_irq()返回的中断编号可以传给request_irq()和free_irq()。

      irq_to_gpio()返回的gpio编号通常用来调用gpio_get_value(),比如在沿触发的中断中获取引脚的状态。有些平台不支持这种映射,应该避免调用映射函数

       static inline int__must_check request_irq(unsigned int irq, irq_handler_t handler,unsigned long flags, const char *name, void *dev);

    范例:irq是要申请的硬件中断号;handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev参数将被传递; flags是中断处理的属性,若设置SA_INTERRUPT,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置SA_SHIRQ,则多个设备共享中断,*dev在中断共享时会用到,一般设置为这个设备的device结构本身或者NULL。当flags发生时,触发中断。

          例9:static irqreturn_t PA0IntHandler(int irq, void*dev_id)

    {

          printk(KERN_INFO "PA0IntHandler:irq=%d",irq);

       return IRQ_HANDLED;

    }

    voidmain(void)

    {

    // 把GPIO0_A0的PIN值转换为相应的IRQ值,并赋值给变量gpioToIrq。

    unsigned long req_flags = IRQF_TRIGGER_RISING;

    intgpioToIrq = gpio_to_irq (RK29_PIN0_PA0);

    If(gpioToIrq != -1){

    //注册PA0IntHandler中断处理函数,中断号是RK29_PIN0_PA0,设置为上升沿触发

       request_irq(gpioToIrq, PA0IntHandler,req_flags, "PA0_test",NULL);

       }

    }

         voidfree_irq(unsigned int irq, void*dev_id)//释放中断

    irq: 释放的中断号  dev_id: 释放的dev_id

    例10: free_irq(gpio_to_irq(RK29_PIN0_PA0),NULL);//释放GPIO0_A0中断。

        int set_irq_type(unsigned int irq, unsigned inttype)

    irq: 指定的中断号type  : 设置的中断类型

    例11:set_irq_type(gpio_to_irq(RK2818_PIN_PA0),IRQF_TRIGGER_LOW);//设置GPIO0_A0中断为低电平触发

         voiddisable_irq_nosync(unsigned int irq)

    强行关闭指定中断,不会等待当前中断处理程序执行完毕。,立即返回

    例12:disable_irq_nosync(gpio_to_irq(RK29_PIN0_PA0));//关闭GPIO0_A0中断。

        voiddisable_irq(unsigned int irq)

    将关闭硬件中断并等待(可能有的)中断处理完成才返回。

    例13:disable_irq(gpio_to_irq(RK29_PIN0_PA0));//关闭GPIO0_A0中断。

         voidenable_irq(unsigned int irq)

    使能一个指定的中断

    例14: enable_irq(gpio_to_irq(RK29_PIN0_PA0));//使能GPIO0_A0中断。

    注意:使能IRQ和不使能IRQ应该配对使用。

       若调用enable_irq之前,并未关闭指定中断(如调用disable_irq_nosync 关闭指定中断),

       则调用enable_irq会报警告(WARNING: at kernel/irq/manage.c:274enable_irq+0x48/0x68();Unbalanced enable for IRQ 58),此为正常现象。

        int enable_irq_wake(unsigned intirq)//返回0成功

        int disable_irq_wake(unsigned int irq)//返回0成功

      要enable和disable的次数相同

    例15:static inline intenable_irq_wake(unsigned int irq)

    {returnset_irq_wake(irq, 1);

    }

    static inline intdisable_irq_wake(unsigned int irq)

    {

    return set_irq_wake(irq, 0);

    }

      voidrk29_gpio_suspend(void)// 让GPIO进入省电睡眠模式

    调用此函数,是否会让GPIO进入省电睡眠模式,与enable_irq_wake和disable_irq_wake函数相关,

    例16:如果先调用了enable_irq_wake(gpio_to_irq(RK29_PIN0_PA0)),则即使调用了

      voidrk29_gpio_resume(void)//唤醒GPIO


    http://blog.chinaunix.net/uid-25909619-id-3372031.html




  • 相关阅读:
    $$Ctrl+shift+M分数罗马字母小写
    设置字体大小加粗斜体下划线
    无序列表有序列表
    数学公式插入
    文本居中、代码插入、图片插入
    VM 使用问题 | 安装失败->>注册表
    VM小技巧——虚拟机解决vm窗口太小的办法
    OneNet平台实践
    linux 打包 | autoconf 使用方法
    C 总结 | 复习注意点
  • 原文地址:https://www.cnblogs.com/liulaolaiu/p/11744573.html
Copyright © 2011-2022 走看看