Linux驱动程序 嵌入式.docx
《Linux驱动程序 嵌入式.docx》由会员分享,可在线阅读,更多相关《Linux驱动程序 嵌入式.docx(33页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、硬盘的容量=主分区的容量+扩展分区的容量扩展分区的容量=各个逻辑分区的容量之和扩展分区是不能直接用的,他是以逻辑分区的方式来使用的,所以说扩展分区可分成假设干逻辑分区,扩展分区如果不再 进行分区了,那么扩展分区就是逻辑分区了。一块物理硬盘只能有:一到四个主分区(但其中只能有一个是活动的主分区),或一到三个主分区,和一个扩展分区。分别对 应 hdal,hda2,hda3,hda4.Linux中规定,每一个硬盘设备最多能有4个主分区(其中包含扩展分区)构成,任何一个扩展分区都要占用一个主 分区号码,也就是在一个硬盘中,主分区和扩展分区一共最多是4个。进程上下文:就是表示进程信息的一系列东西,包括各
2、种变量、寄存器以及进程的运行的环境。这样,当进程被切换后, 下次再切换回来继续执行,能够知道原来的状态。中断上下文:就是中断发生时,原来的进程执行被打断,那么就要把原来的那些变量保存下来,以便中断完成后再恢复。一、字符设备驱动static为防止与其他模块函数重名,让其链接特性是内部的我们所在自己编写的Makefile文件,KERNELRELEASE是在内核顶层Makefile中定义的,执行make modules_install 会在/home/rootf/lib/modules/extra 下面创立模块dmesg | tail -10查看最后10条命令在开发板:depmod建立模块链接mod
3、probe memdev 安装模块 modprobe -r| memdev 卸载模块 modinfo v模块名 获得模块信息echo xxxx /dev/memdevOcat /dev/memdevO流程:应用层根据设备文件,找到设备号,继而找到cdev.dev(dev_t dev;)与cdev.ops(const struct file_operations*ops;)就知道调用方法了,我们的目的是完成这个struct file_operations这个结法体init属性标志,说明该段代码位于代码段的子段初始化段,初始化段的程序只执行一次,执行完后它所占用的内存 空间将被回收。当模块加载时,
4、init属性的函数就被执行;驱动程序:使硬件工作的软件驱动的分类:字符设备驱动、网络接口驱动、块设备驱动程序字符设备:是一种按字节来访问的设备,字符驱动用来驱动字符设备,这样的驱动通常实现open、close, read, write系统调用块设备:1、在大局部unix系统,块设备不能按字节处理数据,只能一次传送一个或者多个长度是512字节 (或者更大的2次累的数)的整块数据,块设备允许随机访问2、而linux那么允许块设备传输任意数目的字节,因此,块与字符设备的区别仅仅是驱动的与内核的接 口不同网络接口:任何网络事务都通过一个接口来进行,一个接口通常是一个硬件设备(ethO),但是它也可以是
5、一个纯粹的软件设备,比方回环接口(1。)【自己发自己收】。一个网络接口负责发送和接收数据报文kconfig:用来生成配置菜单的hello.c代码如下:#include #include static int init hello_init(void)系统提供了 4个宏对描述符集进行操作:#include void FD_SET(int fd, fd-set *fdset)void FD_CLR(int fd, fd_set *fdset)void FD_ZERO(fd_set*fdset)void FDJSSET(int fd, fd_set *fdset)宏FD_SET将文件描述符fd添加到
6、文件描述符集fdset中;宏FD_CLR从文件描述符集fdset中清除文件描述符fd;宏FD_ZERO清空文件描述符集fdset;在调用select后使用FDJSSET来检测文件描述符集fdset中的文件fd发生了变化.Poll方法unsigned int poll(struct file *file, poll_table *wait)poll设备方法负责完成:1、使用poll_wait将等待队列添加到poll_table中static inline void poll_wait(struct file * flip, wait_queue_head_t * wait_address, po
7、ll_table *p)2、返回描述设备是否可读或可写的掩码POLLIN POLLRDNORM POLLOUT POLLWRNORM设备可读数据可读设备可写 数据可写设备可读通常返回(POLLIN | POLLRDNORM)设备可写通常返回(POLLOUT | POLLWRNORM)do_select中,真正发生阻塞的不是在poll方法,决定是不是阻塞是由poll的返回掩码自动创立设备文件struct class *_class_create(struct module *owner, const char *name, struct lock_class_key *key)struct de
8、vice *device_create(struct class *class, struct device parent, dev_t devt, void *drvdata, const char *fmt, .) void device_destroy(struct class *class, dev_t devt)void class_destroy(struct class *cls)struct class *myclass = class_create(THIS_MODULEf “my_device_driver);device_create(myclass, NULL, MKD
9、EV(major_numt 0), NULL, umy_deviceH);当驱动被加载时,udev( mdev )就会自动在/dev下创立my_device设备文件device_destroy (myclass, IKDEV (mem_inajor, 0);删除设备 j点 class_destroy (myclass);注销类1、在/sys/class 下创立 farsight_class 类my_class =class_create(THIS_MODULE, nfarsight_classH);2、在farsight_class中创立新的class设备class_device_create
10、(my_class,NULL, devno, NULL,nfarsight_devn);然后会在/sys中出现如图的文件结构:rootfarsight:/home/l ht/drvtest/udev# 1 s /sys/cl ass/farsiht.cl ass/farsiht.dev/ devuevent其中,dev”和uevent都是“属性”,可以读取dev获取设备的主次设备号;也可以对uevent操作;让内核发出“add” 事件用于热插拔。如:rootfarsight:/sys/cl ass/farsight_cl ass/farsight_dev# cat dev 252:0异步通知概
11、念:一旦设备就绪,那么主动通知应用程序(类似硬件上的“中断”)为了使用户空间处理设备释放的信号,必须完成3项工作1、通过F_SETOWNIO控制命令设置设备文件的拥有者为本进程,这样设备驱动发来的信号才能被本进程接 收2、通过F_SETFLIO控制命令设置设备文件支持FASYNC,即异步通知模式3、通过signal。函数连接信号和处理函数void read_handler(int signum)(printf(ndevice can be read nownn);signal(SIGIO, read_handler);fcntl(fd, F_SETOWN, getpid();flags = f
12、cntl(fd, F_GETFL);fcntl(fd, F_SETFL, flags | FASYNC);while(l);为了使设备支持异步通知机制,驱动程序中涉及3项工作1、支持F_SETOWN命令设置驱动flle-f_owner为对应进程ID,内核已经帮助完成2、支持F_SETFL命令的处理,每当FASYNC标志改变时。驱动程序中的fasync。函数将得以执行。我们需 要实现的是fasync()函数3、在设备资源可获得时,调用kilLfasync。函数激发相应信号if (dev-fasync)/*启动异步读信号*/kilLfasync(&dev-fasync, SIG1O, POLLJN
13、);/*异步通知*/static int mem_fasync (int fd, struct file int on)printk(nstart in fasyncnn);return fasync_helper(fd, filp, on, &dev-fasync);处理 FASYNC 标志变更)/*文件释放函数*/int mem_release(struct inode *inode, struct file *filp)(mem_fasync(-l, filp, 0);/*将文件从异步通知列表中删除*/return 0;)中断处理程序共享中断:就是将不同的设备挂接到同一个中断信号线,Li
14、nux对共享中断的支持主要是为PCI设备服务。中断处理程序(ISR)分解为:顶半部与底半部:顶半部:在中断运行期间,不能执行有可能睡眠的操作,不能同用户交换数据,不能调用schedule函数放弃调度底半部:tasklet运行于中断上下文工作队列运行于进程上下文(只有它能实现上面不能的操作)软中断中断号的查找:arch/arm/mach-s5pc 1 OO/include/mach/irqs.harch/arm/plat-s5p/include/plat/irqs.h开发板上:/proc/interruptsint request_irq(unsigned int irq, irq_handle
15、r_t handler, unsigned long flags, const char *devname, void *dev_id)返回值。展示成功,或者返回一个错误后参数分析:a)/*unsigned int irq 注册中断号b)irq_handler_t handler 中断处理函数consigned long flags(IRQF_DISABLED如果设置该位,为快速中断,反之慢速中断,IRQF_SHARED该位说明中断可以在设备间共享)【快速中断不允许中断嵌套,慢速中断那么可以】d)const char *devname 设备名e)void *dev_id共享中断时使用*/为设备
16、实现一个中断分两步1、向内核注册中断2、实现中断处理函数static struct work_struct key 1 wk;/*定义一个工作队列*/1、申请IRQ/*注册中断号 中断处理函数下降沿触发设备名 共享中断时使用*/ret = request_irq(IRQ_EINT( 1), keyl_handler, IRQF_TRIGGER_FALLING, memjiq11, NULL);if (ret) printk(nmem_irq: request irq failurenn);for (i = 0; i timer);/*初始化定时器*/3、赋值其成员dev-timer.funct
17、ion = mem_do_timer;dev-timer.data =(unsigned long)dev;dev-timer.expires = jiffies + 1*HZ; add_timer(&dev-timer); 增加定时器static void mem_do_timer (unsigned long arg) dev = (mem_dev *)arg;printk(nthe count is %dnM,dev-count);dev-count+4-;mod_timer(&dev-timer, jiffies + 1*HZ); )4、del_timer(&dev-timer);删除
18、定时器MMAP起的地域起的地域高地址len堆初始化被根正文拿川始化敷* mrrp_buf = (char *)_get_free_page(GFP_KERNEL);if (mmap_buf = NULL) cdev_del(&dev-cdev);ret = -ENOMEM;goto out;memset(mmap_buf, 0, PAGE_SIZE);2、int mem_mmap(struct file * flip, struct vm_area_struct * vma)if (remap_pfn_range(vma, vma-vm_start, virt_to_phys(mmap_buf
19、) PAGE_SHIFT, vma-vm_end - vma-vm_start, vma-vm_page_prot)return -E AG AIN;return 0;struct vm_area_struct * vma 虚拟内存区域:一个进程的内存区域可以通过查看/proc/pi d/maps每一行的域为:start_end perm offset majonminor inodeStart:该区域起始虚拟地址 data= mmap_buf;用户层:内存映射函数mmap:负责把文件内容映射到进程的虚拟内存空间,通过对这段内存的读取和修改,来实现对 文件的读取和修改。而不需要再调用read、
20、write1、void *mmap(void *addr, size_t length, int prot, int flags, int fd, offt offset);参数分析:a) addr:指定文件应被映射到用户空间的起始地址。一般制定为NULLb) length:映射到调用用户空间的字节数,它从被映射文件开头offset个字节开始算起prot:指定访问权限。可取如下值相“或:PROT_READ(可读)、PROT_WRITE(可写)、PROT_EXEC(可执行)、 PROJNONE(不可访问)c) flags: MAP.SHARED写入映射区的数据会复制回文件,且允许其他映射该文件的
21、进程共享MAP_PRIVATE对映射区的写入操作回产生一个映射区的复制(copy_on_write),对此区域所作的修改不会写 回原文件d) fd:由。pen返回的文件描述符,代表要映射的文件e) offset:偏移量2、int munmap(void *addr, size_t length);a) addr:映射起始地址b) length:映射长度硬件访问:寄存器和RAM的主要不同在于寄存器操作有副作用(side effect)【读取某个地址时,可能导致该地址内容发生 变化。比方:中断寄存器,只要一读,便会自动清零】X86处理器存在10空间的概念:32位X86, 10空间大小是64k,内存
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux驱动程序 嵌入式 Linux 驱动程序
限制150内