驱动学习之静态映射和动态映射

简介:

1:静态映射方法的特点:

  内核移植时以代码的形式硬编码,如果要更改必须改源代码后重新编译内核在内核启动时建立静态映射表,到内核关机时销毁,中间一直有效对于移植好的内核,你用不用他都在那里


2:动态映射方法的特点:

  驱动程序根据需要随时动态的建立映射、使用、销毁映射映射是短期临时的


3:如何选择虚拟地址映射方法

  (1)2种映射并不排他,可以同时使用

  (2)静态映射类似于C语言中全局变量,动态方式类似于C语言中malloc堆内存

  (3)静态映射的好处是执行效率高,坏处是始终占用虚拟地址空间;动态映射的 好处是按需使用虚拟地址空间,坏处是每次使用前后都需要代码去建立映射&销毁映射(还得学会使用那些内核函数的使用)


4:三星版本内核(内核版本2.6.35.7)中的静态映射表

  不同版本的内核,其静态映射表的文件名以及文件路径不一定相同,但是一般都在arch/arm/xxx/map_xx.h文件中

  (1)主映射表位于:arch/arm/plat-s5p/include/plat/map-s5p.h

CPU在安排寄存器地址时不是随意乱序分布的,而是按照模块去区分的。每一个模块内部的很多个寄存器的地址是连续的。所以内核在定义寄存器地址时都是先找到基地址,然后再用基地址+偏移量来寻找具体的一个寄存器。这个文件夹下面的虚拟地址基地址是不全的,原因是三星在移植的时候只是移植了自己需要的部分,将来我们需要添加其他基地址的时候直接添加就行了。

map-s5p.h中定义的就是要用到的几个模块的寄存器基地址(虚拟地址)。

  (2)虚拟地址基地址定义在:arch/arm/plat-samsung/include/plat/map-base.h

#define S3C_ADDR_BASE (0xFD000000) // 三星移植时确定的静态映射表的基地址,表中的所有虚拟地址都是以这个地址+偏移量来指定的

  (3)GPIO相关的主映射表位于:arch/arm/machs5pv210/include/mach/regs-gpio.h

表中是GPIO的各个端口的基地址的定义

  (4)GPIO的具体寄存器定义位于:arch/arm/mach-s5pv210/include/mach/gpio-bank.h


5:实驱动LED灯

  通过驱动代码去操作LED灯和裸机操作LED灯的方法是一样的,都是操作相应的寄存器地址,不同之处在于驱动代码操作的是虚拟地址,而裸机操作的LED灯对应的物理地址。一个物理地址可以对应多个虚拟地址,原因在于虚拟地址最终指向的也是物理地址,(相当于一个房间(物理地址)有多个入口(虚拟地址)一样)但是一个虚拟地址只能对应一个物理地址。

虚拟地址寄存器(查看mach/gpio-bank.h

1
2
3
4
5
6
7
#define GPJ0CONS5PV210_GPJ0CON    //0xFD050240
#define GPJ0DATS5PV210_GPJ0DAT    //0xFD050244
#define rGPJ0CON*((volatile unsigned int *)GPJ0CON)
#define rGPJ0DAT*((volatile unsigned int *)GPJ0DAT)
rGPJ0CON = 0x11111111;      //设置寄存器的相应位
rGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));   // 亮
rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));   // 灭


6:动态映射操作LED

6.1:如何建立动态映射

  (1)request_mem_region:向内核申请(报告)需要映射的内存资源。

request_mem_region(GPJ0CON_PA, 8, "GPJ0CON"))

参数说明:

  GPJ0CON_PA:需要进行虚拟映射的物理地址

  8:映射的长度为8字节

  "GPJ0CON":描述这个动态映射的名字


  (2)ioremap:真正用来实现映射,传给他物理地址他返回给你一个虚拟地址

pGPJ0CON = ioremap(GPJ0CON_PA, 8);

参数:

  GPJ0CON_PA:需要进行虚拟映射的物理地址

  8:映射的长度为8字节

  返回值:成功返回一个虚拟地址(或者是一段虚拟地址的首地址,具体取决于我们需要映射的字节长度),失败返回0


6.2:如何销毁动态映射

  (1)iounmap:解除映射

  (2)release_mem_region:释放映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
     //使用动态映射来操作LED
     //发出虚拟地址申请请求
if  (!request_mem_region(GPJ0CON_PA, 8,  "GPJ0CON" ))
return  -EINVAL;
   //申请虚拟地址
pGPJ0CON = ioremap(GPJ0CON_PA, 8);
       //if (!request_mem_region(GPJ0DAT_PA, 4, "GPJ0DAT"))
      //return -EINVAL;
     //申请虚拟地址
    //pGPJ0DAT = ioremap(GPJ0DAT_PA, 4);
    //使用申请得到的虚拟地址
*pGPJ0CON = 0x11111111;
*(pGPJ0CON+1) = ((0<<3) | (0<<4) | (0<<5));
     //pGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));
*(pGPJ0CON+1) = ((1<<3) | (1<<4) | (1<<5));
     //释放申请的虚拟地址
     //解除映射
iounmap(pGPJ0CON);
     //iounmap(pGPJ0DAT);
     //释放申请的虚拟地址
    //release_mem_region(GPJ0CON_PA, 8);
release_mem_region(GPJ0DAT_PA, 4);

注:因为这里GPJ0CON(0xe0200240) 和GPJ0DAT(0xe0200244)是两个连续的物理地址,所以我们可以只映射0xe0200240这个物理地址,映射的字节数为8,那么(GPJ0CON+1)就是我们GPJ0DAT对应的虚拟地址。



本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1876410



相关文章
|
4月前
|
存储 数据库 索引
面试题ES问题之动态映射的定义如何解决
面试题ES问题之动态映射的定义如何解决
38 1
|
搜索推荐 Java 程序员
对象映射你用哪个
对象映射你用哪个
96 0
|
XML 存储 Java
Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【三】——基本映射——一对一映射
82 0
配置静态和动态
介绍: 静态nat 和 动态nat 的配置 静态nat 配置步骤 第一步 配置接口地址 第二步 配置静态地址转换 ip nat inside source static 内部私有地址 转换之后的公网地址 动态nat 配置步骤 第一步 配置接口地址 第二步 配置标准acl 指定需要转换的多个内部主机地址 access-list 编号 permit 网段地址 子网掩码反码 第三步 配置 转换后的公网地址地址池 ip nat pool 地址池名字 起始地址 结束地址 子网掩码 第四步 配置动态地址
173 0
直接取配置文件对应数据映射到对象中,可在代码中直接使用
直接取配置文件对应数据映射到对象中,可在代码中直接使用
|
机器学习/深度学习 算法 定位技术
一句话总结等距映射(流形学习)
一句话总结等距映射(流形学习)
一句话总结等距映射(流形学习)
|
前端开发 JavaScript Java
WebJars 映射
WebJars 映射
195 0
|
JSON JavaScript Java
动态与静态 | 学习笔记
快速学习动态与静态。
119 0
|
JSON 数据格式 索引
ES7学习笔记(五)动态映射
通常情况下,我们使用ES建立索引的步骤是,先创建索引,然后定义索引中的字段以及映射的类型,然后再向索引中导入数据。而动态映射是ES中一个非常重要的概念,你可以直接向文档中导入一条数据,与此同时,索引、字段、字段类型都会自动创建,无需你做其他的操作。
1884 0
|
数据库
【自然框架 NatureFW】里的两种“映射”方式
   自然框架里面采用了两种映射关系,一个是流行的ORM,另一是非主流的“CCM ” (我自己想的,呵呵)。   先说一下ORM。ORM是O和R的映射关系。也看到很多人写关于ORM的文章,发现好像有个误区。
948 0