加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

S3C2410_GPB5' undeclared here (not in a function)解决方法

(2013-06-19 14:08:57)
标签:

杂谈

linux

驱动

分类: linux驱动程序

最近在做LED的驱动程序,编译出现很多问题。出现问题的代码如下:

 

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>


#define DEVICE_NAME "leds"

static unsigned long led_table [] = {
   S3C2410_GPB5,
   S3C2410_GPB6,
   S3C2410_GPB7,
   S3C2410_GPB8,
};

static unsigned int led_cfg_table [] = {
   S3C2410_GPB5_OUTP,
   S3C2410_GPB6_OUTP,
   S3C2410_GPB7_OUTP,
   S3C2410_GPB8_OUTP,
};

static int sbc2440_leds_ioctl(
   struct inode *inode,
   struct file *file,
   unsigned int cmd,
   unsigned long arg)
{
   switch(cmd) {
   case 0:
   case 1:
       if (arg > 4) {
           return -EINVAL;
       }
       s3c2410_gpio_setpin(led_table[arg], !cmd);
       return 0;
   default:
       return -EINVAL;
   }
}

static struct file_operations dev_fops = {
   .owner    =    THIS_MODULE,
   .ioctl    =    sbc2440_leds_ioctl,
};

static struct miscdevice misc = {
   .minor = MISC_DYNAMIC_MINOR,
   .name = DEVICE_NAME,
   .fops = &dev_fops,
};

static int __init dev_init(void)
{
   int ret;

   int i;
   
   for (i = 0; i < 4; i++) {
       s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
       s3c2410_gpio_setpin(led_table[i], 0);
   }

   ret = misc_register(&misc);

   printk (DEVICE_NAME"\tinitialized\n");

   return ret;
}

static void __exit dev_exit(void)
{
   misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");
编译make ARCH=arm CROSS_COMPILE=arm-linux-,出现错误:
e/guoqian/4.3.1/linux-2.6.32.2 M=/home/guoqian/led modules ARCH=arm CROSS_COMPILE=arm-linux-
make[1]: Entering directory `/home/guoqian/4.3.1/linux-2.6.32.2'
  CC [M]  /home/guoqian/led/mini2440_leds.o
/home/guoqian/led/mini2440_leds.c:29: error: 'S3C2410_GPB5' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:30: error: 'S3C2410_GPB6' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:31: error: 'S3C2410_GPB7' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:32: error: 'S3C2410_GPB8' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:36: error: 'S3C2410_GPB5_OUTP' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:36: error: initializer element is not constant
/home/guoqian/led/mini2440_leds.c:36: error: (near initialization for 'led_cfg_table[0]')
/home/guoqian/led/mini2440_leds.c:37: error: 'S3C2410_GPB6_OUTP' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:37: error: initializer element is not constant
/home/guoqian/led/mini2440_leds.c:37: error: (near initialization for 'led_cfg_table[1]')
/home/guoqian/led/mini2440_leds.c:38: error: 'S3C2410_GPB7_OUTP' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:38: error: initializer element is not constant
/home/guoqian/led/mini2440_leds.c:38: error: (near initialization for 'led_cfg_table[2]')
/home/guoqian/led/mini2440_leds.c:39: error: 'S3C2410_GPB8_OUTP' undeclared here (not in a function)
/home/guoqian/led/mini2440_leds.c:39: error: initializer element is not constant
/home/guoqian/led/mini2440_leds.c:39: error: (near initialization for 'led_cfg_table[3]')
/home/guoqian/led/mini2440_leds.c: In function 'sbc2440_leds_ioctl':
/home/guoqian/led/mini2440_leds.c:54: error: implicit declaration of function 's3c2410_gpio_setpin'
/home/guoqian/led/mini2440_leds.c: In function 'dev_init':
/home/guoqian/led/mini2440_leds.c:79: error: implicit declaration of function 's3c2410_gpio_cfgpin'
make[2]: *** [/home/guoqian/led/mini2440_leds.o] 错误 1
make[1]: *** [_module_/home/guoqian/led] 错误 2
make[1]: Leaving directory `/home/guoqian/4.3.1/linux-2.6.32.2'
make: *** [all] 错误 2

这个错误的原因是linux内核版本不同造成,上面那个LED驱动程序适合linux2.6.29,但是我的内核是linux2.6.32.2,升级内核版本函数和头文件变了,所以找不到S3C2410_GPB5和S3C2410_GPB5_OUTP的定义。

解决的方法是:

 

1、引用端口的定义,旧版本直接通过S3C2410_GPmn来定义端口GPIOm的第n个引脚,比如GOIOB的第5个引脚引用为S3C2410_GPB5。在新版本中改为采用S3C2410_GPm(n)的方式,比如GPIOB的第5个引脚就改为S3C2410_GPB(5)。这里的S3C2410_GPm(n)函数在arch/arm/march-2410/include/mach/gpio-nrs.h中定义,共有S3C2410_GPA()~S3C2410_GPH()八组。


2、端口功能配置,比如端口的复用功能、输出或输入。在旧版本中采用的是"S3C2410_GPB_功能"的方式定义,比如S3C2410_GPB5_OUTP,直接把功能加在后面。而新版本中采用了一个宏函数S3C2410_gpio_cfgpin(端口引用, 功能),比如S3C2410_gpio_cfgpin(S3C2410_GPB(5),S3C2410_GPIO_OUTPUT)。关于端口功能的定义可以在arch/arm/march-2410/include/mach/regs-gpio.h中找到,复用功能的定义没有变化,增加了输入输出的定义S3C2410_GPIO_INPUT、S3C2410_GPIO_OUTPUT。以前的直接用宏定义配置,现在变成了需要用函数S3C2410_gpio_cfgpin来实现。这个函数的原型参见arch/arm/march-2410/include/mach/gpio-fns.h。

接下来的两个错误:

 error: implicit declaration of function 's3c2410_gpio_setpin'

 

error: implicit declaration of function 's3c2410_gpio_cfgpin'

是因为因为在2.6.32.2内核中,s3c2410_gpio_cfgpin是在include/linux/gpio.h中定义的,所以要添加#include <linux/gpio.h>添加一个头文件为#include <linux/gpio.h>

再次编译通过。

 修改后的LED驱动程序为:

 

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/gpio.h>   //linux2.6.32.2必须包含这个头文件


#define DEVICE_NAME "leds" //混杂设备名

static unsigned long led_table [] = {
   S3C2410_GPB(5),   //在linux2.6.29中是S3C2410_GPB5
   S3C2410_GPB(6),
   S3C2410_GPB(7),
   S3C2410_GPB(8),
};

static int s3c2440_leds_ioctl(
   struct inode *inode,
   struct file *file,
   unsigned int cmd,
   unsigned long arg)   //定义ioctl函数
{
   switch(cmd) {
   case 0:
   case 1:
       if (arg > 4) {
           return -EINVAL;
       }
       s3c2410_gpio_setpin(led_table[arg], !cmd);  //给GPIO口置0
       return 0;
   default:
       return -EINVAL;
   }
}

static struct file_operations dev_fops = {
   .owner    =    THIS_MODULE,
   .ioctl    =    sbc2440_leds_ioctl,
};

static struct miscdevice misc = {    
   .minor = MISC_DYNAMIC_MINOR,
   .name = DEVICE_NAME,
   .fops = &dev_fops,
};  //定义混杂设备

static int __init dev_init(void)
{
   int ret;

   int i;
   
   for (i = 0; i < 4; i++) {
       s3c2410_gpio_cfgpin(led_table[i], S3C2410_GPIO_OUTPUT);  //设置GPIO为输出
       s3c2410_gpio_setpin(led_table[i], 0);     //初始化GPIO为0
   }

   ret = misc_register(&misc);  //注册混杂设备

   printk (DEVICE_NAME"\tinitialized\n");

   return ret;
}

static void __exit dev_exit(void)
{
   misc_deregister(&misc);   //注销混杂设备
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chenzhao");
加载LED驱动时insmod 会出现错误,因为LED的驱动程序已经存在,这时就需要重新配置内核,把LED驱动那一项去掉,移植心的内核,再次加载内核就不会有错了。呵呵!

http://s1/mw690/ba08e8e04df7e44cfe740&690undeclared here (not in function)解决方法" TITLE="S3C2410_GPB5' undeclared here (not in function)解决方法" />





 



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有