liunx驱动----点亮LED

liunx驱动----点亮LED,第1张

概述自动挂接根文件系统(直接从NFS启动) 修改uboot命令行 把 bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 改为: set bootarges noinitrd root=/dev/nfs nfsroot=192.168.0.104:/home/book/work/nfs_root/firs

自动挂接根文件系统(直接从NFS启动)

修改uboot命令行

把 bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200

改为: set bootarges noinitrd root=/dev/nfs nfsroot=192.168.0.104:/home/book/work/nfs_root/first_fs ip=192.168.0.10:192.168.0.104:192.168.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200   在uboot中设置如下: setenv bootargs noinitrd root=/dev/nfs console=ttySAC0 nfsroot=192.168.0.104:/home/book/work/nfs_root/first_fs ip=192.168.0.3:192.168.0.104:192.168.0.1:255.255.255.0::eth0:off init=/linuxrc 设置NFS启动参数 : 设置服务器IP,目录 设置自己的IP   运行第一个驱动程序 insmod first_drv.ko 挂载first_drv.ko cat /proc/devices 查看当前挂载了的驱动 ?

?
  增加一个测试程序    
include <sys/types.h>include <sys/stat.h>include <fcntl.h>include <stdio.h>  int main(int argc,char **argv){int fd;int val = 1;fd = open("/dev/xxx",O_RDWR);//打开if (fd < 0){printf("can‘t open!\n");}write(fd,&val,4);//return 0;}

 

  编译测试程序 arm-linux-gcc -o first_dev_test first_dev_test.c ?

?
提示不能打开当前测试文件是因为不存在/dev/xxx这个文件 所以需要创建这个设备节点 创建设备节点使用mknod 命令 mknod /dev/xxx c 111 0 命令 设备节点 设备类型(字符型) 主设备号(111) 次设备号   ?

?
  挂载设备 命令:insmod xxx(设备名称 卸载设备命令:rmmod xxx( 设备名称) 查看设备命令:lsmod cat /proc/devices 查看当前挂载了的驱动     自动分配主设备号 ? ?

?
在注册 register_chrdev函数中设备号位置填写0 系统将在自动分配设备号 1驱动程序里面可以自动分配主设备号 也可以手动指定设备号 应用程序去打开一个open("/dev/xxx",O_RDWR); 使用 mknod /dev/xxx c 主设备号 次设备号 手动创建 使用自动创建 使用udev机制 就是busyBox 中的mdev机制自动创建 (根据系统信息创设备节点)

定义一个类和一个设备

static struct class *firstdrv_class; static struct class_device *firstdrv_class_dev; 在初始化设备时添加 使用class_create创建一个firstdrv_class类 firstdrv_class = class_create(THIS_MODulE,"firstdrv");//创建一个 first_class 这样的一个类 使用class_device_create创建一个设备 设备节点是 xyz

firstdrv_class_dev = class_device_create(firstdrv_class,NulL,MKDEV(major,0),"xyz"); //mdev 自动创建一个 /dev/xyz */

 

int frist_drv_init(voID){major= register_chrdev(0,"frist_drv",&first_drv_fops);//注册函数(注册驱动程序) (major 主设备号 )告诉内核//主设备号 驱动名称 file_operations结构 /*生成系统信息*/firstdrv_class = class_create(THIS_MODulE,"firstdrv");//创建一个 first_class 这样的一个类firstdrv_class_dev = class_device_create(firstdrv_class,0),"xyz"); //mdev 自动创建一个 /dev/xyz */return 0;}

 

在出口函数中添加如下 使用class_device_unregister 函数来卸载 class_device_create创建的设备

class_device_unregister(firstdrv_class_dev);

使用class_destroy 释放 掉firstdrv_class这个类

class_destroy(firstdrv_class);

voID frist_drv_exit(voID){unregister_chrdev(major,"frist_drv");//卸载函数 卸载驱动class_device_unregister(firstdrv_class_dev);class_destroy(firstdrv_class);}

 

实现点亮LED灯功能   硬件 *** 作 映射虚拟地址 :使用 ioremap(off,sz) 函数 映射 /*将设备的物理地址映射为虚拟地址*/ gpfcon = (volatile unsigned long *)ioremap(0x56000050,16); //0x56000050 (物理 地址) 16(长度) gpfdat = gpfcon+1; //0x56000050+4 = 0x56000054 (物理地址) 16(长度) 取消虚拟地址映射:IoUnmap(_addr); IoUnmap(gpfcon); IoUnmap(gpfcon+1); 内核和用户之间参数传递 : copy_from_user的功能是从用户空间传递数据到内核空间 对应的 copy_to_user 从内核空间传递数据到 用户空间 copy_from_user(&val,buf,count);   配置 GPFCON open
static int first_drv_open(struct inode *inode,struct file *file){//printk("first_drv_open\n");/*配置GPFCON 4 5 6为输出*/*gpfcon &=~((0x3<<(4*2))|(0x3<<(5*2))|(0x3<<(6*2)));//清除GPFCON 4 5 6对应位*gpfcon |= ((0x1<<(4*2))|(0x1<<(5*2))|(0x1<<(6*2)));//设置 GPFCON 4 5 6 为输出return 0;}

 

  设置 GPFDAT write @H_419_687@
static ssize_t first_drv_write(struct file *file,const char __user *buf,size_t count,loff_t * ppos){int val;//printk("first_drv_write\n");copy_from_user(&val,count);//将buf中的数据拷贝到 val中 val的值等于 *buf的前0-count的数据 copy_from_user的功能是从用户空间传递数据到内核空间// 对应的 copy_to_user 从内核空间传递数据到 用户空间if(val == 0){*gpfdat |= ((1<<4)|(1<<5)|(1<<6));// 熄灭灯}else{*gpfdat &= ~((1<<4)|(1<<5)|(1<<6));//打开led}return 0;}

 

使用次设备号: 主设备号 是建立与内核的链接,次设备号 是用来给驱动使用的  总结

以上是内存溢出为你收集整理的liunx驱动----点亮LED全部内容,希望文章能够帮你解决liunx驱动----点亮LED所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1031292.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存