驱动复习(mor8)

来源:互联网 发布:阿里云简称 编辑:程序博客网 时间:2024/05/16 09:51

1、读函数分析:
read函数是从内核空间读出数据到用户空间,在读出数据之前我们要检查它传进来的参数的合法性。先从file结构体中提取私有数据(Men_dev*=file->private_data);再提取读的起始位置(loff_t pos=*fps);然后判断这两者的合法性:如果读的起始位置pos比内核空间的已经存在的数据还要大(即pos>dev->size),那么这是不合法的。同样如果内核空间的数据为空(即dev=NULL) ,则没有数据可以读,这也是不合法的。
如果在长度合法并且内核空间有数据可以读的情况下,我们就可以利用copy_to_user()这个函数将内核空间的数据送个用户空间了。注意读完之后这个偏移量是需要加count(表示下一次读的起始位置),然后返回读的字节数count;

int memdev_read(struct file*filp,char*buf,size_t count,loff_t*fpo){    Mem_dev* dev =filp->private_data;    loff_t pos   =*fpo;    size_t = ret;    if(pos > dev->size)        goto ↓out;    if(pos+count > dev->size)        count = dev->size - pos;    if(dev->data)        goto ↓out;    if(copy_to_user(buf,&(dev-data[pos]),count))    {        ret = -EFAULT;        goto ↓out;    }    *fpo +=count;    ret   =count;    out:        return  ret;}

2、在Linux源码的顶层Makefile中其实不含有vmlinux的信息,vmlinux是在/arch/arm中的Makefile中定义的。
3、驱动调试技术:
a、打印调试:
printk打印调试一般定义一个宏开关来控制调试的需求。

#define DEBUG_SWITCH        1#ifdef    DEBUG_SWITCH#define pr_debug(fmt,args...) printf(fmt, ##args)#else#define pr_debug(fmt,args...) /*do nothing */#endif

b、调试器调试
c、查询调试
2、I/O与内存空间:
X86处理器存在I/O空间它是相对内存空间而言的32位的X86体系结构I/O空间和内存空间单独编址的,I/O空间的大小为64k。在arm中的内存分配表中有一部分是特殊功能寄存器,所以在arm中I/O空间和内存空间是统一编址的,它只支持内存空间。
3、I/O端口:
当一个寄存器或内存位于I/O空间时称其为I/O端口。
I/O内存:
当一个寄存器或内存位于内存空间是称其为内存端口。
4、I/O端口的操作:申请、访问、释放;
a、申请I/O端口:内核提供了函数来申请I/O端口
struct resource*request region(unsigned long f,unsigned long n,const char*name);
在内核申请从f开始的n歌端口,name为设备的名字成功为非NULL,失败为NULL。
b、释放I/O端口:
void release_region (unsigned long start , unsigned long n);
一般在驱动卸载时释放I/O端口。
5、I/O内存的操作:申请、映射、访问、释放
申请:struct resource* request_mem_region(unsigned long star,unsigned long len,char*nem);
申请从start开始的长度为len的内存区,成功为非NULL。已经使用的I/O内存在/proc/iomem中列出。
映射:void*iormap(unsigned long phys_addr,unsigned size);
这个函数完成物理地址到虚拟地址的映射。
访问:使用内核的函数来访问。
释放:void iounmap(void* addr);
void release_mem_regione(unsigned long start,unsigned long len);
6、在Linux中实现中断步骤:注册中断、实现中断历程。
中断注册:

int request_irq(unsigned int irq,void(*handler)(int,void*,pt_regs*),unsigned long flags,const char*devname,void* dev_id);//const char* devname用于在/proc/interrups中显示//void* dev_id用于共享中断,一般慢速的小的中断可以共享//flags表示与中断管理相关的选项:    SA_INTERRUPT:该为置位表示快速中断,否则表示慢速中断    SA_SHIRQ:表示可以在设备间共享。 

释放中断:

void free_irq(unsigned int irq , void* dev_id);

注:中断历程调用和普通函数的调用的区别:
中断历程函数如果是共享中断的话不能禁中断,而且中断历程中不能使用信号量,因为它可能引起阻塞,任何有可能阻塞的函数都不应该出现在中断历程中。中断历程函数不可以向用户空间发送或接收数据,因为中断历程不属于任何进程的上下文。
7、NAND flash和NOR flash的区别:NAND flash的存储单元是串联的,NOR flash的存储单元是并联的。
先从Flash说起吧,目前Flash主要有两种NOR Flash和NADN Flash,这两种Flash相对于SDRAM的区别就是断电之后,Flash可以保存数据,而SDRAM就不可以保存数据。
NOR Flash的访问跟访问内存一样,速度很快,cpu指令可以直接在里面运行,一般我们可以用1~2M的Norflash来放我们的运行程序。它的数据线和地址线是分开的,可以很方便的读取数据。
NAND Flash没有采取内存的随机读取技术,它的读取是以一次读取一块的形式来进行的,通常是一次读取512个字节,采用这种技术的Flash比较廉价。但由于用户不能直接运行NAND Flash上的代码,因此好多使用NAND Flash的开发板除了使用NAND Flah以外,还作上了一块小的NOR Flash来运行启动代码。一般开发板中会配备64M来存储内容。由此看来,Nandflash适合大容量的数据存储,类似硬盘。NAND Flash上数据线和地址线是共用的,NOR flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。

  SDRAM由于其速度很快,主要用于程序执行时的程序存储、执行或计算,类似内存。

0 0