📄 tesled.c
字号:
#include <linux/kernel.h>#include <linux/module.h>#include <linux/fs.h>#include <asm/uaccess.h> /* get_user and put_user */#include <asm/arch/gpio.h>/* #define DEBUG */MODULE_LICENSE("GPL");MODULE_AUTHOR("Nelson Castillo/emQbit");#define SUCCESS 0#define DEVICE_FILE_NAME "tesled"#define DEVICE_NAME "tesled"#define MAJOR_NUM 101struct semaphore sw_sem;#define led_bit0 AT91_PIN_PC21 /* led */unsigned char led_state = 0;int default_led_state = 1;module_param(default_led_state, int, 0);intset_led_state(unsigned char s){ if (s <= 1) { at91_set_gpio_value(led_bit0, s & 0x1);#ifdef DEBUG printk(KERN_INFO "bit0: %x\n", s);#endif led_state = s; return 0; } return -1; /* error */}static int device_open(struct inode *inode, struct file *file){#ifdef DEBUG printk(KERN_INFO "device_open(%p)\n", file);#endif return SUCCESS;}static int device_release(struct inode *inode, struct file *file){#ifdef DEBUG printk(KERN_INFO "device_release(%p,%p)\n", inode, file);#endif return SUCCESS;}static ssize_t device_read(struct file *file, char __user * buffer, size_t length, loff_t * offset){ unsigned char value = led_state; int ret_val = 0; if (down_interruptible (&sw_sem)) return -ERESTARTSYS;#ifdef DEBUG printk(KERN_INFO "device_read(%p,%p,%d)\n", file, buffer, length);#endif if (put_user(value, buffer)) { ret_val = -EFAULT; goto read_exit; } ret_val++; read_exit: up(&sw_sem); return ret_val;}static ssize_tdevice_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset){ unsigned char value; int ret_val = 0; if (down_interruptible (&sw_sem)) return -ERESTARTSYS;#ifdef DEBUG printk(KERN_INFO "device_write(%p,%p,%d,%d)\n", file, buffer, length, *offset);#endif if (get_user(value, buffer)) { ret_val = -EFAULT; goto write_out; } if (set_led_state(value)) { ret_val = -EINVAL; goto write_out; } ret_val++;#ifdef DEBUG printk(KERN_INFO "wrote %x\n", value);#endifwrite_out: up(&sw_sem); return ret_val;}struct file_operations our_file_ops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release, .owner = THIS_MODULE,};int init_module(){ int ret_val; ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &our_file_ops); if (ret_val < 0) { printk(KERN_ALERT "device %s failed(%d)\n", DEVICE_NAME, ret_val); return ret_val; } sema_init(&sw_sem, 1); at91_set_gpio_output(led_bit0, 0); printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM); if (set_led_state(default_led_state)) printk(KERN_INFO "invalid default_led_state\n"); return SUCCESS;}void cleanup_module(){ int ret; ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME); if (ret < 0) printk(KERN_ALERT "Error: unregister_chrdev: %d\n", ret);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -