最近在做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 a function)解决方法" TITLE="S3C2410_GPB5' undeclared here (not in a function)解决方法" />
加载中,请稍候......