您尚未登录。

楼主 #1 2018-06-05 15:55:10

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

写一个非常简单的 V3s@linux4.13-y 中断驱动

hello.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>

#define GPIO 192    //PG0
#define GPIO_INT_NAME  "pg0_int"

#define GPIO_HIGH gpio_get_value(GPIO)
#define GPIO_LOW (gpio_get_value(GPIO) == 0)
short int irq_any_gpio    = 0;
int count =0;

enum { falling, rising } type; 
static irqreturn_t r_irq_handler(int irq, void *dev_id)
 {
    count++;
    printk(KERN_DEBUG "interrupt received (irq: %d)\n", irq);
	if (irq == gpio_to_irq(GPIO)) 
    {

        type = GPIO_LOW ? falling : rising;

        if(type == falling)
        {
            printk("gpio pin is low\n");    
        }
        else
            printk("gpio pin is high\n");

    }

    return IRQ_HANDLED;
}

void r_int_config(void) {

   if (gpio_request(GPIO, GPIO_INT_NAME )) 
   {
      printk("GPIO request failure: %s\n", GPIO_INT_NAME );
      return;
   }

   if ( (irq_any_gpio = gpio_to_irq(GPIO)) < 0 ) {
      printk("GPIO to IRQ mapping failure %s\n",GPIO_INT_NAME );
      return;
   }

   printk(KERN_NOTICE "Mapped int %d\n", irq_any_gpio);

   if (request_irq(irq_any_gpio,(irq_handler_t ) r_irq_handler, IRQF_TRIGGER_FALLING , GPIO_INT_NAME, NULL)) 
   {
      printk("Irq Request failure\n");
      return;
   }

   return;
}

void r_int_release(void) {

   free_irq(gpio_to_irq(GPIO), NULL);
    gpio_free(GPIO);;
   return;
}

int init_module1(void)
{
        printk("<1>Hello World\n"); 
    r_int_config();
        return 0;
}

module_init(init_module1);    // Do some better naming
module_exit(r_int_release);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("whycan");

# dmesg
[   26.204637] interrupt received (irq: 71)
[   26.204660] gpio pin is low
[   26.919621] interrupt received (irq: 71)
[   26.919642] gpio pin is low
[   27.429350] interrupt received (irq: 71)
[   27.429359] gpio pin is low
[   27.694572] interrupt received (irq: 71)
[   27.694586] gpio pin is low
[   27.906767] interrupt received (irq: 71)
[   27.906779] gpio pin is low

把PG0 IO脚下拉就会进入中断, 输出上面的信息.


参考链接: https://stackoverflow.com/questions/25507750/detecting-interrupt-on-gpio-in-kernel-module

参考链接: 试一试 Ubuntu 下编译第一个 Hello World 驱动并运行
http://whycan.com/t_5233.html















以下由 @哇酷小二 2021-04-15 添加:
------------------------
Makefile:

obj-m = hello.o

编译指令 (根据实际情况修改指令):

ARCH=arm CROSS_COMPILE=/opt/buildroot/output/host/bin/arm-linux-gnueabihf- make -C /opt/buildroot/output/build/linux-zero-5.2.y/ M=${PWD} modules

编译日志:

$ ARCH=arm CROSS_COMPILE=/opt/buildroot/output/host/bin/arm-linux-gnueabihf- make -C /opt/buildroot/output/build/linux-zero-5.2.y/ M=${PWD} modules
make: Entering directory '/opt/buildroot/output/build/linux-zero-5.2.y'
  CC [M]  /opt/buildroot/modules/test1/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /opt/buildroot/modules/test1/hello.o
see include/linux/module.h for more information
  CC      /opt/buildroot/modules/test1/hello.mod.o
  LD [M]  /opt/buildroot/modules/test1/hello.ko
make: Leaving directory '/opt/buildroot/output/build/linux-zero-5.2.y'




离线

楼主 #2 2018-06-05 16:05:51

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

QQ20180605160512.png





离线

楼主 #4 2018-06-14 14:47:26

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

可以的,亲自试过。





离线

楼主 #6 2018-08-09 08:47:34

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

@include_h 一楼的代码我是修改 ns2009.c 里面的代码,直接编译到内核的.

你这个要做改一下 KDIR,改成你的内核源码试一试.





离线

楼主 #8 2018-11-15 19:50:58

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

可能我一楼的代码是直接编译到 zImage 的,所以没有碰到你的这种情况.





离线

楼主 #9 2018-11-15 19:59:55

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

https://discuss.96boards.org/t/simple-irq-driver-issue/724/2

CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y





离线

楼主 #11 2018-11-15 20:04:35

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

605364021 说:

晕哥,我在4.13y内核分支已有相关驱动的情况下,想做个只控制PG0的.ko核模块通过insmod来实现控制led灯的闪烁,这样可以实现?

肯定可以的, 看9楼的解决方案, 先试一试





离线

楼主 #15 2018-11-15 21:13:19

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

杜邦线,或者PG0飞一个轻触开关到GND。





离线

楼主 #16 2018-11-15 21:25:11

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

我也搜到这个答案,但是被我直接pass了,不过又get到新姿势了。





离线

楼主 #18 2018-11-15 21:54:35

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

605364021 说:
605364021 说:

晕哥,我在4.13y内核分支已有相关驱动的情况下,想做个只控制PG0的.ko核模块通过insmod来实现控制led灯的闪烁,这样可以实现?

想用.ko内核模块实现led灯的闪烁,需要重新向内核注册设备吗?还是直接在.ko模块上实现相关功能就行?

不用了,参考:

https://whycan.cn/t_1853.html#p11754
https://stackoverflow.com/questions/10812858/how-to-use-timers-in-linux-kernel-device-drivers

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>

MODULE_LICENSE("GPL");

static struct timer_list my_timer;

void my_timer_callback( unsigned long data )
{
     /* do your timer stuff here */
}

int init_module(void)
{
  /* setup your timer to call my_timer_callback */
  setup_timer(&my_timer, my_timer_callback, 0);
  /* setup timer interval to 200 msecs */
  mod_timer(&my_timer, jiffies + msecs_to_jiffies(200));
  return 0;
}

void cleanup_module(void)
{
  /* remove kernel timer when unloading module */
  del_timer(&my_timer);
  return;
}

如果搞定了, 希望可以贴个完整的上来参考一下.

最好把这个中断也加上,按下GPIO 触发闪烁, 或者调整闪烁频率.





离线

楼主 #27 2019-04-17 13:37:49

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,342
积分: 9202

Re: 写一个非常简单的 V3s@linux4.13-y 中断驱动

zhenfanhei 说:

wifi在眼前了,[    5.009565] mmc1: new high speed SDIO card at address 0001

厉害厉害!





离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn