1、查看原理图,得到控制led的管脚GPF4/GPF5/GPF6
2、查看datasheet,找到LED对应的寄存器(GPFCON, GPFDAT)
目的是得到控制寄存器和数据寄存器的地址以及控制寄存器的控制模式选择
该寄存器占用16个字节,其中4个字节是保留字节
3、开始编写LED驱动程序
1
2
#include 3
#include 4
#include 5
#include 6
#include 7
#include 8
#include 9
#include 10
#include 11
#include 12
13
static struct class *my01drv_leds_class; 14
static struct class_device *my01drv_leds_dev;15
16
volatile unsigned long *gpfcon = NULL; 17
volatile unsigned long *gpfdat = NULL;18
19
static int my01drv_leds_open(struct inode *inode, struct file *file)20
{21
22
*gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));23
*gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));24
return 0;25
}26
27
static ssize_t my01drv_leds_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)28
{29
int val;30
int num=0;31
copy_from_user(&val,buf,count);32
if(val == 1) 33
*gpfdat &= ~((1<<4) | (1<<5) | (1<<6));34
else 35
*gpfcon |= ((1<<4)|(1<<5)|(1<<6));36
37
return 0;38
}39
40
static struct file_operations my01drv_leds_fops = {41
.owner = THIS_MODULE, 42
.open = my01drv_leds_open, 43
.write = my01drv_leds_write, 44
};45
46
int my01drv_leds_major;47
static int my01_leds_init(void)48
{49
50
my01drv_leds_major = register_chrdev(0, "my01drv_leds", &my01drv_leds_fops);51
52
53
54
my01drv_leds_class = class_create(THIS_MODULE,"my01drvleds");55
56
57
58
my01drv_leds_dev = class_device_create(my01drv_leds_class,NULL,MKDEV(my01drv_leds_major,0),NULL,"JIJIJI");59
60
61
62
gpfcon = (volatile unsigned long *)ioremap(0x56000050,16);63
64
65
gpfdat = gpfcon + 1;66
67
return 0;68
}69
static int my01_leds_exit(void)70
{71
72
unregister_chrdev(my01drv_leds_major, "my01drv_leds");73
74
class_device_create(my01drv_leds_dev);75
76
class_destroy(my01drv_leds_class);77
78
iounmap(gpfcon);79
}80
81
82
module_init(my01_leds_init);83
module_exit(my01_leds_exit);84
85
86
MODULE_AUTHOR("jishubao");87
MODULE_VERSION("0.1.0");88
MODULE_DESCRIPTION("S3C2410/S3C2440 LED Driver");89
MODULE_LICENSE("GPL");90
4、编写测试程序
1
#include
2
#include
3
#include
4
#include
5
int main(int argc, char **argv)
6
{
7
int val = 1;
8
int fd = open("/dev/JIJIJI",O_RDWR);
9
if(fd < 0)
10
printf("can't open
");
11
if(argc != 2)
12
{
13
printf("Usage :
");
14
printf("%s
", argv[0]);
15
return 0;
16
}
17
if (strcmp(argv[1], "on") == 0)
18
{
19
val = 1;
20
printf("LED ON OK
");
21
}
22
else
23
{
24
val = 0;
25
printf("LED OFF OK
");
26
}
27
28
write(fd, &val, 4);
29
return 0;
30
}
5、编写Makefile
1KERN_DIR = /home/fs/linux/linux-2.6.22.623all:4 make -C $(KERN_DIR) M=`pwd` modules 56clean:7 make -C $(KERN_DIR) M=`pwd` modules clean8 rm -rf modules.order910obj-m += my01leds_driver.o6、编译驱动文件和测试文件,拷贝到单板运行
1
fs@ubuntu:~/linux/mydrvtest/my01leds_driver$ make
1fs@ubuntu:~/linux/mydrvtest/my01leds_driver$ arm-linux-gcc -o my01leds_test my01leds_test.c
1
fs@ubuntu:~/linux/mydrvtest/my01leds_driver$ sudo cp my01leds_test my01leds_driver.ko /source/rootfs/fs_2440/
1# insmod my01leds_driver.ko
1
# ./my01leds_test on
若是卸载出现段错误,请注意是否是驱动程序中的卸载设备类与设备顺序是否有误,正确的是先注册类后注册设备,先卸载设备后卸载设备类
7、基本完成工作目的
后期实时更新链接:
LED驱动练习