📄 led.c
字号:
/*#define MODULE*/#include <linux/kernel.h>#include <linux/module.h>#include <asm/uaccess.h>#include <linux/mm.h>#include <linux/ioport.h>#include <asm/io.h>#include <linux/ioport.h>#include <linux/fs.h>#include <linux/wrapper.h>#define DRAM_MEM_MAJOR 231#define DEVICE_NAME "device_led"#define SUCCESS 0static int Device_Open = 0;int dram_mem_init(void);static int device_open(struct inode *,struct file *);static int device_release(struct inode *,struct file *);static ssize_t device_read(struct file *,char *,size_t,loff_t *);static ssize_t device_write(struct file *,const char *,size_t,loff_t *);static loff_t device_seek(struct file *,loff_t,int);int init_module(void);void cleanup_module(void);struct file_operations dram_mem_ops ={ llseek: device_seek, read: device_read, write: device_write, open: device_open, release: device_release};static int Major;unsigned long virt_addr0; unsigned long virt_addr1;unsigned long virt_addr2;int dram_mem_init(void){ virt_addr0 = (unsigned long)ioremap((unsigned long)0x56000050,0x4); *(unsigned long *)virt_addr0&= 0xffff0000;//清零 *(unsigned long *)virt_addr0|= 0x5400;//输出有效 virt_addr1 = (unsigned long)ioremap((unsigned long)0x56000054,0x4); *(unsigned long *)virt_addr1=0x0; virt_addr2 = (unsigned long)ioremap((unsigned long)0x56000058,0x4); *(unsigned long *)virt_addr2&= 0xffffff1f;//IO使能 Major = register_chrdev(DRAM_MEM_MAJOR,DEVICE_NAME,&dram_mem_ops); if(Major <0) { iounmap((void *)virt_addr0); iounmap((void *)virt_addr1); iounmap((void *)virt_addr2); printk("DRAM_MEM init_module:failed with %d\n",Major); return Major; } Major = DRAM_MEM_MAJOR; printk("DRAM_MEM_MAJOR registred: Major = %d\n" ,Major); return 0;}static int device_open(struct inode * inode,struct file *file){ if(Device_Open) { return -EBUSY; } Device_Open++; MOD_INC_USE_COUNT; return SUCCESS;}static int device_release(struct inode * inode,struct file *file){ Device_Open --; MOD_DEC_USE_COUNT; return 0;}static ssize_t device_read(struct file *file, char * buffer, size_t length, loff_t * offset){ volatile unsigned int intx; /*unsigned long num;*/ unsigned long len; unsigned long * address; GPFUP&= 0xffffff1f;//IO使能 GPFCON&= 0xffff0000;//清零 GPFCON|= 0x5400;//输出有效d long *)virt_addr; /*printk("*offset read = %x\n",*offset);*/ len = 0; if(length < 4) { printk("<1>device_read:length must larger than 4 \n"); return -1; } while(length) { //num = (unsigned long *)(* offset) - 0x30000000; //intx = address[num]; intx = address[(*offset)]; //intx = LONGSWAP(intx); if(copy_to_user(buffer,(char *)&intx,4)) return -1; buffer = buffer + 4; *offset = *offset + 1; length = length - 4; len = len + 4; } return (len);}static ssize_t device_write(struct file *file, const char * buffer, size_t length, loff_t * offset){*(unsigned long *)virt_addr1=*buffer;return(0); }static loff_t device_seek(struct file *filp,loff_t off,int whence){ loff_t newpos; switch(whence) { case 0: newpos = off; break; case 1: newpos = filp->f_pos +off; break; case 2: return -EINVAL; break; default: return -EINVAL; } if((unsigned long)newpos <0) return -EINVAL; filp->f_pos = newpos; return newpos;}#ifdef MODULEint init_module(){ return dram_mem_init();}void cleanup_module(){ int ret; iounmap((void *)virt_addr0); iounmap((void *)virt_addr1); iounmap((void *)virt_addr2); ret = unregister_chrdev(Major,DEVICE_NAME); if(ret < 0) { printk("unregister_chrdev:error %d\n",ret); } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -