当前位置: 首页 > news >正文

【研发日记】嵌入式处理器技能解锁(四)——TI C2000 DSP的Memory

文章目录

前言

背景介绍

Memory映射

RAM

ROM

外设Register

Memory分配

应用实例

总结

参考资料


前言

        见《【研发日记】嵌入式处理器技能解锁(一)——多任务异步执行调度的三种方法》

        见《【研发日记】嵌入式处理器技能解锁(二)——TI C2000 DSP的SCI(串口)通信》

        见《【研发日记】嵌入式处理器技能解锁(三)——TI C2000 DSP的C28x内核》

背景介绍

        本文要讲的Memory是TI C2000 DSP的片上存储器。其在芯片的整体架构中,所处的位置如下:

        Tips:除了上图中的ROM和RAM,另外的外设寄存器从广义的角度讲也是Memory的一部分。

Memory映射

        存储器映射表,描述了存储器中各个组成部分的地址,用于读写寻址,如下图所示:

RAM

        TI C2000 DSP的RAM由三个部分组成:Mx RAM、LSx RAM和GSx RAM。

        M0 RAM和M1 RAM,总计4KB,是两个具有专用功能的RAM模块,与CPU紧密耦合,只有CPU可以访问,软件开发人员一般不用关注。

        LS0-7 RAM,总计32KB,是本地共享RAM(Local shared RAM),CPU、CLA和BGCRC可访问,可以用作软件的堆栈等通用功能,需要软件开发人员关注。

        GS0-3 RAM,总计32KB,是全局共享RAM(Global shared RAM),除了CPU、CLA和BGCRC可访问,另外HIC和DMA也都具有对这些存储器的完全读写访问权限,比LSx RAM具有更广泛的用途,可供软件开发人员更灵活地使用。

        Tips:另外的几种消息RAM是特定模块的专用RAM,在对应功能启用时用于共享数据。

ROM

        TI C2000 DSP的ROM也是由三个部分组成:Boot Rom、Secure Rom和Flash Bankx。

        Boot Rom,总计64KB,里边中存放着芯片厂家制定的一些代码,芯片每次复位后都要先执行这里的代码,然后才开始执行软件开发人员编译的代码。Boot ROM中代码的功能是芯片层面的初始化(不是main函数中的初始化),去执行一些类似于clear RAM这样的任务,软件开发人员只需要知道这部分的存在即可,一般不需要特别关注。

        Secure Rom,总计48KB,是一些具有更高权限的存储区域,CPU和外设通过常规的方式无法对其读写,需要使用特殊的API和Password才能访问。Secure ROM中是芯片厂家为用户提供的特定功能(function),如果没有启用这些功能,一般也不需要关注。

        Flash Bank 0-2,总计3*128KB。其中每个组(Bank)又由16个扇区(Selector)组成,总计16*8KB。每个扇区(Selector)又由64个页(Page)组成,总计64*128Byte。是通用型存储空间,可以存放软件开发人员的Code和Bytes。在程序运行时,CPU可以直接在上面寻址并抓取指令和Bytes。

        Tips:另外还有一种OTP(one-time programmable) ROM,它只能写入一次,不能擦除。一般用于存放芯片ID或者ECU ID,以及一些Configure和其他出厂信息。

外设Register

        外设(Peripheral)寄存器是DSP各个外设子系统(例如ADC)的存储单元,其特点时固定地址存储固定数据。DSP的外设子系统非常多,功能各不相同。每个外设也都有很多寄存器,主要用于Configure外设的模式和反馈外设的Status/Result。外设ADC(Analog to Digital Converter)的部分寄存器,示例如下:

        Tips:外设寄存器的用法与各个外设的功能高度相关,后面用到哪个外设时再针对性研究。

Memory分配

        软件开发人员在使用TI C2000 DSP芯片时,Memory主要被分配成如下几个部分:

        Stack(栈):包含临时创建的局部变量、函数调用入口的参数、函数返回值、const修饰的局部常量。

        Heap(堆):用于存放程序运行中被软件开发人员动态分布的内存段,可增可减,一般用malloc等函数实现动态分布内存。用malloc函数分布的内存,必须用free进行内存释放,否则会造成Memory溢出。

        Global/Static:这两种变量都具有穿越代码运行周期的能力(只是作用范围不同),所以需要在Memory中分配固定的地址

        Zi-data:表示未初始化赋值(Zero initialized)的全局变量和Static修饰的变量,它是直接在RAM中分配一个固定地址

        Code(Instruction):字面指软件开发人员写的代码,但是在Memory中已经是编译后的东西,它被划分为指令和数据两部分,上图中的Code准确讲应该叫指令(Instruction)。

        Ro-data:字面指只能读取的数据,即程序中定义的常量,例如#define 宏定义、用const修饰过变量等。这些常量是一直在ROM中的,芯片运行起来后CPU直接从ROM中读取。

        Rw-data:字面指可读可写的数据,它实际上包括了堆、栈和全局变量等。这些数据又分为已被初始化赋值的和未被初始化赋值的。但是在Memory分配图中为了便于描述,把Rw-data理解为已被初始化的即可。ROM中的Rw-data从烧录文件中而来,在Memory中是固定地址和固定Value的。芯片启动时会被移到RAM中使用,芯片运行起来之后Rw-data就是动态变化的了,堆栈的地址和Value都会实时变化,Global/Static只有Value会变化

应用实例

        这里展示一个示例Demo代码,直接用代码中的注释进行说明。

Demo.c File
#include <xxxx.h>
uint16 Val1 = 1;	//Val1是Global变量,并且已经初始化了,在RAM的Rw-data区域有一个固定地址。但是为了芯片下电时不丢失,所以在ROM的Rw-data区域中也有一个地址来存放。Val1在ROM中的Value一直都是1,但是在RAM中的Value会随着代码的运行而变化。
static uint16 Val2 = 2;	// Val2也是已初始化的Static变量,跟Val1的Memory分配是一样的Rw-data区域。这里的static修饰代表它的作用范围有限。
uint16 Val3;	//Val3也是Global变量,但是未初始化,所以分配在RAM中Zi-data区域的一个固定地址。
const uint16 Val4 = 4;	//Val4被const修饰了,是一个常量,分配在ROM的Ro-data区域。uint16 DemoFcn(uint16 Num)	//Num是函数入口的参数,分配在Stack区域
{uint16 Var5 = 5;	//Var5是局部变量,只在DemoFcn()函数调用时临时使用,所以分配在RAM Stack区域的一个随机地址,DemoFcn()函数退出时就会把这个Memory释放掉。因为Var5有一个初始值,所以在ROM栈区也会分配一个空间。static uint16 Var6 = 6;	// Var6被static修饰,代表它的Value要穿越芯片运行周期,即下一次读取Var6时,它前一次写入的值仍能被读到,所以它被非标配在RAM中Rw-data区域的固定地址上。const uint16 Var7 = 7;  // Var7被const修饰,所以是常量,但是它只在DemoFcn()函数中短暂使用,所以是局部常量,被分配在RAM中Rw-data的Stack区域。void *p;p = malloc(8); //动态分配一个size 8的Memory,p是这片Memory区域的起始地址,它是分配在RAM Heap区域的一个随机地址。*p = 1;	//使用这片区域*(p+1) = 2;	//使用这片区域free(p); 	//释放这片区域return (Num+*p);	//函数的返回值存放在RAM Stack区域
}void main()
{uint16 Var8 = 0;	//Var8是局部变量,分配在RAM Stack区域的一个随机地址。Var8 = DemoFcn (9);	//存放在RAM Stack区域的函数返回值,赋给Var8。
}

        Tips:除了上述的Data,还有内部的赋值、加法等运算,会被编译常指令(Instruction),然后分配在ROM的Code区域

总结

        以上就是本人在研发中使用嵌入式处理器Memory时,一些个人理解和分析的总结,主要介绍了TI C2000 DSP Memory的工作原理,展示了具体的使用方法,并对比分析了它的特点和适用场景。

        后续还会分享另外几个最近解锁的嵌入式处理器新技能,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成文本人持续分享的动力。

        另外,上述例程使用的Demo工程,可以到笔者的主页查找和下载。

参考资料

        TMS320F28003x Real-Time Microcontrollers datasheet.pdf


        版权声明,原创文章,转载和引用请注明出处和链接,侵权必究!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++编程:无锁环形队列 (LockFreeRingQueue)的简单实现、测试和分析
  • ELK整合实战,filebeat和logstash采集SpringBoot项目日志发送至ES
  • Yii2框架的初始化及执行流程
  • 索引是什么
  • springboot生成、响应图片验证码
  • 如果忘记了 Apple ID 密码,如何重设
  • SpinalHDL之spinal.core 组件(上篇)
  • 【软件测试】功能测试理论基础
  • httplib库:用C++11搭建轻量级HTTP服务器
  • PHP获取和操作配置文件php.ini的几个函数介绍
  • 【源码+文档+调试讲解】多媒体信息共享平台
  • 大型、复杂、逼真的安全服和安全帽检测:SFCHD数据集和SCALE方法
  • 内存泄漏之VLD可以检测哪些类型的内存泄漏?
  • 【人工智能】助力音乐产业
  • Android之内容提供者(ContentProvider)
  • SegmentFault for Android 3.0 发布
  • #Java异常处理
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • es的写入过程
  • Gradle 5.0 正式版发布
  • LeetCode18.四数之和 JavaScript
  • mockjs让前端开发独立于后端
  • nodejs:开发并发布一个nodejs包
  • React-flux杂记
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • 大型网站性能监测、分析与优化常见问题QA
  • 工作手记之html2canvas使用概述
  • 关于 Cirru Editor 存储格式
  • 诡异!React stopPropagation失灵
  • 使用common-codec进行md5加密
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 微服务核心架构梳理
  • 在Unity中实现一个简单的消息管理器
  • 终端用户监控:真实用户监控还是模拟监控?
  • Nginx实现动静分离
  • #define、const、typedef的差别
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (152)时序收敛--->(02)时序收敛二
  • (void) (_x == _y)的作用
  • (附源码)php投票系统 毕业设计 121500
  • (算法)求1到1亿间的质数或素数
  • (转)JAVA中的堆栈
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET 服务 ServiceController
  • .net6+aspose.words导出word并转pdf
  • .NET和.COM和.CN域名区别
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • /bin/rm: 参数列表过长"的解决办法
  • @Documented注解的作用