zoukankan      html  css  js  c++  java
  • 19、硬件访问技术

    硬件访问技术

     

    我们前面点亮led就是使用动态的虚拟地址:

    看了动态映射,接下来就是静态映射:

    该结构有四个成员:第一个参数是我们的虚拟地址,第二个参数才是我们实际的物理地址,只不过我们现在使用页桢号来表示。假如物理地址是50008000,一页的大小为4K,用物理地址除以4K,就得到页桢号了。它现在是一个宏,是通过下面两步实现的:

    我们知道一个页的大小了4K,除以4K就是物理地址右移12位。如上代码。除以2就是向右移动一位。第三是映射区域的长度,第四是区域的类型。

    注意:当你有n个地址空间需要映射,就得创建n个上面的结构。

    接下来就是看系统是如何完成这种映射关系的。

    搜索:s3c_iodesc

    我们搜索的结果如上,可以看出这是个数组,这个数组的元素是结构struct map_desc。前面知道一个这样的结果对应的是内存的一片映射区域。

    我们来看GPIO的一片区域:

    S3c6410芯片手册:

    我们查看芯片手册知道,0x7f008000是GPIO这片区域的起始物理地址。

    然后这片区域会被映射到下面的虚拟地址:

    S3C64XX_VA_GPIO:

    接着找后面的S3C_ADDR_CPU:

    接着找后面的S3C_ADDR:

    接着找S3C_ADDR_BASE和一个偏移量x

    找到的是上面的S3C_ADDR_BASE 0XF4000000加上偏移量x,就是S3C_ADDR的地址。

    有了这样的地址,当我们的内核要去使用这表的的时候:

    我们知道,当我们的6410启动的时候,会去找这样的一张表来完成映射。

    这就是内核启动的时候完成的静态映射。

    接下来,我们使用静态映射来改写我们的led程序。

    我们来搜索S3C64XX_GPKCON.

    上面拿到的就是我们的虚拟地址。

    S3C64XX_GPK_BASE:

    我们可以看到,我们又回到了前面静态映射的物理地址:

    所以S3C64XX_GPKCON的地址就是我们的虚拟地址,我们可以直接使用。

    修改前面的led.c部分为:

    Make编译后:

    把生成的led.ko拷贝到开发板运行:

    Cat /proc/devices查看主设备号:

    创建设备文件:

    运行了led_app 1程序后,看到开发板的led全亮。

    运行了led_app 0程序后,led全灭。

    这就是我们使用静态寄存器的过程。但是一般不用静态映射。

    上面是寄存器提供的读写函数。

    上面只是顺利的操作,其实在运行程序的时候,有一个问题:

    这是访问地址越界的样子。等待搞懂......

  • 相关阅读:
    button 垂直分布
    GitHub上值得关注的iOS开源项目
    电脑连接网络(网络正常),但不能上网,登录网页提示dns_probe_finished_no_internet
    android 模拟应用因内存不足被后台杀死命令
    android 屏幕划分
    android 没有root的手机导出数据库
    移动硬盘不能识别,设备管理器中显示黄色感叹号
    低功耗蓝牙开发(BLE)
    音视频学习笔记
    Java中为什么要使用线程池?如何使用?
  • 原文地址:https://www.cnblogs.com/FORFISH/p/5188469.html
Copyright © 2011-2022 走看看