驱动复习(mor8)

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由于其速度很快,主要用于程序执行时的程序存储、执行或计算,类似内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值