您尚未登录。

楼主 #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





离线

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

beyondabcd
会员
注册时间: 2018-06-12
已发帖子: 44
积分: 44

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

现在成功了吗

离线

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

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

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

可以的,亲自试过。





离线

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

include_h
会员
注册时间: 2018-08-08
已发帖子: 12
积分: 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,342
积分: 9202

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

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

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





离线

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

605364021
会员
注册时间: 2018-10-23
已发帖子: 251
积分: 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,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





离线

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

605364021
会员
注册时间: 2018-10-23
已发帖子: 251
积分: 251

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

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

离线

楼主 #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楼的解决方案, 先试一试





离线

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

605364021
会员
注册时间: 2018-10-23
已发帖子: 251
积分: 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
积分: 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
积分: 251

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

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

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

离线

楼主 #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到新姿势了。





离线

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

605364021
会员
注册时间: 2018-10-23
已发帖子: 251
积分: 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,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 触发闪烁, 或者调整闪烁频率.





离线

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

605364021
会员
注册时间: 2018-10-23
已发帖子: 251
积分: 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
积分: 15

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

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

离线

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

IoTer
会员
注册时间: 2019-01-20
已发帖子: 25
积分: 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
积分: 60

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

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

离线

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

smartcar
会员
注册时间: 2018-02-19
已发帖子: 735
积分: 735

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

和这个一样

只是要一个读 dts 的代码

https://whycan.cn/t_2251.html

离线

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

zhenfanhei
会员
注册时间: 2018-01-18
已发帖子: 300
积分: 245
个人网站

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
已发帖子: 300
积分: 245
个人网站

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
已发帖子: 300
积分: 245
个人网站

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,342
积分: 9202

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
已发帖子: 300
积分: 245
个人网站

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

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





离线

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

zhenfanhei
会员
注册时间: 2018-01-18
已发帖子: 300
积分: 245
个人网站

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

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





离线

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

ubuntu
会员
注册时间: 2020-03-30
已发帖子: 272
积分: 250

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

离线

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

笨企鹅
会员
注册时间: 2019-10-28
已发帖子: 38
积分: 37.5

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

向大牛学习

离线

#32 2021-01-22 12:16:41

LinuxGo
会员
注册时间: 2021-01-07
已发帖子: 88
积分: 120

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

晕哥 我这边编译 好多错误,怎么办呀,呼叫晕哥
程序复制了1楼的 ,Makefile复制了5楼并改了 路径
编译结果如下

jonsen@ubuntu:~/f1c100s/test_chrdevbase$ make 
make -C /home/jonsen/f1c100s/linux/ M=/home/jonsen/f1c100s/test_chrdevbase modules
make[1]: Entering directory '/home/jonsen/f1c100s/linux'
  CC [M]  /home/jonsen/f1c100s/test_chrdevbase/chardevbase.o
In file included from ./arch/x86/include/asm/barrier.h:5,
                 from ./include/linux/compiler.h:242,
                 from ./include/linux/kernel.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:1:
./arch/x86/include/asm/arch_hweight.h: In function ‘__arch_hweight64’:
./arch/x86/include/asm/arch_hweight.h:55:42: error: expected ‘:’ or ‘)’ before ‘POPCNT64’
   55 |  asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
      |                                          ^~~~~~~~
./arch/x86/include/asm/alternative.h:133:28: note: in definition of macro ‘ALTINSTR_REPLACEMENT’
  133 |  b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n\t"
      |                            ^~~~~~~~
./arch/x86/include/asm/arch_hweight.h:55:7: note: in expansion of macro ‘ALTERNATIVE’
   55 |  asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
      |       ^~~~~~~~~~~
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h: At top level:
./arch/x86/include/asm/atomic64_64.h:20:40: error: unknown type name ‘atomic64_t’
   20 | static inline long atomic64_read(const atomic64_t *v)
      |                                        ^~~~~~~~~~
In file included from ./include/linux/kernel.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:1:
./arch/x86/include/asm/atomic64_64.h: In function ‘atomic64_read’:
./arch/x86/include/asm/atomic64_64.h:22:22: error: request for member ‘counter’ in something not a structure or union
   22 |  return READ_ONCE((v)->counter);
      |                      ^~
./include/linux/compiler.h:246:17: note: in definition of macro ‘__READ_ONCE’
  246 |  union { typeof(x) __val; char __c[1]; } __u;   \
      |                 ^
./arch/x86/include/asm/atomic64_64.h:22:9: note: in expansion of macro ‘READ_ONCE’
   22 |  return READ_ONCE((v)->counter);
      |         ^~~~~~~~~
./arch/x86/include/asm/atomic64_64.h:22:22: error: request for member ‘counter’ in something not a structure or union
   22 |  return READ_ONCE((v)->counter);
      |                      ^~
./include/linux/compiler.h:248:22: note: in definition of macro ‘__READ_ONCE’
  248 |   __read_once_size(&(x), __u.__c, sizeof(x));  \
      |                      ^
./arch/x86/include/asm/atomic64_64.h:22:9: note: in expansion of macro ‘READ_ONCE’
   22 |  return READ_ONCE((v)->counter);
      |         ^~~~~~~~~
./arch/x86/include/asm/atomic64_64.h:22:22: error: request for member ‘counter’ in something not a structure or union
   22 |  return READ_ONCE((v)->counter);
      |                      ^~
./include/linux/compiler.h:248:42: note: in definition of macro ‘__READ_ONCE’
  248 |   __read_once_size(&(x), __u.__c, sizeof(x));  \
      |                                          ^
./arch/x86/include/asm/atomic64_64.h:22:9: note: in expansion of macro ‘READ_ONCE’
   22 |  return READ_ONCE((v)->counter);
      |         ^~~~~~~~~
./arch/x86/include/asm/atomic64_64.h:22:22: error: request for member ‘counter’ in something not a structure or union
   22 |  return READ_ONCE((v)->counter);
      |                      ^~
./include/linux/compiler.h:250:30: note: in definition of macro ‘__READ_ONCE’
  250 |   __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
      |                              ^
./arch/x86/include/asm/atomic64_64.h:22:9: note: in expansion of macro ‘READ_ONCE’
   22 |  return READ_ONCE((v)->counter);
      |         ^~~~~~~~~
./arch/x86/include/asm/atomic64_64.h:22:22: error: request for member ‘counter’ in something not a structure or union
   22 |  return READ_ONCE((v)->counter);
      |                      ^~
./include/linux/compiler.h:250:50: note: in definition of macro ‘__READ_ONCE’
  250 |   __read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
      |                                                  ^
./arch/x86/include/asm/atomic64_64.h:22:9: note: in expansion of macro ‘READ_ONCE’
   22 |  return READ_ONCE((v)->counter);
      |         ^~~~~~~~~
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h: At top level:
./arch/x86/include/asm/atomic64_64.h:32:33: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   32 | static inline void atomic64_set(atomic64_t *v, long i)
      |                                 ^~~~~~~~~~
      |                                 atomic_t
./arch/x86/include/asm/atomic64_64.h:44:50: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   44 | static __always_inline void atomic64_add(long i, atomic64_t *v)
      |                                                  ^~~~~~~~~~
      |                                                  atomic_t
./arch/x86/include/asm/atomic64_64.h:58:41: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   58 | static inline void atomic64_sub(long i, atomic64_t *v)
      |                                         ^~~~~~~~~~
      |                                         atomic_t
./arch/x86/include/asm/atomic64_64.h:74:50: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   74 | static inline bool atomic64_sub_and_test(long i, atomic64_t *v)
      |                                                  ^~~~~~~~~~
      |                                                  atomic_t
./arch/x86/include/asm/atomic64_64.h:85:42: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   85 | static __always_inline void atomic64_inc(atomic64_t *v)
      |                                          ^~~~~~~~~~
      |                                          atomic_t
./arch/x86/include/asm/atomic64_64.h:98:42: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
   98 | static __always_inline void atomic64_dec(atomic64_t *v)
      |                                          ^~~~~~~~~~
      |                                          atomic_t
./arch/x86/include/asm/atomic64_64.h:113:42: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  113 | static inline bool atomic64_dec_and_test(atomic64_t *v)
      |                                          ^~~~~~~~~~
      |                                          atomic_t
./arch/x86/include/asm/atomic64_64.h:126:42: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  126 | static inline bool atomic64_inc_and_test(atomic64_t *v)
      |                                          ^~~~~~~~~~
      |                                          atomic_t
./arch/x86/include/asm/atomic64_64.h:140:50: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  140 | static inline bool atomic64_add_negative(long i, atomic64_t *v)
      |                                                  ^~~~~~~~~~
      |                                                  atomic_t
./arch/x86/include/asm/atomic64_64.h:152:57: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  152 | static __always_inline long atomic64_add_return(long i, atomic64_t *v)
      |                                                         ^~~~~~~~~~
      |                                                         atomic_t
./arch/x86/include/asm/atomic64_64.h:157:48: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  157 | static inline long atomic64_sub_return(long i, atomic64_t *v)
      |                                                ^~~~~~~~~~
      |                                                atomic_t
./arch/x86/include/asm/atomic64_64.h:162:47: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  162 | static inline long atomic64_fetch_add(long i, atomic64_t *v)
      |                                               ^~~~~~~~~~
      |                                               atomic_t
./arch/x86/include/asm/atomic64_64.h:167:47: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  167 | static inline long atomic64_fetch_sub(long i, atomic64_t *v)
      |                                               ^~~~~~~~~~
      |                                               atomic_t
./arch/x86/include/asm/atomic64_64.h:175:37: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  175 | static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
      |                                     ^~~~~~~~~~
      |                                     atomic_t
./arch/x86/include/asm/atomic64_64.h:181:50: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  181 | static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, s64 *old, long new)
      |                                                  ^~~~~~~~~~
      |                                                  atomic_t
./arch/x86/include/asm/atomic64_64.h:186:34: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  186 | static inline long atomic64_xchg(atomic64_t *v, long new)
      |                                  ^~~~~~~~~~
      |                                  atomic_t
./arch/x86/include/asm/atomic64_64.h:200:40: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  200 | static inline bool atomic64_add_unless(atomic64_t *v, long a, long u)
      |                                        ^~~~~~~~~~
      |                                        atomic_t
./arch/x86/include/asm/atomic64_64.h:219:45: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  219 | static inline long atomic64_dec_if_positive(atomic64_t *v)
      |                                             ^~~~~~~~~~
      |                                             atomic_t
./arch/x86/include/asm/atomic64_64.h:230:41: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  230 | static inline void atomic64_and(long i, atomic64_t *v)
      |                                         ^~~~~~~~~~
      |                                         atomic_t
./arch/x86/include/asm/atomic64_64.h:238:47: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  238 | static inline long atomic64_fetch_and(long i, atomic64_t *v)
      |                                               ^~~~~~~~~~
      |                                               atomic_t
./arch/x86/include/asm/atomic64_64.h:247:40: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  247 | static inline void atomic64_or(long i, atomic64_t *v)
      |                                        ^~~~~~~~~~
      |                                        atomic_t
./arch/x86/include/asm/atomic64_64.h:255:46: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  255 | static inline long atomic64_fetch_or(long i, atomic64_t *v)
      |                                              ^~~~~~~~~~
      |                                              atomic_t
./arch/x86/include/asm/atomic64_64.h:264:41: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  264 | static inline void atomic64_xor(long i, atomic64_t *v)
      |                                         ^~~~~~~~~~
      |                                         atomic_t
./arch/x86/include/asm/atomic64_64.h:272:47: error: unknown type name ‘atomic64_t’; did you mean ‘atomic_t’?
  272 | static inline long atomic64_fetch_xor(long i, atomic64_t *v)
      |                                               ^~~~~~~~~~
      |                                               atomic_t
In file included from ./include/linux/atomic.h:660,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/atomic64.h:21:18: error: conflicting types for ‘atomic64_read’
   21 | extern long long atomic64_read(const atomic64_t *v);
      |                  ^~~~~~~~~~~~~
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h:20:20: note: previous definition of ‘atomic64_read’ was here
   20 | static inline long atomic64_read(const atomic64_t *v)
      |                    ^~~~~~~~~~~~~
In file included from ./include/linux/atomic.h:660,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/atomic64.h:59: warning: "atomic64_inc_return" redefined
   59 | #define atomic64_inc_return(v)  atomic64_add_return(1LL, (v))
      | 
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h:172: note: this is the location of the previous definition
  172 | #define atomic64_inc_return(v)  (atomic64_add_return(1, (v)))
      | 
In file included from ./include/linux/atomic.h:660,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/atomic64.h:63: warning: "atomic64_dec_return" redefined
   63 | #define atomic64_dec_return(v)  atomic64_sub_return(1LL, (v))
      | 
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h:173: note: this is the location of the previous definition
  173 | #define atomic64_dec_return(v)  (atomic64_sub_return(1, (v)))
      | 
In file included from ./include/linux/atomic.h:660,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/atomic64.h:65: warning: "atomic64_inc_not_zero" redefined
   65 | #define atomic64_inc_not_zero(v)  atomic64_add_unless((v), 1LL, 0LL)
      | 
In file included from ./arch/x86/include/asm/atomic.h:276,
                 from ./include/linux/atomic.h:5,
                 from ./include/linux/jump_label.h:186,
                 from ./arch/x86/include/asm/string_64.h:6,
                 from ./arch/x86/include/asm/string.h:5,
                 from ./include/linux/string.h:19,
                 from ./arch/x86/include/asm/page_32.h:35,
                 from ./arch/x86/include/asm/page.h:14,
                 from ./arch/x86/include/asm/thread_info.h:12,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/atomic64_64.h:210: note: this is the location of the previous definition
  210 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:324,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopud.h:21: warning: "PUD_SHIFT" redefined
   21 | #define PUD_SHIFT P4D_SHIFT
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:56: note: this is the location of the previous definition
   56 | #define PUD_SHIFT 30
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:324,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopud.h:22: warning: "PTRS_PER_PUD" redefined
   22 | #define PTRS_PER_PUD 1
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:57: note: this is the location of the previous definition
   57 | #define PTRS_PER_PUD 512
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:324,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopud.h:23: warning: "PUD_SIZE" redefined
   23 | #define PUD_SIZE   (1UL << PUD_SHIFT)
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:73: note: this is the location of the previous definition
   73 | #define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:324,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopud.h:24: warning: "PUD_MASK" redefined
   24 | #define PUD_MASK   (~(PUD_SIZE-1))
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:74: note: this is the location of the previous definition
   74 | #define PUD_MASK (~(PUD_SIZE - 1))
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:345,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopmd.h:20: warning: "PMD_SHIFT" redefined
   20 | #define PMD_SHIFT PUD_SHIFT
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:63: note: this is the location of the previous definition
   63 | #define PMD_SHIFT 21
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:345,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopmd.h:21: warning: "PTRS_PER_PMD" redefined
   21 | #define PTRS_PER_PMD 1
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:64: note: this is the location of the previous definition
   64 | #define PTRS_PER_PMD 512
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:345,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopmd.h:22: warning: "PMD_SIZE" redefined
   22 | #define PMD_SIZE   (1UL << PMD_SHIFT)
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:71: note: this is the location of the previous definition
   71 | #define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:345,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/asm-generic/pgtable-nopmd.h:23: warning: "PMD_MASK" redefined
   23 | #define PMD_MASK   (~(PMD_SIZE-1))
      | 
In file included from ./arch/x86/include/asm/pgtable_types.h:250,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/pgtable_64_types.h:72: note: this is the location of the previous definition
   72 | #define PMD_MASK (~(PMD_SIZE - 1))
      | 
In file included from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/processor.h:180: warning: "cache_line_size" redefined
  180 | #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
      | 
In file included from ./include/linux/printk.h:9,
                 from ./include/linux/kernel.h:14,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:1:
./include/linux/cache.h:79: note: this is the location of the previous definition
   79 | #define cache_line_size() L1_CACHE_BYTES
      | 
In file included from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/processor.h: In function ‘load_cr3’:
./arch/x86/include/asm/processor.h:253:12: error: implicit declaration of function ‘__sme_pa’ [-Werror=implicit-function-declaration]
  253 |  write_cr3(__sme_pa(pgdir));
      |            ^~~~~~~~
In file included from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/linux/thread_info.h: At top level:
./include/linux/thread_info.h:96:19: error: redefinition of ‘arch_within_stack_frames’
   96 | static inline int arch_within_stack_frames(const void * const stack,
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/thread_info.h:38,
                 from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/thread_info.h:171:19: note: previous definition of ‘arch_within_stack_frames’ was here
  171 | static inline int arch_within_stack_frames(const void * const stack,
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/elf.h:5,
                 from ./include/linux/module.h:15,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/elf.h: In function ‘elf_common_init’:
./arch/x86/include/asm/elf.h:180:3: error: ‘struct thread_struct’ has no member named ‘fsbase’
  180 |  t->fsbase = t->gsbase = 0;
      |   ^~
./arch/x86/include/asm/elf.h:180:15: error: ‘struct thread_struct’ has no member named ‘gsbase’
  180 |  t->fsbase = t->gsbase = 0;
      |               ^~
In file included from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/elf.h: In function ‘mmap_is_ia32’:
./include/linux/thread_info.h:91:22: error: implicit declaration of function ‘current_thread_info’ [-Werror=implicit-function-declaration]
   91 |  test_ti_thread_flag(current_thread_info(), flag)
      |                      ^~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/elf.h:306:3: note: in expansion of macro ‘test_thread_flag’
  306 |   test_thread_flag(TIF_ADDR32));
      |   ^~~~~~~~~~~~~~~~
./include/linux/thread_info.h:91:22: warning: passing argument 1 of ‘test_ti_thread_flag’ makes pointer from integer without a cast [-Wint-conversion]
   91 |  test_ti_thread_flag(current_thread_info(), flag)
      |                      ^~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      int
./arch/x86/include/asm/elf.h:306:3: note: in expansion of macro ‘test_thread_flag’
  306 |   test_thread_flag(TIF_ADDR32));
      |   ^~~~~~~~~~~~~~~~
./include/linux/thread_info.h:77:59: note: expected ‘struct thread_info *’ but argument is of type ‘int’
   77 | static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
      |                                       ~~~~~~~~~~~~~~~~~~~~^~
In file included from ./include/linux/cache.h:6,
                 from ./include/linux/printk.h:9,
                 from ./include/linux/kernel.h:14,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:1:
./arch/x86/include/asm/elf.h: At top level:
./arch/x86/include/asm/cache.h:8:25: error: ‘CONFIG_X86_L1_CACHE_SHIFT’ undeclared here (not in a function); did you mean ‘CONFIG_ARM_L1_CACHE_SHIFT’?
    8 | #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/cache.h:9:30: note: in expansion of macro ‘L1_CACHE_SHIFT’
    9 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
      |                              ^~~~~~~~~~~~~~
./include/linux/cache.h:13:25: note: in expansion of macro ‘L1_CACHE_BYTES’
   13 | #define SMP_CACHE_BYTES L1_CACHE_BYTES
      |                         ^~~~~~~~~~~~~~
./include/linux/cache.h:35:58: note: in expansion of macro ‘SMP_CACHE_BYTES’
   35 | #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
      |                                                          ^~~~~~~~~~~~~~~
./arch/x86/include/asm/elf.h:381:3: note: in expansion of macro ‘____cacheline_aligned’
  381 | } ____cacheline_aligned;
      |   ^~~~~~~~~~~~~~~~~~~~~
In file included from ./include/linux/module.h:24,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./arch/x86/include/asm/module.h:67:2: error: #error unknown processor family
   67 | #error unknown processor family
      |  ^~~~~
In file included from ./include/linux/kernel.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:1:
./include/linux/sched.h: In function ‘need_resched’:
./include/linux/thread_info.h:91:22: warning: passing argument 1 of ‘test_ti_thread_flag’ makes pointer from integer without a cast [-Wint-conversion]
   91 |  test_ti_thread_flag(current_thread_info(), flag)
      |                      ^~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      int
./include/linux/compiler.h:77:42: note: in definition of macro ‘unlikely’
   77 | # define unlikely(x) __builtin_expect(!!(x), 0)
      |                                          ^
./include/linux/thread_info.h:93:28: note: in expansion of macro ‘test_thread_flag’
   93 | #define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
      |                            ^~~~~~~~~~~~~~~~
./include/linux/sched.h:1613:18: note: in expansion of macro ‘tif_need_resched’
 1613 |  return unlikely(tif_need_resched());
      |                  ^~~~~~~~~~~~~~~~
In file included from ./arch/x86/include/asm/preempt.h:7,
                 from ./include/linux/preempt.h:81,
                 from ./include/linux/spinlock.h:51,
                 from ./include/linux/seqlock.h:36,
                 from ./include/linux/time.h:6,
                 from ./include/linux/stat.h:19,
                 from ./include/linux/module.h:10,
                 from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:2:
./include/linux/thread_info.h:77:59: note: expected ‘struct thread_info *’ but argument is of type ‘int’
   77 | static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
      |                                       ~~~~~~~~~~~~~~~~~~~~^~
In file included from /home/jonsen/f1c100s/test_chrdevbase/chardevbase.c:7:
./include/linux/gpio.h: At top level:
./include/linux/gpio.h:49:10: fatal error: asm/gpio.h: No such file or directory
   49 | #include <asm/gpio.h>
      |          ^~~~~~~~~~~~
cc1: some warnings being treated as errors
compilation terminated.
make[2]: *** [scripts/Makefile.build:323: /home/jonsen/f1c100s/test_chrdevbase/chardevbase.o] Error 1
make[1]: *** [Makefile:1508: _module_/home/jonsen/f1c100s/test_chrdevbase] Error 2
make[1]: Leaving directory '/home/jonsen/f1c100s/linux'
make: *** [Makefile:9: all] Error 2
晕哥 说:

可以的,亲自试过。

离线

#33 2021-04-15 14:44:09

cube
会员
注册时间: 2021-03-11
已发帖子: 288
积分: 202.5

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

感谢楼主, 测试了一下, 一楼的代码在 tiny200 tina3.5 linux 也可以跑.

离线

#34 2021-04-15 21:58:32

mysteryli
会员
注册时间: 2020-03-05
已发帖子: 485
积分: 390
个人网站

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

这种在应用层怎么调用?

离线

#35 2021-04-15 22:33:42

raspberryman
会员
注册时间: 2019-12-27
已发帖子: 503
积分: 465

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

mysteryli 说:

这种在应用层怎么调用?

只是一个简单的演示代码,如果需要应用层调用,需要加 open/close/read/write/ioctl 等操作代码

离线

#36 2021-05-07 22:30:04

microxp
会员
注册时间: 2021-04-27
已发帖子: 76
积分: 124

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

该评论内容与本帖子无关,鼓励各位坑友积极发言讨论与帖子有关的内容!

离线

  • 不通过:与技术无关

#37 2022-04-01 15:38:20

uuid
会员
注册时间: 2020-12-08
已发帖子: 45
积分: 31

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

把楼主的 hello.c 和 Makefile 复制后,编译:

ARCH=arm64 CROSS_COMPILE=/opt/a100/longan/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- make -C /opt/a100/longan/kernel/linux-4.9/ M=${PWD} modules

A133 的板子, 一块能中断, 一块不能中断,一头雾水。

离线

#38 2022-04-02 09:13:17

东哥
会员
注册时间: 2021-04-15
已发帖子: 11
积分: 5.5

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

我之前是用内存映射直接写寄存器,这个比我的方便多了

离线

页脚

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

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