随着智能终端及物联网设备的普及,越来越多的软件和硬件基于Linux环境进行开发。特别是在涉及外设设备及固件开发时,编写兼容Linux的底层驱动是必不可少的环节。本文的目的旨在介绍如何编写一个简单的驱动框架。
首先,我们来分析一下Linux驱动的结构。大多数Linux驱动都具有类似的结构,具体可以分解为:头文件、数据结构定义以及驱动函数。
从数据结构定义开始,我们要定义驱动和外设访问所需要的相关变量,有下面三个数据结构:
1.设备对象:
struct my_dev{//设备号int devno;//设备名char dev_name[32];//API接口定义struct my_dev_operations *ops;//设备私有数据void *priv;};
2.设备操作:
struct my_dev_operations {int (*open)(struct my_dev* dev);int (*close)(struct my_dev* dev);int (*ioctl)(struct my_dev* dev);int (*read)(struct my_dev* dev, int *buf);int (*write)(struct my_dev* dev, int *buf);};
3.字符设备:
struct my_dev_char{ struct cdev cdev; int buf[64]; //......};
然后,要定义相应的驱动函数,比如open函数。该函数用于将设备驱动注册到系统并生成一个对应的设备对象,然后将该对象绑定到相应的设备号下:
int my_dev_open(struct inode* inode, struct file* filp){//定义一个设备对象struct my_dev *dev;//分配一个设备号int devno = get_devnumber();//为设备对象分配内存dev = (struct my_dev*)kmalloc(sizeof(struct my_dev));//为设备对象制定设备名sprintf(dev->dev_name, “my_dev%04d”, devno);//注册字符设备register_chrdev_region(MKDEV(devno, 0), 1, dev->dev_name);//分配一个字符设备struct my_dev_char *my_char_dev = (struct my_dev_char *) kmalloc(sizeof(struct my_dev_char), GFP_KERNEL);//初始化字符设备cdev_init(&my_char_dev->cdev, &my_dev_fops);//将设备绑定到设备号下cdev_add(&my_char_dev->cdev, MKDEV(devno, 0), 1);//保存设备号dev->devno = devno;//将设备对象放入filp中filp->private_data = dev;return 0;}
最后,在驱动入口函数中定义驱动的相关操作,注册驱动并完成相应的操作:
int __init my_dev_init(void){int ret;//注册驱动ret = register_chrdev(MY_DEV_MAJOR, MY_DEV_NAME, &my_dev_fops);if(ret{printk(KERN_ERR "register Gec6818 nand stor err\n");return ret;} //完成相应的操作//...return 0;}
经过上面的操作,一个简单的Linux驱动框架就被成功搭建起来了。通过上面的步骤,成功搭建了一个基本的驱动框架,可以更多地关注驱动程序的功能性。如此,一个稳健的Linux驱动就可以在Linux系统上运行了。
香港服务器首选树叶云,2H2G首月10元开通。树叶云(www.IDC.Net)提供简单好用,价格厚道的香港/美国云 服务器 和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
嵌入式linux U盘自动挂载
具体的操作过程如下:1.接入usb设备,然后运行命令:devlabel add -d /dev/sda1 -s /dev/usbdevice (--automount 可去掉!)/dev/sda1是usb设备名称,具体可以用fdisk -l查看,如果fdisk不能显示,可以用一个万能的方法: (#表示0,1,2,3....)检测/proc/scsi/usb-storage-#是否存在;如果存在,检测/proc/scsi/usb-storage-#/#是否存在;如果存在,检查文件/proc/scsi/usb-storage-#/#中最后一行Attach:是否是YES;如果是YES,那么 0 = sda, 1=sdb, 2=sdc ;/dev/usbdevice是要使用的用户定义的设备名称,这个可以放在任意的目录中,名字大家自己定automount指定:在 devlabel 重新启动时,如果 /etc/fstab 中有这个设备项目而且这个设备项目存在(找到了带有同一 UUID 的设备),那么就自动挂载这个项目。 2.建一个目录/mnt/usb3.打开/etc/fstab,在里面添加一行:/dev/usbdevice /mnt/usb auto noauto,owner 0 0这时就OK了,以后插入usb存储设备时就会自动挂载到/mnt/usb目录下了(前提是要有这个目录)解决思想:当某个 USB 设备被插入,hotplug 就会运行 updfstab 程序。 如果这个usb贮存设备存在,该程序会为它在 /etc/fstab 中添加一项记录。 所添加的这一行包含实际设备名称(如 /dev/sda1)和 kudzu 选项。 kudzu 选项通知 Kudzu工具如果设备不存在就删除这一行。 因为这一行是 devlabel 所需的,你必须删除 kudzu 选项才能使这一行被保留在文件内。 你还需把设备名称改成 devlabel 设备名称(如 /dev/usbdevice),并创建挂载点(如 /mnt/usb)。 所以修改后的就是上面的第3步.最后,还有一种最最简单的方法,也是我现在使用的方法哈:可以直接打开/etc/hotplug/ ,在里面找到add),在其中的if [ -x /sbin/devlabel ]; then /sbin/devlabel restartfi后面加上[ -x /usr/sbin/udisk ]&& /usr/sbin/udisk其中udisk是一个简单的挂载脚本:#! /bin/shmount|grep /mnt/usbif [ $? = 0 ]; thenumount /mnt/usbrmdir /mnt/usbelsemkdir /mnt/usbmount /dev/sda1 /mnt/usb fi 这样做的目的是:当usb设备接入时,hotplug程序就会自动运行,在运行脚本中加入一个挂载脚本,不就一切OK了么~~不过上面的讨论都只能用于挂载,卸载还是必须用umount(选第3种办法的直接打udisk),这是同WIN一样的.
学嵌入式linux是必须计算机专业的吗?入门的话怎么学?
不一定非要计算机专业的人才能学,只要肯钻,任何人都可以学。linux源代码开放,而且不是X86架构,所以不用担心学不会
Linux驱动中 什么设备都能用platform
这个好像是总线设备注册的规则吧,在2.6内核中引入的,更加方便些,使用cdev应该也可以,因为2.6内核中引入了platform总线结构,楼主可以看一下这方面的书籍。 。 。 。
发表评论