您的位置:首页 > 其它

最简单的驱动:LED驱动程序与应用程序解析

2011-08-23 15:14 417 查看
led驱动程序:

1 #include <linux/miscdevice.h>

2 #include <linux/delay.h>

3 #include <asm/irq.h>

4 #include <mach/regs-gpio.h>

5 #include <mach/hardware.h>

6 #include <linux/kernel.h>

7 #include <linux/module.h>

8 #include <linux/init.h>

9 #include <linux/mm.h>

10 #include <linux/fs.h>

11 #include <linux/types.h>

12 #include <linux/delay.h>

13 #include <linux/moduleparam.h>

14 #include <linux/slab.h>

15 #include <linux/errno.h>

16 #include <linux/ioctl.h>

17 #include <linux/cdev.h>

18 #include <linux/string.h>

19 #include <linux/list.h>

20 #include <linux/pci.h>

21 #include <asm/uaccess.h>

22 #include <asm/atomic.h>

23 #include <asm/unistd.h>

24

25

26 #define DEVICE_NAME "my_leds"

27

28 static unsigned long led_table [] = {

29 S3C2410_GPB5,

30 S3C2410_GPB6,

31 S3C2410_GPB7,

32 S3C2410_GPB8,

33 };

34

35 static unsigned int led_cfg_table [] = {

36 S3C2410_GPB5_OUTP,

37 S3C2410_GPB6_OUTP,

38 S3C2410_GPB7_OUTP,

39 S3C2410_GPB8_OUTP,

40 };

41

42 static int sbc2440_leds_ioctl(

43 struct inode *inode,

44 struct file *file,

45 unsigned long arg,

46 unsigned int cmd) //arg代表第几个led; cmd代表打开还是关闭

//原来此处cmd在前,arg在后,这样跟应用程序在用的时候的命令正好是个反的,所有我做了一下修改,相应的应用程序进行了相应的修改

47 {

48 int i ;

49 switch(cmd) {

50 case 0:

51 case 1:

52 if (arg > 4) {

53 return -EINVAL;

54 }

55 s3c2410_gpio_setpin(led_table[arg], !cmd);

56 return 0;

57 case 2:

58 if(arg > 4) //此处为自己添加的功能,用于同时打开4个led

59 {

60 return -EINVAL;

61 }

62 for(i=0;i<4;i++)

63 {

64 s3c2410_gpio_setpin(led_table[i], 0);

65 }

66 return 0;

67 case 3:

68 if(arg > 4) //此处为自己添加的功能,用于同时关闭4个led

69 {

70 return -EINVAL;

71 }

72 for(i=0;i<4;i++)

73 {

74 s3c2410_gpio_setpin(led_table[i], 1);

75 }

76 return 0;

77 default:

78 return -EINVAL;

79 }

80 }

81

82 static struct file_operations dev_fops = {

83 .owner = THIS_MODULE,

84 .ioctl = sbc2440_leds_ioctl,

85 };

86

87 static struct miscdevice misc = {

88 .minor = MISC_DYNAMIC_MINOR, //定义在miscdevice.h中,为255,表示自动获取次设备号

89 .name = DEVICE_NAME,

90 .fops = &dev_fops,

91 };

92

93 static int __init dev_init(void)

94 {

95 int ret;

96

97 int i;

98

99 for (i = 0; i < 4; i++) {

100 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

101 s3c2410_gpio_setpin(led_table[i], 1);

102 }

103

104 ret = misc_register(&misc);

105

106 printk (DEVICE_NAME"\tinitialized\n");

107

108 return ret;

109 }

110

111 static void __exit dev_exit(void)

112 {

113 misc_deregister(&misc);

114 }

115

116 module_init(dev_init);

117 module_exit(dev_exit);

118 MODULE_LICENSE("GPL");

119 MODULE_AUTHOR("FriendlyARM Inc.");

应用程序:

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <sys/ioctl.h>///系统调用头文件

int main(int argc,char **argv)

{

int led_no;

int led_ctl;

int fd;//区别fd与FILE *

//led_no=argv[1];//错误的!

//led_ctl=argv[2];

sscanf(argv[1],"%d",&led_no);//将argv[1]中的内容以整数的形式打印到led_no中,注意第三个参数必须是地址(变量的地址或者数组名)。

sscanf(argv[2],"%d",&led_ctl);

if(argc!=3||led_no>3||led_no<0||led_ctl>3||led_ctl<0)

printf("usage:./led_app led_num 1|0,1打开led,0关闭led\n");

fd=open("/dev/my_leds",0);//注意open的用法!

if(fd<0)

{

perror("cannot open device!\n");

exit(1);

}

ioctl(fd,led_no,led_ctl);//由于驱动程序改变,此处做了相应修改,将led_no与led_ctl位置调换了一下。

close(fd);//打开的设备别忘了关掉

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: