我本仁慈,奈何苍天不许
分类: LINUX
2013-12-17 14:43:59
添加LED驱动
第一种方法:
1、修改内核配置:
$ make menuconfig
Kernel Features --->
[*]Use this ARM EABI to compile the kernel
[*] Allow old BAI binaries to run with this kernel(EXPERIMENTAL)
2、添加驱动文件
将时间代码LED_TEST/fsc100_led_drv.c 拷贝到/drivers/char下
代码如下:
#ifdef MODULE
#include
#include
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
//#define __KERNEL__
#include
#include
#include
//#include
#include
#include
#include
//#include
//#include
//#include
//#include
#include
//#include
#include
//#include
MODULE_LICENSE ("GPL");
#define LED_ON 0x4800
#define LED_OFF 0x4801
#define GPG3CON *(volatile unsigned int *)S5PC100_GPG3_BASE
#define GPG3DAT *(volatile unsigned int *)(S5PC100_GPG3_BASE + 0x4)
static int major = 252;
static int minor = 0;
static dev_t devno;
static struct cdev cdev;
static int led_ioctl(struct inode *s_node,struct file *s_file,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case LED_ON:
GPG3DAT |= 0x0f;
break;
case LED_OFF:
GPG3DAT &= ~0x0f;
break;
}
return 0;
}
static struct file_operations led_fops=
{
.ioctl = led_ioctl
};
static void char_reg_setup_cdev(void)
{
int error;
cdev_init(&cdev, &led_fops);
cdev.owner = THIS_MODULE;
error = cdev_add(&cdev, devno, 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev\n", error);
return;
}
static int __init led_init(void)
{
int result;
devno = MKDEV(major, minor);
result = register_chrdev_region (devno, 1 , "led");
if (result < 0)
{
printk (KERN_WARNING "gpio : can't get major number %d\n", major);
return result;
}
char_reg_setup_cdev();
GPG3CON &= ~0xffff;
GPG3CON |= 0x1111;
printk (KERN_INFO "led driver registered\n");
return 0;
}
static void __exit led_exit(void)
{
cdev_del(&cdev);
unregister_chrdev_region(devno, 1);
printk (KERN_INFO "led driver unregistered\n");
return;
}
module_init(led_init);
module_exit(led_exit);
注意:下面两处标红的地方名字可以随意,但必须一致
3、修改drivers/char/Kconfig
在menu “Character devices”下面
添加如下内容:
config FSC100_LED
tistate “FSC100 LED Device Support”
depends on ARCH_S5PC100
help
Support led device on FS_S5PC100 develop board
4、修改drivers/char/Makefile
在obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o 下一行添加
Obj_$(CONFIG_FSC100_LED) +=fsc100_leddrv.o
5、交叉编译fsc100_led_test.c
代码如下:
#include
#include
#include
#include
#include
#define LED_ON 0x4800
#define LED_OFF 0x4801
int main(void)
{
int fd;
if((fd = open("/dev/led", O_RDWR)) == -1)
{
perror("open error");
exit(-1);
}
printf("open led ok\n");
while(1)
{
ioctl(fd, LED_ON, NULL); //GPG3 1
usleep(500000);
ioctl(fd, LED_OFF, NULL); //GPG3 0
usleep(500000);
}
close(fd);
return 0;
}
Arm-none-linux-gnueabi-gcc fsc100_led_test.c -o fsc100_led_test
6、最后通过mount命令挂载(在我的“Cortex-A8内核、文件系统下载和挂载共享目录”博客里有介绍如何挂载)
注意:在挂载之前需要配置开发板的IP,与Ubuntu系统的IP必须是同一网段。
7、可以在开发板的终端查看led的设备节点号
cat proc/devices
8、创建设备节点
mknod /dec/led c 252 0
9、最后运行可执行文件
第二种方法
第二种方法只是与第一种方法的配置方法不一样而已,所以这里只是如何配置。
1、在drivers/myled目录下创建目录,我这里取名为“myled”,然后把fsc100_led_drv.c文件拷贝到该目录下。
2、创建Kconfig文件:
menu "Character led"
config FSC100_LED
bool "s5p100_led support"
depends on ARCH_S5PC100
---help---
support led_test
endmenu
注意:Kconfig是以menu开头,以endmenu结束的,这是一种语法规定。
3、创建Makefile文件:
obj-$(CONFIG_FSC100_LED) += fsc100_led_drv.o
注意:上面两步,可以参考其他的驱动配置文件,如char
4、上面两步只是配置了myled目录下的两个文件,还得配置它的上一层目录下的Kcong和Makefile,让myled目录被识别.
5、/drivers目录下的Makefile:
在第一行添加如下一句话即可:
obj-y += myled/
6、/drivers目录下的Kconfig:
在第二行添加如下:
source "drivers/myled/Kconfig"
7、在顶层目录下make menuconfig 然后选中s5p100_led support
8、后面就是编译、烧写、测试,与第一种方法一样。