MC9S12XE 内存分配

发布者:黄金大花猫最新更新时间:2021-07-15 来源: eefocus关键字:MC9S12XE  内存分配  映射关系 手机看文章 扫描二维码
随时随地手机看文章

1.逻辑地址和全局地址的映射关系

9S12XE系列的逻辑地址与全局地址映射关系如下图所示:

在这里插入图片描述

其中对应关系如下:


逻辑地址0x0000-0x07FF的2K MCU内部及其外设控制寄存器空间对应全局地址的0x0000-0x07FF;

逻辑地址0x0800-0x0BFF的1K EEPROM空间通过EPAGE映射非固定页EEPROM到全局地址0x10_0000-0x13_FBFF,逻辑地址0x0C00-0x0FFF的1K固定页EEPROM映射到全局地址0x13_FC00-0x13_FFFF(CPU直接访问逻辑地址0x0C00-0x0FFF相当于访问全局地址0x13_FC00-0x13_FFFF,不过逻辑地址在CPU的直接寻址范围内,直接访问0x0C00-0x0FFF速度更快,单片机访问全局地址0x13_FC00-0x13_FFFF也是范围逻辑地址为0x0C00-0x0FFF的固定页EEPROM,下面RAM和FLASH的寻址方式与EEPROM相同);

逻辑地址0x1000-0x1FFF 4K RAM空间通过RPAGE映射非固定页RAM到全局地址RAM_LOW-0x0F_DFFF,逻辑地址0x2000-0x3FFF的8K 固定页RAM映射到全局地址0x0F_DFFF-0x0F_FFFF(CPU 直接访问0x2000-0x3FFF相当于访问0x0F_DFFF-0x0F_FFFF,速度更快);

逻辑地址0x4000-0x7FFF 16K固定页FLASH映射到全局地址0x7F_4000-0x7F_7FFF,逻辑地址0xC000-0xFFFF 16K固定页FLASH映射到全局地址0x7F_C000-0x7F_FFFF(CPU直接访问0x4000-0x7FFF和0xC000-0xFFF相当于访问0x7F_4000-0x7F_7FFF和0x7F_C000-0x7F_FFFF,速度更快,反过来也是一样),逻辑地址0x8000-0xBFFF的16K FLASH空间通过PPAGE映射非固定页FLASH到全局地址FLASH_LOW-0x7F_3FFF和0x7F_8000-0x7F_BFFF。

2.内存的分页及页内逻辑地址与全局地址的关系

由于9S12内CPU 16位地址总线只能访问64K的内存空间,对于大于64K内存空间,单片机引入页地址将超出能直接访问的资源进行分页,然后通过页地址进行访问。其中RAM引入RPAGE,EEPROM引入EPAGE,FLASH引入PPAGE。下一节RAM、EEPROM和FLASH的页地址与页内逻辑地址并不从0开始,是因为要将页地址和页内逻辑地址进行组合形成全局地址,对应相应内存类型所在的全局地址范围,具体的对应的关系如下:


RPAGE

在这里插入图片描述

EPAGE

在这里插入图片描述

PPAGE

在这里插入图片描述

3.prm文件与内存映射的关系

XEP100的prm文件总共可分为6部分,我们主要用到4部分:

1)SEGMENTS…END

SEGMENTS…END中间是所使用的单片机内部资源的定义,包括了内部资源名和地址,其中内部资源明可由用户自己定义,也可以自行定义自己用的的内部资源的名字和地址范围。


EEPROM = READ_ONLY DATA_NEAR IBCC_NEAR 0x0C00 TO 0x0FFF;定义了固定页EEPROM的地址;

RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;定义了固定页RAM的地址;

ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x7FFF; ROM_C000 = READ_ONLY DATA_NEAR IBCC_NEAR 0xC000 TO 0xFEFF;定义了两块固定页ROM的地址,也就是两块16 K固定页Flash的地址,因为访问16K 固定页Flash的逻辑地址相当于访问Flash 的全局地址中的Flash FD,FF页,所以在prm文件中直接定义其的逻辑地址用,不再定义其的页地址和页内逻辑地址组合,下面的分页EEPRM和分页RAM定义情况与Flash相同;

EEPROM_00 = READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF;...定义了非固定页EEPROM的地址,其中地址的前2位表示页数,后4位表示该页内的逻辑地址,二者结合可以组合成全局地址。EEPROM的页数范围为0-FE,页内的逻辑地址范围为0x0800-0x0BFF,其他地址为非法;

RAM_F0 = READ_WRITE DATA_FAR 0xF01000 TO 0xF01FFF;定义了非固定页RAM地址组合,其中地址的前2位表示页数,后4位表示该页内的逻辑地址,二者结合可以组合成全局地址,EEPROM的页数范围为F0-FD,页内的逻辑地址范围为0x1000-0x1FFF,其他地址为非法。FE和FF页对应固定页RAM,前面已经定义,这里不再重复定义;

PAGE_C0 = READ_ONLY DATA_FAR IBCC_FAR 0xC08000 TO 0xC0BFFF;定义了非固定页FLASH地址组合,其中地址的前2位表示页数,后4位表示该页内的逻辑地址,二者结合可以组合成全局地址,FLASH的页数范围为C0-FC和FE,页内的逻辑地址范围为0x8000-0xBFFF,其他地址为非法。FD和FF页对应固定页FLASH,前面已经定义,这里不再重复定义;

上面6种资源类型可以不全部定义,只定义自己程序中需要的内存资源,例如程序中只需要固定页的RAM和ROM那么就可以自己定义如下的SEGMENTS…END部分:


SEGMENTS

      MY_RAM           = READ_WRITE  DATA_NEAR            0x2000 TO   0x3FFF; 

      MY_ROM_4000      = READ_ONLY   DATA_NEAR IBCC_NEAR  0x4000 TO   0x4FFF;

END


2)PLACEMENT…END

PLACEMENT…END内主要功能是将对应类型的代码放到SEGMENT…END中定义的内存资源内,其中DISTRIBUTE_INTO和INTO功能相似,都是将对应类型的代码放置到指定资源,但使用优化器时,需要使用DISTRIBUTE_INTO,否则会导致优化失败,具体功能如下:

<1>将程序中的预启动和启动函数、常量、字符串、虚拟表、固定页代码、需要拷贝到RAM的数据放置到ROM_C000,也就是放置到地址为0xC000-0xFEFF的固定页FLASH内,代码如下:


    _PRESTART,              /* Used in HIWARE format: jump to _Startup at the code start */

      STARTUP,                /* startup data structures */

      ROM_VAR,                /* constant variables */

      STRINGS,                /* string literals */

      VIRTUAL_TABLE_SEGMENT,  /* C++ virtual table segment */

    //.ostext,                /* eventually OSEK code  */

      NON_BANKED,             /* runtime routines which must not be banked */

      COPY                    /* copy down information: how to initialize variables */

                              /* in case you want to use ROM_4000 here as well, make sure

                                 that all files (incl. library files) are compiled with the

                                 option: -OnB=b */

                        INTO  ROM_C000/*, ROM_4000*/;


<2>将放置到默认Flash内的代码和数据放置到分页FALSH内,代码如下:


 DEFAULT_ROM       INTO                PAGE_FE,          PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8, 

                              PAGE_F7, PAGE_F6, PAGE_F5, PAGE_F4, PAGE_F3, PAGE_F2, PAGE_F1, PAGE_F0, 

                              PAGE_EF, PAGE_EE, PAGE_ED, PAGE_EC, PAGE_EB, PAGE_EA, PAGE_E9, PAGE_E8, 

                              PAGE_E7, PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0, 

                              PAGE_DF, PAGE_DE, PAGE_DD, PAGE_DC, PAGE_DB, PAGE_DA, PAGE_D9, PAGE_D8, 

                              PAGE_D7, PAGE_D6, PAGE_D5, PAGE_D4, PAGE_D3, PAGE_D2, PAGE_D1, PAGE_D0, 

                              PAGE_CF, PAGE_CE, PAGE_CD, PAGE_CC, PAGE_CB, PAGE_CA, PAGE_C9, PAGE_C8, 

                              PAGE_C7, PAGE_C6, PAGE_C5, PAGE_C4, PAGE_C3, PAGE_C2, PAGE_C1, PAGE_C0;


<3>将堆栈和放置到默认RAM的数据放置到固定页RAM,代码如下:


 //.stackstart,            /* eventually used for OSEK kernel awareness: Main-Stack Start */

      SSTACK,                 /* allocate stack first to avoid overwriting variables on overflow */

    //.stackend,              /* eventually used for OSEK kernel awareness: Main-Stack End */

      DEFAULT_RAM             /* all variables, the default RAM location */

                        INTO  RAM;


<4>将放置到非固定页RAM的数据放置到分页RAM,代码如下:


PAGED_RAM         INTO  /* when using banked addressing for variable data, make sure to specify

                                 the option -D__FAR_DATA on the compiler command line */

                              RAM_F0, RAM_F1, RAM_F2, RAM_F3, RAM_F4, RAM_F5, RAM_F6, RAM_F7, 

                              RAM_F8, RAM_F9, RAM_FA, RAM_FB, RAM_FC, RAM_FD;


若在SEGMENTS…END中自行定义了自己所使用的资源名称和地址范围,则可将对应类别的代码放入自己定义的内部资源内。若SEGMENTS内自行定义的ROM如MY_ROM_4000 = READ_ONLY DATA_NEAR IBCC_NEAR 0x4000 TO 0x4FFF;,自行定义的RAM如MY_RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;那么可将代码放入MY_ROM_4000,数据放入MY_RAM内,代码为:


PLACEMENT

_PRESTART,             

      STARTUP,               

      ROM_VAR,                

      STRINGS,                

      VIRTUAL_TABLE_SEGMENT,       

      DEFAULT_ROM,NON_BANKED,          

      COPY                    INTO  MY_ROM_4000

      SSTACK,DEFAULT_RAM    INTO MY_RAM

END


3)设置堆栈大小

堆栈堆栈大小默认设置为0x100,可以根据最近单片机内存的大小自行定义大小。


STACKSIZE 0x100


4)设置上电复位中断函数

9S12固定引脚复位、上电复位、低电压复位和非法地址复位为中断向量0、固定时钟监控复位为中断向量1、固定看门狗复位为中断向量2,且地址分别固定为0xFFFE、0xFFFC、0xFFFA。如下图所示:

在这里插入图片描述

在prm文件需要设置上电复位中断,代码如下,单片机上电后进入复位中断,运行启动代码。


VECTOR 0 _Startup

关键字:MC9S12XE  内存分配  映射关系 引用地址:MC9S12XE 内存分配

上一篇:CodeWarrior v5.x/MC9S12(X)怎么使用printf
下一篇:MC9S12XE 启动过程

推荐阅读最新更新时间:2024-11-10 15:32

STM32 内存分配详解
1、KEIL 编译后数据 code RO-data RW-data ZI-data flash 实际存储数据 2、内存段 bss 段、data段、text段、堆(heap)和栈(stack)。 2.1、bss 段 bss 段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域; bss 是英文Block Started by Symbol的简称; bss 段属于静态内存分配。 2.2、data 段 数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域; 数据段属于静态内存分配。 2.3、text 段 代码段(code seg
[单片机]
STM32 <font color='red'>内存</font><font color='red'>分配</font>详解
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved