免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9644 | 回复: 11
打印 上一主题 下一主题

[Linux资讯] 请问怎么把Linux 多个C文件编译成一个ko文件呢?(C文件里都有module_init) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-26 11:50 |只看该作者 |倒序浏览
是这样的:我用platform平台总线做驱动,有两个文件:

(1)平台设备led_dev.c

(2)平台驱动led_drv.c

l现在问题是,

led_dev.c中有:

int __init led_dev_init(void)
{
    platform_device_register(&led_device);  
   
    return 0;
}

module_init(led_dev_init);



led_drv.c中有:

int __init led_drv_init(void)
{
    platform_driver_register(&led_driver);
   
    return 0;
}

module_init(led_drv_init);

采用编译成模块时,
Makefile这样写:obj-m += led_dev.o led_drv.o
是可以把led_dev.c编译成led_dev.ko
         把led_drv.c编译成led_drv.ko

然后加载时insmod两次就行了!

但现在我想:能不能仅编译成一个ko文件,

加载时只需insmod一次就行了?

为达到此效果,我的Makefile改成这样:
obj-m += led.o
led-objs := led_dev.o led_drv.o
但编译会报错: multiple definition of `init_module'

请问:各位有什么方法呢?不妨赐教啊!小弟谢过~

论坛徽章:
0
2 [报告]
发表于 2014-08-26 14:32 |只看该作者
两个模块如果有关联,可以试试modprobe。要是觉得输入太多insmod麻烦,干脆写个脚本算了

论坛徽章:
0
3 [报告]
发表于 2014-08-26 16:49 |只看该作者
谢谢  我的两个模块 有关联的,一个是平台设备,一个平台驱动。你说的写脚本 是指利用脚本去完成多个ko文件的insmod吗?还是编译成一个ko文件呢?

论坛徽章:
0
4 [报告]
发表于 2014-08-26 17:13 |只看该作者
回复 3# 牡丹岩

关联的意思是模块具有依赖性,比如说一个模块会用到另一个模块的函数。modprobe会检查这种依赖性,然后先把依赖的模块的装上,再装其他的模块。脚本就是:
#/bin/bash
insmod **
insmod **
insmod **
*********
然后sudo运行

论坛徽章:
0
5 [报告]
发表于 2014-08-26 17:37 |只看该作者
嗯 谢啦。不过 有没有办法 编译成一个ko文件呢?

再问个问题:我insmod 加载驱动模块时,开发板会自动重启,这是为啥啊?

论坛徽章:
0
6 [报告]
发表于 2014-08-26 17:45 |只看该作者
回复 5# 牡丹岩
这我就不知道了,等其他人答吧

论坛徽章:
0
7 [报告]
发表于 2014-08-26 18:24 |只看该作者
本帖最后由 牡丹岩 于 2014-08-26 18:27 编辑

写个脚本 效果 还真不错 相见恨晚啊  谢了 !

内核重启时提示错误如下:
kernel bug at kernel/timer.c:662!
Unable to handle kernel NULL pointer dereference at virtual address 00000000

自动重启.png (82.49 KB, 下载次数: 94)

自动重启.png

论坛徽章:
0
8 [报告]
发表于 2014-08-28 10:30 |只看该作者
内核遇到空指针时,必然会重启。说明,你的驱动注册过程中,有野指针之类的错误出现。不信你把 platform_device_register(&led_device)和platform_driver_register(&led_driver)注释掉,看看,保证不重启。检查代码错误吧!

论坛徽章:
0
9 [报告]
发表于 2014-08-28 10:31 |只看该作者
内核重启时提示错误如下:
kernel bug at kernel/timer.c:662!
Unable to handle kernel NULL pointer dereference at virtual address 00000000

另外看你的Log提示, NULL pointer ,分明就是野指针。。再看溢出文件:timer.c:662!,定时器/看门狗退出
所以,检查你的源文件吧

论坛徽章:
0
10 [报告]
发表于 2014-08-28 13:07 |只看该作者
本帖最后由 牡丹岩 于 2014-08-28 13:13 编辑

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/input.h>
  4. #include <linux/interrupt.h>
  5. #include <asm/gpio.h>
  6. #include <linux/timer.h>


  7. static struct input_dev *p_button_dev = NULL;//定义输入设备

  8. struct timer_list my_timer;//定义定时器


  9. //定义定时器超时处理函数
  10. void timer_func(unsigned long data)
  11. {
  12.         int key_value = gpio_get_value(S5PV210_GPH2(0));

  13.         //上报事件给input核心层
  14.         input_report_key(p_button_dev, KEY_A, !key_value);//按下为1,释放为0

  15.              //告诉input子系统上报已经完成
  16.         input_sync(p_button_dev);
  17. }

  18. //中断处理函数
  19. static irqreturn_t button_interrupt(int irq, void *dev_id)
  20. {
  21.              mod_timer(&my_timer, jiffies + 5);//启动定时器以及设置超时时间
  22.    
  23.         return IRQ_HANDLED;
  24. }

  25. //初始化按钮
  26. static int __init button_init(void)
  27. {
  28.         int ret;
  29.         ret = gpio_request(S5PV210_GPH2(0), "key2");
  30.         if (ret)
  31.              {
  32.                 printk(KERN_ERR "gpio_request Failed to register device\r\n");

  33.                           goto error1;
  34.         }
  35.    
  36.              //为新输入设备分配内存并初始化
  37.         p_button_dev = input_allocate_device();
  38.         if (!p_button_dev)
  39.              {
  40.                 printk(KERN_ERR "can't allocate input mem!\r\n");

  41.                          goto error2;
  42.         }
  43.    
  44.         p_button_dev->name = "gec_input";
  45.         p_button_dev->id.bustype = 0x1;
  46.         p_button_dev->id.product = 0x2;
  47.         p_button_dev->id.vendor  = 0x3;
  48.         p_button_dev->id.version = 0x4;
  49.         p_button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);       
  50.              p_button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);   
  51.              //注册一个输入设备
  52.         ret = input_register_device(p_button_dev);
  53.         if (ret)
  54.              {
  55.                 printk(KERN_ERR "Failed to register device\r\n");

  56.                           goto error3;
  57.         }
  58.    
  59.                //申请中断注册中断处理函数
  60.         ret = request_irq(IRQ_EINT(16), button_interrupt,
  61.                                  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_DISABLED,
  62.                                       "button", NULL);
  63.         if (ret)
  64.         {
  65.                 printk(KERN_ERR "Can't request irq %d\r\n", IRQ_EINT(16));

  66.                           goto error4;
  67.         }   
  68.    
  69.         //定时器
  70.         init_timer(&my_timer);//初始化定时器
  71.         my_timer.function = timer_func;//注册定时器超时处理函数

  72.          return 0;
  73.    

  74. error4:
  75.             free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
  76.          input_unregister_device(p_button_dev);
  77.    
  78. error3:
  79.             input_free_device(p_button_dev);

  80. error2:
  81.            ret = -ENOMEM;

  82. error1:
  83.            gpio_free(S5PV210_GPH2(0));
  84.    
  85.            return ret;
  86. }

  87. static void __exit button_exit(void)
  88. {
  89.         gpio_free(S5PV210_GPH2(0));       
  90.         free_irq(IRQ_EINT(16), NULL);
  91.         input_unregister_device(p_button_dev);
  92.         del_timer(&my_timer);//删除内核定时器
  93. }

  94. module_init(button_init);
  95. module_exit(button_exit);

  96. MODULE_LICENSE("Dual BSD/GPL");
  97. MODULE_LICENSE("GPL");

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP