最近比较忙,所以到现在才更新内容。下面是我借鉴加改良的驱动代码,在板上运行没有问题。
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define IOCTL_GPIO_ON 1
- #define IOCTL_GPIO_OFF 0
- MODULE_LICENSE("GPL");
- static dev_t devnr;
- static struct cdev cdev;
- static struct class *led_class;
- static struct device *led_device;
- static unsigned long leds_table[] =
- {
- S5PV210_MP04(4),
- S5PV210_MP04(5),
- S5PV210_MP04(6),
- S5PV210_MP04(7),
- };
- static char leds_name[][4] = {{"LED1"},{"LED2"},{"LED3"},{"LED4"}};
- #define LED_SIZE ARRAY_SIZE(leds_table) //在kernel.h中定义
- static int led_open(struct inode *inode, struct file *filp)
- {
- int i;
- int err;
-
- /* for(i = 0; i < LED_SIZE; i++)
- {
- err = gpio_request(leds_table[i], leds_name[i]);
- if(err){
- printk(KERN_ERR "fail to request S5PV210_MP04(%d)n",i + 4);
- return err;
- }
- }*/
-
- for(i = 0; i < LED_SIZE; i++)
- {
- s3c_gpio_cfgpin(leds_table[i], S3C_GPIO_OUTPUT);
- gpio_set_value(leds_table[i], 0);
- //gpio_direction_output(leds_table[i],0);
- //gpio_set_value(led_table[i],0);
- }
- printk(KERN_INFO "LEDs driver successfully open!n");
- return 0;
- }
- static int led_close(struct inode *inode, struct file *filp)
- {
- /*gpio_free(leds_table[0]);
- gpio_free(leds_table[1]);
- gpio_free(leds_table[2]);
- gpio_free(leds_table[3]);*/
- printk(KERN_ERR "leds successfully close!n");
- return 0;
- }
- static int led_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
- {
- if(arg > LED_SIZE)
- {
- return -EINVAL;
- }
- switch(cmd){
- case IOCTL_GPIO_ON:
- gpio_set_value(leds_table[arg],0);
- //gpio_direction_output(leds_table[arg],1);
- break;
-
- case IOCTL_GPIO_OFF:
- gpio_set_value(leds_table[arg],1);
- //gpio_direction_output(leds_table[arg],0);
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
- }
- struct file_operations led_fops = {
- .owner = THIS_MODULE,
- .open = led_open,
- .ioctl = led_ioctl,
- .release = led_close,
- };
- //装载模块
- static int __init led_init(void)
- {
- int ret;
- // 设备号的获取
- ret = alloc_chrdev_region(&devnr, 0, 1, "led_device");
- if(ret){
- printk(KERN_ERR "alloc char device region fail!n");
- return ret;
- }
-
- //初始化cdev并添加到系统
- cdev_init(&cdev, &led_fops);
-
- ret = cdev_add(&cdev, devnr, 1);
- if(ret){
- printk(KERN_ERR "add cdev fail!n");
- goto add_error;
- }
- //创建设备节点
- led_class = class_create(THIS_MODULE, "led_class"); /*创建类,在/sys/class下显示信息*/
- if(IS_ERR(led_class)){
- printk(KERN_ERR "class create fail!n");
- goto class_error;
- }
-
- led_device = device_create(led_class, NULL,devnr, NULL, "led_device"); /*创建节点,存在于/dev/ */
- if(IS_ERR(led_device)){
- printk(KERN_ERR "device create fail!n");
- goto device_error;
- }
- printk(KERN_INFO "SUCCCESS!n");
-
- return 0;
-
- //错误处理
- device_error:
- class_destroy(led_class);
- class_error:
- cdev_del(&cdev);
- add_error:
- unregister_chrdev_region(devnr, 1);
- return -ENODEV;
- }
- //卸载模块
- static void __exit led_exit(void)
- {
- device_destroy(led_class, devnr);
- class_destroy(led_class);
- cdev_del(&cdev);
- unregister_chrdev_region(devnr, 1);
- }
- module_init(led_init);
- module_exit(led_exit);
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define DEVICE "/dev/led_device"
- #define IOCTL_GPIO_OFF 0
- #define IOCTL_GPIO_ON 1
- int main(int argc, char **argv)
- {
- int fd;
- int time = 1;
- fd = open(DEVICE, O_RDWR);
- if(fd < 0){
- printf("open file error!n");
- return fd;
- }
- printf("led start to work!!n");
-
- while(1)
- {
- time++;
- printf("led flow work %d timen",time);
- ioctl(fd, IOCTL_GPIO_ON,0);
- ioctl(fd, IOCTL_GPIO_OFF,1);
- ioctl(fd, IOCTL_GPIO_ON,2);
- ioctl(fd, IOCTL_GPIO_OFF,3);
- sleep(1);
- ioctl(fd, IOCTL_GPIO_OFF,0);
- ioctl(fd, IOCTL_GPIO_ON,1);
- ioctl(fd, IOCTL_GPIO_OFF,2);
- ioctl(fd, IOCTL_GPIO_ON,3);
- sleep(1);
- }
- return 0;
- }
- #leds Makefile
- ARCH=arm
- CROSS_COMPILE=/home/huangsp/ok210/arm-2009q3/bin/arm-none-linux-gnueabi-
- APP_COMPILE=/home/huangsp/ok210/arm-2009q3/bin/arm-none-linux-gnueabi-
- #obj-m := led_app.o
- obj-m :=led_drv.o
- #KDIR := /path/to/kernel/linux/
- KDIR := /home/huangsp/ok210/android-kernel-samsung-dev/
- PWD := $(shell pwd)
- default:
- make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
- app:led_app.c
- $(APP_COMPILE)gcc -o app led_app.c
- clean:
- $(MAKE) -C $(KDIR) M=$(PWD) clean