/* * Copyright (c) 2009-~ Lan Peng * * This source code is released for free distribution under the terms of the * GNU General Public License * * Author: Lan Peng<lanpeng722@gmail.com> * Created Time: 2009年09月14日 星期一 18时02分17秒 * File Name: led.c * * Description: */ #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/device.h> #include <linux/miscdevice.h> #include <linux/platform_device.h> #include <linux/types.h> #include <linux/io.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/interrupt.h> #include <asm/uaccess.h> #include <mach/irq.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/page.h> #include <mach/hardware.h> #include <mach/platform.h> #include <mach/lpc32xx_gpio.h> #define GPO_5_SET (*(volatile unsigned int __force *)0xf4028004)//虚拟地址 #define GPO_5_CLR (*(volatile unsigned int __force *)0xf4028008)//虚拟地址 #define GPO_5 (1<<5) //寄存器的第五位控制led灯 #define DEV_NAME "ledlan"//设备文件名 #define IO_SET 1 #define IO_CLR 0 static int lan_led_open(struct inode *inode, struct file *file); static int lan_led_release(struct inode *inode, struct file *file); static ssize_t lan_led_write(struct file *file, const char __user *buff, ssize_t count, loff_t *ppos); static ssize_t lan_led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int lan_led_open(struct inode *inode, struct file *file) { printk("Open......\n"); try_module_get(THIS_MODULE); GPO_5_SET |= GPO_5; return 0; } static int lan_led_release(struct inode *inode, struct file *file) { printk("Release......\n"); module_put(THIS_MODULE); return 0; } static ssize_t lan_led_write(struct file *file, const char __user *buff, ssize_t count, loff_t *ppos) { int i; unsigned char ctrl=0; if(count > 1) return -1; printk("write......\n"); get_user(ctrl, (u8 *)buff); i = (ctrl - 0x30)&0x03; if(i == 0) GPO_5_CLR |= GPO_5; else if(i == 1) GPO_5_SET |= GPO_5; return count; } static ssize_t lan_led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch(cmd) { case IO_SET: GPO_5_SET |= GPO_5; break; case IO_CLR: GPO_5_CLR |= GPO_5; break; default: GPO_5_SET |= GPO_5; break; } return 0; } static struct file_operations lan_led_fops = { .owner = THIS_MODULE, .write = lan_led_write, .ioctl = lan_led_ioctl, .open = lan_led_open, .release = lan_led_release, }; static struct miscdevice lan_led_miscdev = { /*杂设备*/ .minor = MISC_DYNAMIC_MINOR, .name = DEV_NAME, .fops = &lan_led_fops, }; static int __init lan_init(void) { int ret; printk("init......\n"); ret = misc_register(&lan_led_miscdev); if(ret) printk("Failed to register miscdev"); return 0; } static void __exit lan_exit(void) { printk("byebye......\n"); misc_deregister(&lan_led_miscdev); } module_init(lan_init); module_exit(lan_exit); MODULE_LICENSE("GPL");
//用户态测试程序:test_led.c: /* * Copyright (c) 2009-~ Lan Peng * * This source code is released for free distribution under the terms of the * GNU General Public License * * Author: Lan Peng<lanpeng722@gmail.com> * Created Time: 2009年09月14日 星期一 20时21分18秒 * File Name: test_led.c * * Description: */
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int main(int args, char *argv[]) { int fd; int i; char buf; fd = open("/dev/ledlan", O_RDWR); if(fd == -1) { printf("Open Error!\n"); exit(1); } #if 1 for(i = 0; i < 10; i++){ buf = '1'; write(fd, &buf, 1); usleep(300000); buf = '0'; write(fd, &buf, 1); usleep(300000); } #endif
#if 1 printf("ioctl......"); for(i = 0; i < 10; i++){ ioctl(fd, 0, NULL); usleep(300000); ioctl(fd, 1, NULL); usleep(300000); } #endif return 0; }
|