Driver for linux-2.6.38
tree
├── led_misc_drv.c
├── Makefile
├── my_led_cmd.h
└── test.c
1. my_led_cmd.h
#ifndef __MY_LED_CMD_H__ #define __MY_LED_CMD_H__ #define MY_MAGIC 0x58 #define MY_MAX_NR 2 /* max number of cmd */ #define MY_IOC_ON _IO(MY_MAGIC,0) #define MY_IOC_OFF _IO(MY_MAGIC,1) #endif
2. led_misc_drv.c
#include <linux/module.h> #include <linux/miscdevice.h> #include <linux/ioctl.h> #include <linux/fs.h> #include <mach/regs-gpio.h> #include <plat/gpio-cfg.h> #include <mach/gpio-fns.h> #include "my_led_cmd.h" #define DEVICE_NAME "my_led" #define OUTLOW 0 /* pull down to light LED */ #define OUTHIGH 1 /* GPB 5 6 7 8 low active */ #define LED(x) S3C2410_GPB(x) static void initpin(unsigned int pin) { s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); s3c_gpio_cfgpin(pin, S3C2410_GPIO_OUTPUT); } static int my_open(struct inode *inode, struct file *file) { char i; for(i=5;i<=8;i++) initpin(LED(i)); return 0; } static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { if(_IOC_TYPE(cmd) != MY_MAGIC) { printk(DEVICE_NAME " ioctl magic not same.\n"); return -EINVAL; } if(_IOC_NR(cmd) > MY_MAX_NR) { printk(DEVICE_NAME " ioctl magic out of max number.\n"); return -EINVAL; } switch(cmd) { case MY_IOC_ON: s3c2410_gpio_setpin(LED(arg), OUTLOW); break; case MY_IOC_OFF: s3c2410_gpio_setpin(LED(arg), OUTHIGH); break; default: return -EINVAL; } return 0; } static struct file_operations my_fops = { .owner = THIS_MODULE, .open = my_open, .unlocked_ioctl = my_ioctl, }; static struct miscdevice my_device = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &my_fops, }; static int __init my_init(void) { misc_register(&my_device); printk (DEVICE_NAME" driver init\n"); return 0; } static void __exit my_exit(void) { misc_deregister(&my_device); printk (DEVICE_NAME" driver exit\n"); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");
3. test.c
#include <stdio.h> #include <unistd.h> #include <error.h> #include <fcntl.h> #include <sys/ioctl.h> #include "my_led_cmd.h" #define DEV_PATH "/dev/my_led" int main(int argc, char **argv) { int i=5; int fd = open(DEV_PATH, O_RDWR); if(fd < 0) { perror("open"); return 1;} while(i) { ioctl(fd,MY_IOC_ON,i); sleep(1); ioctl(fd,MY_IOC_OFF,i); i++; if(i>8) { i=5; } } return 0; }
4. Makefile
#Makefile CC=arm-linux-gcc DRV_OBJ := led_misc_drv obj-m := $(DRV_OBJ).o PWD := $(shell pwd) K_DIR :=/home/kozmers/Workspace/machine/ARM/__01_qq2440/__02_kernel/linux-2.6.38 OBJS=test.o all: $(MAKE) -C $(K_DIR) M=$(PWD) modules cp $(DRV_OBJ).ko /srv/nfs/
test:$(OBJS) $(CC) -o $@ $< arm-linux-strip test cp test /srv/nfs/
clean: $(MAKE) -C $(K_DIR) M=$(PWD) clean
-rm test