您尚未登录。

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/input/touchscreen.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_module(void)
{
        printk("<1>Hello World\n"); 
    r_int_config();
        return 0;
}

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

# 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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

QQ20180605160512.png

离线

#3 2018-06-14 14:44:25

beyondabcd
会员
注册时间: 2018-06-12
累计积分: 44

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

现在成功了吗

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

可以的,亲自试过。

离线

#5 2018-08-08 23:35:43

include_h
会员
注册时间: 2018-08-08
累计积分: 12

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

@晕哥 ,能贴出将它编译成.ko文件的脚本吗?
友善的A9 4412是Makefile这样的,现在换到全志我转不过来,

FILE =  key_poll
INC =   key_poll.h

obj-m = $(FILE).o

KDIR = /works/linux/linux-3.5/

all:
    make -C $(KDIR)  M=$(PWD)  modules

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

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

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

离线

#7 2018-11-15 19:34:20

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

晕哥 我将你的代码复制来进行测试,但是在insmod .ko文件时出现了

# insmod led.ko 
[ 3287.239687] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.245282] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.250413] led: Unknown symbol gpio_free (err 0)
[ 3287.255131] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.260126] led: Unknown symbol gpio_request (err 0)
[ 3287.266851] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.272447] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.277566] led: Unknown symbol gpio_free (err 0)
[ 3287.282282] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.287271] led: Unknown symbol gpio_request (err 0)
insmod: can't insert 'led.ko': unknown symbol in module, or unknown parameter

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

离线

#10 2018-11-15 20:02:33

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

605364021 说:

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

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

离线

#12 2018-11-15 20:21:01

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

前两个在内核.config文件下不存在,只有第三个有。是要将新建的内核加载到zimge上去运行?只移植.ko模块到板子上运行可以?

离线

#13 2018-11-15 20:31:59

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

605364021 说:

晕哥 我将你的代码复制来进行测试,但是在insmod .ko文件时出现了

# insmod led.ko 
[ 3287.239687] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.245282] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.250413] led: Unknown symbol gpio_free (err 0)
[ 3287.255131] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.260126] led: Unknown symbol gpio_request (err 0)
[ 3287.266851] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.272447] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.277566] led: Unknown symbol gpio_free (err 0)
[ 3287.282282] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.287271] led: Unknown symbol gpio_request (err 0)
insmod: can't insert 'led.ko': unknown symbol in module, or unknown parameter

这个问题解决了,.c文件缺失MODULE_LICENSE("GPL");,在.c文件加上,再编译就可以在v3上进行模块加载了

离线

#14 2018-11-15 20:48:08

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

晕哥 说:
# 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脚下拉就会进入中断, 输出上面的信息.

怎么将PG0 IO脚下拉,赋值?

最近编辑记录 605364021 (2018-11-15 20:48:38)

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

605364021 说:
晕哥 说:
# 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脚下拉就会进入中断, 输出上面的信息.

怎么将PG0 IO脚下拉,赋值?

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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

605364021 说:
605364021 说:

晕哥 我将你的代码复制来进行测试,但是在insmod .ko文件时出现了

# insmod led.ko 
[ 3287.239687] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.245282] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.250413] led: Unknown symbol gpio_free (err 0)
[ 3287.255131] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.260126] led: Unknown symbol gpio_request (err 0)
[ 3287.266851] led: Unknown symbol gpiod_get_raw_value (err 0)
[ 3287.272447] led: Unknown symbol gpiod_to_irq (err 0)
[ 3287.277566] led: Unknown symbol gpio_free (err 0)
[ 3287.282282] led: Unknown symbol gpio_to_desc (err 0)
[ 3287.287271] led: Unknown symbol gpio_request (err 0)
insmod: can't insert 'led.ko': unknown symbol in module, or unknown parameter

这个问题解决了,.c文件缺失MODULE_LICENSE("GPL");,在.c文件加上,再编译就可以在v3上进行模块加载了

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

离线

#17 2018-11-15 21:51:10

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

605364021 说:

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

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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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 触发闪烁, 或者调整闪烁频率.

离线

#19 2018-11-18 16:37:21

605364021
会员
注册时间: 2018-10-23
累计积分: 251

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

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>

#define PG0 192 //PG0 192=32*6+0
#define DEVICE "myled"
#define MAGIC_NUM 'k'			//定义幻数
#define LED_ON _IO(MAGIC_NUM, 0) //_IO    不带参数的ioctl
#define LED_OFF _IO(MAGIC_NUM, 1)

/*--------------------------------------------------------------------------
  函数名:      led_open
  参数:        struct inode *inode,struct file *filp
  返回值:      int
  描述:        open对应的驱动函数
 -------------------------------------------------------------------------*/

int led_open(struct inode *inode, struct file *filp)
{
   int ret;
   ret = gpio_request_one(PG0,GPIOF_OUT_INIT_HIGH,"myled");//配置为输出,并初始化为高电平,gpio.txt
   if(ret)
	{
		printk("error: cannot request gpio PG0 \n");
		printk("error ret = %d", ret);				
	}
	gpio_set_value(PG0,1); // GPIO 输出   void gpio_set_value(unsigned gpio, int value); 
	return 0;
}

/*--------------------------------------------------------------------------
	函数名:		led_release
	参数:		struct inode *inode,struct file *filp
	返回值:	int
	描述:		release对应的驱动函数
--------------------------------------------------------------------------*/

int led_release(struct inode *inode, struct file *filp)
{
	gpio_free(PG0);// 释放之前声明的 GPIO  void gpio_free(unsigned gpio);
	printk("LED dev release");
	return 0;
}

/*--------------------------------------------------------------------------
	函数名:	led_ioctl
	参数:		struct inode *inode,struct file *filp,unsigned int cmd, unsigned long arg
	返回值:	int
	描述:		led_ioctl函数 
--------------------------------------------------------------------------*/

long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	switch(cmd)
	{
		case LED_ON:
			printk("GPIO LED set low.\n");
			gpio_set_value(PG0, 0);
			break;
		case LED_OFF:
			printk("GPIO LED set high.\n");
			gpio_set_value(PG0, 1);
			break;
		default:
			printk("error cmd .\n");
			break;
	}
	return 0;
}

/*--------------------------------------------------------------------------
	函数名:		file_opreations led_fops
	参数:		owner, open, release, ioctl		
	返回值:		null
	描述:		file_opreations结构体
--------------------------------------------------------------------------*/

struct file_operations led_fops ={
		.owner		= THIS_MODULE,
		.open		= led_open,
		.release	= led_release,
		.unlocked_ioctl		= led_ioctl,
};

/*--------------------------------------------------------------------------
	函数名:		miscdevie led_dev
	参数:		minor, name, fops
	返回值:		null
	描述:		杂项设备
--------------------------------------------------------------------------*/

struct miscdevice led_dev ={
		.minor		= MISC_DYNAMIC_MINOR,//minor是这个混杂设备的次设备号,由系统自动配置,
		.name		= DEVICE,			//.name 设备名
		.fops		= &led_fops
};

/*--------------------------------------------------------------------------
	函数名:		led_init
	参数:		void
	返回值:		int
	描述:		模块初始化参数,安装模块时执行
--------------------------------------------------------------------------*/

static int __init led_init(void)
{
		int ret;
		ret = misc_register(&led_dev);//注册驱动程序时采用misc_register函数注册,此函数中会自动创建设备节点,即设备文件
		if(ret)
		{		
			printk("error: cannot register misc.\n");
			return ret;
		}
		printk("misc-register %s\n", DEVICE);
		return 0;
}

/*--------------------------------------------------------------------------
		函数:		led_exit
		参数:		void
		返回值:		void
		描述:		模块卸载函数,卸载模块时执行
--------------------------------------------------------------------------*/

static void __exit led_exit(void)
{
		misc_deregister(&led_dev);//杂项设备的注销过程,其实就是注册过程的逆向过程
		printk("mise-deregister %s\n", DEVICE);
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
#include<asm-generic/ioctl.h>

#define DEVICE          "/dev/myled"
#define MAGIC_NUM       'k'
#define LED_ON   _IO(MAGIC_NUM, 0)
#define LED_OFF  _IO(MAGIC_NUM, 1)

int main(int argc, char *argv[])
{
       int fd;

        printf("Start led test.\n");

        fd = open(DEVICE, O_RDWR);//O_RDWR:可读可写
        if (fd < 2) {
                printf("Cannot open device %s\n", DEVICE);
                return -EFAULT;
        }       
        while (1) {
                ioctl(fd, LED_ON, 0);//ioctl(int fd,unsigned long cmd,...),fd:文件描述符,cmd 控制命令
                sleep(1);
                ioctl(fd, LED_OFF, 0);
                sleep(1);
        }
        return 0;       
}

上面是驱动程序和测试程序,能实现led灯的自动闪烁,我现在在弄按键产生中断来控制led灯的控制,但是原理图不会找按钮对应的引脚.....

离线

#20 2019-01-02 13:11:37

aoaoao123mm
会员
注册时间: 2019-01-02
累计积分: 15

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

晕哥请问中断号是在哪里查到的,还有那个中断事件?

离线

#21 2019-03-18 09:15:53

IoTer
会员
注册时间: 2019-01-20
累计积分: 25

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

aoaoao123mm 说:

晕哥请问中断号是在哪里查到的,还有那个中断事件?

中断号在 V3s 手册的 "PB_EINT interrupt", "PG_EINT interrupt" 可以找到,
只有 PB, PG 两组口可以作为外部中断口。

离线

#22 2019-03-22 10:25:59

Beta_vulgaris
会员
注册时间: 2019-03-07
累计积分: 60

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

如果用Device tree配置,中断GPIO怎么表示?

离线

#23 2019-03-22 10:46:45

smartcar
会员
注册时间: 2018-02-19
累计积分: 717

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

和这个一样

只是要一个读 dts 的代码

https://whycan.cn/t_2251.html

离线

#24 2019-04-17 13:04:28

zhenfanhei
会员
注册时间: 2018-01-18
累计积分: 257
个人网站

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

晕哥,S3上申请失败啊,点解? # insmod gpio-sun8i.ko
[   24.670723] <1>Hello World
[   24.678214] GPIO to IRQ mapping failure pb12_int

估计也是gpio_to_irq不行,我折腾触摸跟wifi也是中断申请不能通过,4.13.16,大概什么情况?

离线

#25 2019-04-17 13:06:38

zhenfanhei
会员
注册时间: 2018-01-18
累计积分: 257
个人网站

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

加了一些跟踪,也是类似gpio到irq的映射那不行
# insmod brcmutil.ko
# insmod brcmfmac.ko
# [   61.265277] interrupt find name:wifi type:<NULL> full_name:/soc/mmc@01c10000/wifi@1
[   61.282371] irq gpio 42--zengfh
[   61.290215] irqgpio:42 request
[   61.297933] irq -22--zengfh
[   61.305348] of_irq_parse_one: dev=/soc/mmc@01c10000/wifi@1, index=0
[   61.321016] intspec:  intspec=1 intlen=3
[   61.329710]  intsize=3 intlen=3
[   61.337572] Checked index res:0
[   61.345384] irq_domain_translater /soc/pinctrl@01c20800 irq:-941213360 type:0 failed!
[   61.362553] brcmfmac: brcmf_of_probe: interrupt could not be mapped err:0
[   61.380772] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43430-sdio.bin failed with error -2
[   62.403759] brcmfmac: brcmf_sdio_htclk: HT Avail timeout (1000000): clkctl 0x50
[   63.424179] brcmfmac: brcmf_sdio_htclk: HT Avail timeout (1000000): clkctl 0x50

离线

#26 2019-04-17 13:08:07

zhenfanhei
会员
注册时间: 2018-01-18
累计积分: 257
个人网站

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

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

离线

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

晕哥
管理员
注册时间: 2017-09-06
累计积分: 9,191

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

zhenfanhei 说:

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

厉害厉害!

离线

#28 2019-04-17 20:03:59

zhenfanhei
会员
注册时间: 2018-01-18
累计积分: 257
个人网站

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

不是啊,我是无法申请中断,gpio_to_irq系统里面是空的

离线

#29 2019-04-18 08:57:14

zhenfanhei
会员
注册时间: 2018-01-18
累计积分: 257
个人网站

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

S3的一些脚在 pinctrl_V3s里面无定义,加上去即可,暂时我也没加全,就把PB10~PB13加了,其它还有好多,不加无法申请中断,不过比较坑的是全志只有PB PG才能做中断,其它不行,

离线

#30 2020-04-06 17:38:38

ubuntu
会员
注册时间: 2020-03-30
累计积分: 67

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

离线

#31 2020-12-29 13:00:00

笨企鹅
会员
注册时间: 2019-10-28
累计积分: 34

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

向大牛学习

离线

页脚

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

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