第一个嵌入式linux驱动程序——LED

2019-07-12 22:14发布

驱动程序如下: #include #include #include #include #include #include #include #include #include #include #include //新版内核 static struct class *first_class; static struct class_device *first_class_dev; volatile unsigned long *gpmcon=NULL; volatile unsigned long *gpmdat=NULL; static int first_open(struct inode * inode, struct file * file) { //printk("open "); *gpmcon &= 0xffff1111; return 0; } static ssize_t first_write(struct inode * file, const char __user *buf, size_t count, loff_t *ppos) { //printk("write "); int val; copy_from_user(&val,buf,count); printk("val=%d ",val); if(val==1) { *gpmdat &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)); } else { *gpmdat |=(1<<0)|(1<<1)|(1<<2)|(1<<3); } printk("gpmdatl=%d ",*gpmdat); return 0; } static struct file_operations first_openration ={ .owner = THIS_MODULE, .open = first_open, .write = first_write, }; int major; static int first_init(void) { //参数为0表示然系统自动分配设备号 major=register_chrdev( 0, "first",&first_openration); first_class = class_create(THIS_MODULE, "first"); //自动创建设备节点 /* 新版的内核不能用class_device_create 要用device_create*/ first_class_dev = device_create(first_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */ gpmcon = (volatile unsigned long*)ioremap(0x7F008820,16);//重映射 gpmdat=gpmcon+1;//指针的操作是按照指针指向的长度为单位? /*本例中使用的是unsigned long类型刚好是4个字节*/ return 0; } static void first_exit(void) { unregister_chrdev( major, "first"); /* 新版的内核不能用class_device_unregister 要用device_unregister*/ device_unregister(first_class_dev); class_destroy(first_class); iounmap(gpmcon);//释放重映射 } module_init(first_init); module_exit(first_exit); MODULE_LICENSE("GPL");
测试程序如下: #include #include #include #include int main(int argc,char **argv) { int fd; int val=1; fd=open("/dev/xyz",O_RDWR); if(fd < 0) printf("can not open!!! "); if(argc !=2) { printf("Usage: "); printf("%s ",argv[0]); } if(strcmp(argv[1],"on")==0) { val=1; } else { val=0; } write(fd,&val,4); printf("user val=%d ",val); return 0; }
输入命令:./main on 点亮所有的灯    ./mian off  熄灭所有的灯