功能: 不用ioctl函数控制LED,用read函数读取PIO寄存器值, Write函数写入寄存器值实现控制LED灯
myleds_2.c
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/fcntl.h> #include <asm/io.h> #include <linux/string.h> #include <linux/cdev.h> #include <linux/device.h> #include <asm/uaccess.h> #include <linux/slab.h> #define DEV_NAME "leddev" #define NUMBER_OF_DEVICE 1 #define PIO_LED 0x00401420|0xE0000000 struct class *led_class; static struct cdev cdev; dev_t devno; static ssize_t led_open(struct inode *inode, struct file *file) { //printk(KERN_ALERT "led device open successfully!\n"); return 0; } static ssize_t led_release(struct inode *inode, struct file *file) { //printk(KERN_ALERT "led device close successfully!\n"); return 0; } static ssize_t led_read(struct file *file, char __user *buff, size_t count, loff_t *offp){ unsigned char led_dat; char led_string; if(NULL == file){ return -1; } led_dat = readb(PIO_LED) & 0x0f; if(sprintf(&led_string,"%x",led_dat)==0) { printk(KERN_ALERT "read:sprintf error\n"); return -EFAULT; } if(copy_to_user(buff,&led_string,count)!=0) { printk(KERN_ALERT "read:copy_to_user error\n"); return -EFAULT; } return count; } static ssize_t led_write(struct file *file, char __user *buff, size_t count, loff_t *offp){ unsigned char led_dat; char led_string; if(NULL == file){ return -1; } if(copy_from_user(&led_string,buff,count)!=0){ printk(KERN_ALERT "write:user pointer is not valid\n"); return -EFAULT; } if(sscanf(&led_string,"%x",&led_dat)==0){ printk(KERN_ALERT "write:sscanf error\n"); return -EFAULT; } writeb(led_dat,PIO_LED); return count; } static struct file_operations led_fops= { .owner= THIS_MODULE, .open = led_open, .read = led_read, .write = led_write, .release = led_release, }; static int led_init(void) { int ret; ret = alloc_chrdev_region(&devno,0, NUMBER_OF_DEVICE, DEV_NAME); if(ret<0){ printk(KERN_ALERT "%s alloc device error",__func__); return ret; } led_class = class_create(THIS_MODULE,"led_char_class"); if(IS_ERR(led_class)){ printk(KERN_ALERT "%s create class error\n",__func__); return -1; } device_create(led_class, NULL, devno, NULL, DEV_NAME); cdev_init(&cdev, &led_fops); cdev.owner = THIS_MODULE; cdev_add(&cdev, devno, NUMBER_OF_DEVICE); return 0; } static void led_exit(void) { printk(KERN_ALERT "%s",__func__); cdev_del(&cdev); device_destroy(led_class,devno); class_destroy(led_class); unregister_chrdev_region(devno,NUMBER_OF_DEVICE); } module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kimi Shi");
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include <unistd.h> int main(int argc,char **argv) { int fd, led_dat; char arg[3]; char buff; //check argument if(argc!=2 && argc!=3){ printf("INPUT ERROR, Use format below:\n"); printf("test_led_2 -r --read data from PIO_LED register\n"); printf("test_led_2 -w [0-15] --set PIO_LED register\n"); exit(1); } //check argument 1 if(sscanf(argv[1],"%s",&arg)!=1 || (strcmp(arg,"-r")!=0 && strcmp(arg,"-w")!=0) ){ printf("Input argument 1 wrong!\n"); exit(1); } //open led device fd=open("/dev/leddev",O_RDWR); if(fd<0){ perror("open led device\n"); exit(1); } //read PIO_LED register data if(strcmp(arg,"-r")==0){ read(fd, &buff, 1); printf("Value of PIO_LED register: %c\n",buff); } //Wrtie data to PIO_LED register if(strcmp(arg,"-w")==0){ //check argument, 0x00 to 0x0f if(sscanf(argv[2],"%d",&led_dat)!=1 ||led_dat<0 ||led_dat>15){ printf("input argument 2 wrong!\n"); exit(1); } sprintf(&buff,"%x",led_dat); write(fd,&buff,1); } //clode device close(fd); return 0; }
test_led_3.c 流水灯
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include <unistd.h> int main(int argc,char **argv) { int fd = -1; int i, cnt; unsigned char led = 0x0f; unsigned char buff; //open fd = open("/dev/leddev",O_RDWR); if(0>fd){ perror("open err:"); exit(1); } //light water while(1){ for(i=0;i<4;i++){ led &= (1 << i); sprintf(&buff, "%x",led); cnt = write(fd, &buff, 1); if(0>cnt){ perror("write err:"); exit(1); } led = 0x0f; sleep(1); } } //close close(fd); return 0; }