文章目录

  • 前言
  • 1. 微型计算机
    • 1.1 微型计算机的结构
    • 1.2 由结构引发的思考
  • 2. F28335的存储空间
    • 2.1 存储器映射
    • 2.2 寄存器映射
  • 总结

前言

学习F28335的存储空间时对存储器、寄存器以及它们相应的映射等问题较为模糊,在阅读大量的资料以及仔细地思考后将该部分问题总结如下,以供大家参考。如有错误,也希望大家积极指正。


1. 微型计算机

F28335是一种单片机,而单片机本质上就是微型计算机。微型计算机的结构包括微处理器CPU(包括运算器ALU、控制器CU、寄存器)、存储器(RAM、ROM)、I/O接口以及总线。也就是说我们见到的51芯片、32芯片以及F28335芯片其本质都是微型计算机,图1给出了三种常用的微型计算机。

图1 三种微型计算机

1.1 微型计算机的结构

相信学过《微机原理》的人都很熟悉图2,这是一张典型的8088微型计算机的内部结构图。该结构主要有三大部分:

  1. 内核CPU是8088,其内部集成了ALU、CU以及各种寄存器。详细的内部的结构图如图3所示;
  2. 存储器相对于CPU独立,包括了RAM和ROM;
  3. I/O是微型计算机与外部交流窗口,它不仅包括I/O口,还包括了一些片上外设。
    图2 微型计算机的结构

图3 8088CPU内部结构

图3中的AX、BX、CX、DX、CS等都是寄存器,而CPU与存储器之间的数据交换是通过总线的方式,例如:当CPU需要从存储器提取数据时,CPU首先会将存储器的地址放入相应的地址寄存器中,然后通过地址总线发出该地址找到相应的存储空间,存储空间将数据放在数据总线上,CPU从数据总线读取数据并放入相应的数据寄存器中。对于外设同理。(关于这一部分使用哪些寄存器以及CPU的取指计算过程,大家可以查阅《微机原理》)

1.2 由结构引发的思考

通过上面的内容我们可以知道:F28335芯片是一种微型计算机,它的内部集成了CPU、存储器、I/O等,CPU与存储器、I/O等外设之间相对独立。F28335的CPU内部含有寄存器,寄存器与存储器本质上都是实际存在的具有存储功能的物理空间,但是一个在CPU内部,一个在CPU外部。
实际上,在F28335的存储器中有一部分存储空间也为寄存器,既然寄存器和存储器两者都是具有存储功能的物理空间,那为什么叫法不同呢?我的想法是:寄存器本质上就是存储器,之所以将部分存储空间叫寄存器是因为其指示的物理存储空间使用非常频繁,人为操作的次数多,所以需要用寄存器的方式(给空间命名的方式)使得操作更加方便,减少编程的错误。这在之后作详细说明

2. F28335的存储空间

F28335芯片内部的存储器包括了256K×16位的FLASH(ROM),34K×16位的SARAM,8K×16 位的 BOOT ROM以及2K×16 位的 OPT ROM,采用统一寻址方式(程序、数据和 I/O 统一寻址),从而提高了存储空间的利用率。

存储器的这些存储空间都是实际存在的物理空间,为了统一管理以及便于访问这些空间,需要给这些空间分配地址,同样,为了统一访问片上的I/O和外设,都需要分配相应的地址。这就好似快递员将快递送到你家一样,你家就是存储空间,快递员是CPU,快递是数据,如果快递员不知道你家地址,那么快递就无法到家,因此有必要填写家庭地址。

2.1 存储器映射

为存储器的存储空间分配地址的行为就是存储器映射。查阅F28335的数据手册,可得F28335的存储器映射地址如图4所示。

图4 F28335存储器及外设映射情况 作如下几点说明:

  1. 空间大小的计算:比如M1的地址范围为0x800-0x400,则0x800-0x400=0x400=1024(dec)=1k,也就是说有1k的存储空间,而每个存储空间的大小为16位(这一点大家在之后编程的时候会发现,F28335操作的每一个寄存器大多数都是16位的),因此为1k×16。可能有人说该空间的大小为2k,这也是正确的,这是因为原则上认为1位就是1bit,而8位构成1字节(byte),1024个字节构成1kb,因此1k×16的大小为1k×2×8=2k×8;
  2. FLASH的地址为0x30 0000-0x34 0000;BOOT ROM的地址为0x3F E000-0x3F FFC0;OPT ROM的地址为0x38 0000-0x38 0800;SARAM的地址就是0x00 0000-0x00 0800的M0、M1以及L0-L7;
  3. 外设帧 0/1/2/3,这 4 个空间也是存储空间同样分配了地址,但是它们只能是数据空间。设帧 1/2/3 空间是 Protected,表示这三个空间存放的寄存器不可以随便配置,若要对存放在 Protected 空间内的寄存器进行配置,要进行 EALLOW 声明,以 EDIS 结束声明,起到保护和警示作用。

2.2 寄存器映射

F28335片上集成了I/O以及多个外设,如SPI、SCI、EPWM、ECAP等,而操作F28335片上外设的本质就是在外设帧中相应存储空间写入或者读出数据,由于这一部分存储空间需要经常使用,人为操作频繁,因此正常编程时,需要频繁使用到这些存储空间的地址,而地址记忆时较为繁琐,因此可以为这些存储空间取人脑较为容易记忆的名字,取得名字我们称为Xx寄存器,而取名字的过程称为寄存器映射。这样,在编程时我们就可以在CCS中写这些寄存器的名字来替代原先的地址,也就能直接改变存储空间中的值,从而达到控制片上外设的作用。

从寄存器以及寄存器的映射概念可以看到,寄存器本质上就是存储器的中一些常用的存储空间。前面我说过,在CPU中也有一些寄存器(参照图3),它们本质上也是存储空间,而在编写汇编语言时我们要经常用到CPU中的这些存储空间,因此为了书写的方便,我们也用同样的方法为这些存储空间编写名字,也就有了AX、BX、CX、DX、SI等。

下面我将以片上外设GPIO为例,说明在CCS中它是如何将GPIO下存储空间的地址进行映射的。
先看下面这一条语句,这是一条非常简单的将GPIO68设置为高电平的语句。从该语句的结构上看,GpioDataRegs事实上是一个结构体,同时它也是映射后的寄存器。

GpioDataRegs.GPCSET.bit.GPIO68=1;

查看GpioDataRegs的说明,如下:

#ifdef __cplusplus
#pragma DATA_SECTION("GpioDataRegsFile")
#else
#pragma DATA_SECTION(GpioDataRegs,"GpioDataRegsFile");
#endif
volatile struct GPIO_DATA_REGS GpioDataRegs;

可以看到,GpioDataRegs是一个volatile struct GPIO_DATA_REGS类型的结构体。看到这里总结一下:从目前看到的情况来说,GpioDataRegs就是一个volatile struct GPIO_DATA_REGS类型的结构体变量,而我们前面说对GPIO的操作实际上是对GPIO存储空间地址下的存储器进行数据写入或读出,我们既需要将GpioDataRegs当作一个寄存器,也需要对存储空间地址操作,显然根据寄存器映射的概念,我们需要将GpioDataRegs与存储空间地址结合在一起,也就是给存储空间地址取名为GpioDataRegs,这就是“#pragma DATA_SECTION(GpioDataRegs,“GpioDataRegsFile”);”语句的作用。

打开“DSP2833x_Headers_nonBIOS.cmd”文件,找到GpioDataRegsFile存在的语句如下:

   GpioDataRegsFile  : > GPIODAT      PAGE = 1

可以看到,GpioDataRegsFile指向了GPIODAT,那么在该文件中找到GPIODAT存在的语句如下:

GPIODAT     : origin = 0x006FC0, length = 0x000020     /* GPIO data registers */

可以看到,最终寄存器GpioDataRegs指向的地址为0x006FC0,长度为0x20,也就是32×16位。

下面说明寄存器GpioDataRegs为什么指向的地址为0x006FC0,其长度又为什么是32×16位。首先从寄存器的名字可以看到,这是GPIO数据寄存器,查阅F28335的数据手册中GPIO数据寄存器地址映射情况如图5所示。

图5 GPIO数据寄存器地址映射

可以看到,寄存器GpioDataRegs实际上是一个大类寄存器,其下包括了GPADAT-GPCTOGGLE等多个寄存器,而GPADAT寄存器的起始地址为0x6FC0,因此GpioDataRegs的起始地址也应该为0x006FC0。

回到“volatile struct GPIO_DATA_REGS GpioDataRegs;”语句中,点击GPIO_DATA_REGS可以看到该结构体的定义为:

struct GPIO_DATA_REGS {union  GPADAT_REG       GPADAT;       // GPIO Data Register (GPIO0 to 31)union  GPADAT_REG       GPASET;       // GPIO Data Set Register (GPIO0 to 31)union  GPADAT_REG       GPACLEAR;     // GPIO Data Clear Register (GPIO0 to 31)union  GPADAT_REG       GPATOGGLE;    // GPIO Data Toggle Register (GPIO0 to 31) union  GPBDAT_REG       GPBDAT;       // GPIO Data Register (GPIO32 to 63)union  GPBDAT_REG       GPBSET;       // GPIO Data Set Register (GPIO32 to 63)union  GPBDAT_REG       GPBCLEAR;     // GPIO Data Clear Register (GPIO32 to 63)union  GPBDAT_REG       GPBTOGGLE;    // GPIO Data Toggle Register (GPIO32 to 63)union  GPCDAT_REG       GPCDAT;       // GPIO Data Register (GPIO64 to 95)union  GPCDAT_REG       GPCSET;       // GPIO Data Set Register (GPIO64 to 95)union  GPCDAT_REG       GPCCLEAR;     // GPIO Data Clear Register (GPIO64 to 95)union  GPCDAT_REG       GPCTOGGLE;    // GPIO Data Toggle Register (GPIO64 to 95)Uint16                  rsvd1[8];
};

可以看到,结构体中定义了多个共用体变量,而这些变量恰好就是GpioDataRegs下各寄存器的名字。从图5的Size一栏以及上面的代码可以看到,GpioDataRegs一共包括了12个寄存器,这12个寄存器的大小均为2×16位,另外还包括了8×16位的保留空间,合起来就是32×16位的空间大小,解释了长度为什么是长度为0x20。


总结

  1. F28335的内核CPU与存储器是相互独立的;
  2. 寄存器与存储器本质是都是具体存在物理存储空间;
  3. 给存储器的存储空间分配地址的过程称为存储器映射;
  4. 一些存储空间需要经常操作,而直接操作地址的出错率较大,因此可以将存储空间的地址取人类容易记忆的名字,该过程称为寄存器映射,取得名字(指向存储空间的地址)称为寄存器。

对TMS320F28335存储空间的理解相关推荐

  1. Redis集群搭建很easy

    前言 哨兵模式虽然让读写分离更加高可用,但单台服务器由于本身的内存和CPU瓶颈,对于高并发和大数据业务的应用场景还是远远不能满足:对于这种情况,有点经验的小伙伴会毫不犹豫的想到集群,搞他好几个节点,负 ...

  2. 初见 IsolatedStorage

    IsolatedStorage 翻译过来是(隔离存储空间) 怎么理解呢,jake lin的故事讲得很好,可以拿过来借用一下 " 朝鲜人民精神文明都非常的发达, 因此上网时都不需要访问inte ...

  3. 数据结构与算法分析 收获总结 第11章 图

    1.图(Graph)结构是一种非线性的数据结构,可以用G=(V,E)表示,每个图中都包含一个顶点集合V和一个边集合E,其中E中的每条边都是V中的某一对顶点之间的连接,顶点总数记为|V|,边的总数记为| ...

  4. 【Linux系统编程】进程地址空间和虚拟地址空间

    00. 目录 文章目录 00. 目录 01. 早期的内存分配机制 02. 分段 03. 分页 04. 地址比较 05. 附录 01. 早期的内存分配机制 在早期的计算机中,要运行一个程序,会把这些程序 ...

  5. python语言基本排序算法_排序算法(Python)

    参考: <数据结构(Python 语言描述)> - 3.4 基本排序算法.3.5 更快的排序 Tips:为了保持简洁,每个函数都只处理整数列表,并且假设列表不为空. 目录.jpg 术语 1 ...

  6. C:内存中供用户使用的存储空间

    内存中供用户使用的存储空间可分为: 代码区:存代码的地方. 常量区:存常量的地方. 静态存储区:存变量的地方. 动态存储区:存变量的地方. 存变量的分为静态存储和动态存储两个区: "静态&q ...

  7. python yield理解_对Python中Yield的理解

    看到下面这段程序的时候,有点不明白这个yield到底是个啥东西,看了网上很多的博客,大致理解了yield的含义,所以记录下来. 要说yield首先要说python中的生成器,那么什么是生成器? 假设有 ...

  8. Linux 虚拟内存和物理内存的理解【转】

    转自:http://www.cnblogs.com/dyllove98/archive/2013/06/12/3132940.html 首先,让我们看下虚拟内存: 第一层理解 1.         每 ...

  9. JavaMail学习笔记(一)、理解邮件传输协议(SMTP、POP3、IMAP、MIME)

    电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行传递,就必须遵循一定的规则,这些规则就是邮件传输协议.SMTP协议定了邮件客户端与SMTP服务之间,以及两台SMTP服务器之间发送邮 ...

  10. [译]深入理解JVM

    深入理解JVM 原文链接:http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals 每个使用Java的开发者都知道Java ...

最新文章

  1. 【PHPWord】创建带样式表格的Word文档
  2. 聊聊高并发系统之队列术
  3. c99变长数组_你学过数组,那你知道柔性数组吗?
  4. silverlight 实时更新 marquee效果
  5. 媒体转码切片_移动、咪咕携手华为实现5G网络切片应用大型直播
  6. Versant 对象型数据库
  7. html浏览器边框颜色,CSS设置字体和边框颜色时Chrome和其他主流浏览器差别的问题_html/css_WEB-ITnose...
  8. web developer tips (55):多项目解决方案中设置启动项
  9. 基于Wi-Fi的HID注射器,利用WHID攻击实验
  10. php搞笑图片合成,PS教你怎么把照片做成搞笑的qq表情
  11. 如何处理图片放大后变模糊的情况?
  12. Tableau可视化---Tableau简介
  13. 艾司博讯:拼多多重复开店注意的事项
  14. Linux下stream内存带宽测试参数和示例详解附源码(总结)
  15. 初识RxJava(三)转换类 操作符
  16. SeaMonkey推荐
  17. 你真的了解Filter过滤器 ?
  18. 省常中模拟 Test3 Day1
  19. 图像增强的几个方法以及Matlab代码
  20. Photoshop脚本 查看当前图层的锁定状态

热门文章

  1. FOXIT PDF EDITOR工具分割PDF
  2. java jdom 创建xml_java中使用jdom生成xml
  3. PS如何进行自定义画笔
  4. 苹果手机密码设置在哪里_oppo怎么设置SIM密码-oppo手机SIM卡密码设置详细教程
  5. 一张图理清SpringMVC工作原理
  6. xUtils更新到3.0后的基本使用规则
  7. Java类加载机制与反射 jvm学习
  8. DICOM医学图像简介
  9. Matlab中获取文件夹下所有子文件夹名称操作
  10. html编写在线打字通,HTML5代码打字练习、HTML5案例 - 02