開發環境:紅帽企業版5,mini2440-2.6.29版本
交叉編譯器4.3.2
我是用mini2440板子啟動並執行,適合沒有驅動基礎的同學的。
原始碼如下:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/delay.h>#include <asm/uaccess.h>#include <asm/irq.h>#include <asm/io.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <linux/gpio.h>//#include <mach/gpio-nrs.h>#define LED_MAJOR 234 #define DEVICE_NAME "leds" static unsigned long led_table[]={ S3C2410_GPF3, S3C2410_GPF4, S3C2410_GPF5, S3C2410_GPF6, }; static unsigned long led_cfg_table[]={ S3C2410_GPF3_OUTP, S3C2410_GPF4_OUTP, S3C2410_GPF5_OUTP, S3C2410_GPF6_OUTP, }; int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd , unsigned long arg){ switch(cmd){ case 0: s3c2410_gpio_setpin(led_table[0],0); s3c2410_gpio_setpin(led_table[1],1); s3c2410_gpio_setpin(led_table[2],1); s3c2410_gpio_setpin(led_table[3],1); break; case 1: s3c2410_gpio_setpin(led_table[0],1); s3c2410_gpio_setpin(led_table[1],0); s3c2410_gpio_setpin(led_table[2],1); s3c2410_gpio_setpin(led_table[3],1); break; case 2: s3c2410_gpio_setpin(led_table[0],1); s3c2410_gpio_setpin(led_table[1],1); s3c2410_gpio_setpin(led_table[2],0); s3c2410_gpio_setpin(led_table[3],1); break; case 3: s3c2410_gpio_setpin(led_table[0],1); s3c2410_gpio_setpin(led_table[1],1); s3c2410_gpio_setpin(led_table[2],1); s3c2410_gpio_setpin(led_table[3],0); break; default: return -EINVAL; break; } return 0; } struct file_operations led_ops = { .owner = THIS_MODULE, .ioctl = led_ioctl, }; static int __init init_led(void) { int i, ret; ret = register_chrdev(LED_MAJOR,DEVICE_NAME,&led_ops); if(ret < 0){ printk(DEVICE_NAME, "can't register major number/n"); } for(i = 0; i < 4; i++){ s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]); s3c2410_gpio_setpin(led_table[i],1); } printk(DEVICE_NAME "initialized/n"); return 0; } static void __exit exit_led(void) { unregister_chrdev(LED_MAJOR,DEVICE_NAME); } module_init(init_led); module_exit(exit_led); MODULE_LICENSE("GPL"); MODULE_AUTHOR("linwei");
makefile如下:
ifneq ($(KERNELRELEASE),)obj-m := led2.oelseKDIR := /home/smb/kernel/linux-2.6.29all:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-clean:rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*endif
測試程式如下:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>int main(int argc, char **argv){int on;int led_no;int fd;if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no > 3) {fprintf(stderr, "Usage: leds led_no 0|1\n");exit(1);}fd = open("/dev/leds", 0);if (fd < 0) {fd = open("/dev/leds", 0);}if (fd < 0) {perror("open device leds");exit(1);}ioctl(fd, on, led_no);close(fd);return 0;}
虛擬機器運行圖:
開發板運行圖
本人弄了一上午才弄出來 讓大家見笑了,一次記錄我的驅動人生。