CCS 为指针或变量分配固定地址
为什么要分配地址
在C语言中可以使用malloc
为指针申请内存,但DSP/单片机中却不能这么简单粗暴。倘若不申请内存,有时候又容易被优化掉。更有些场景为了提升代码效率,要把某些数据放在RAM中读写,而不是Flash。因此需要一种可以为指针或变量分配固定地址的方法。
在RAM或Flash中 为指针或变量分配固定地址
以DSP-TMS320F28335,在RAM中给指针分配地址为例
- F28335的存储器地址划分(TI官方):
- F28335片内Flash分段:
- 比如我们有这样一个结构体
typedef struct motor_{
float32 encoder_zero_position;
float32 electric_angle;
Uint16 TB_PRD;
float32 U_alpha_ref;
float32 U_beta_ref;
/* ...... */
/* 此处省略一些数据 */
float32 previous_sum_speed_error;
float32 speed_loop_KP;
float32 speed_loop_KI;
} State;
还有这样一个结构指针
State *motor1;
- 在"DSP2833x_Headers_nonBIOS.cmd"或"F28335.cmd"文件中,分配存储空间(若默认已分配 则无需修改):
MEMORY
{
PAGE 0: /* Program Memory */
/* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
ZONE0 : origin = 0x004000, length = 0x001000 /* XINTF zone 0 */
RAML0 : origin = 0x008000, length = 0x001000 /* on-chip RAM block L0 */
RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */
RAML2 : origin = 0x00A000, length = 0x001000 /* on-chip RAM block L2 */
RAML3 : origin = 0x00B000, length = 0x001000 /* on-chip RAM block L3 */
ZONE6 : origin = 0x0100000, length = 0x100000 /* XINTF zone 6 */
ZONE7A : origin = 0x0200000, length = 0x00FC00 /* XINTF zone 7 - program space */
FLASHH : origin = 0x300000, length = 0x008000 /* on-chip FLASH */
FLASHG : origin = 0x308000, length = 0x008000 /* on-chip FLASH */
FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */
FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */
FLASHD : origin = 0x320000, length = 0x008000 /* on-chip FLASH */
FLASHC : origin = 0x328000, length = 0x008000 /* on-chip FLASH */
FLASHA : origin = 0x330000, length = 0x00FF80
CSM_RSVD : origin = 0x33FF80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */
BEGIN : origin = 0x33FFF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */
OTP : origin = 0x380400, length = 0x000400 /* on-chip OTP */
ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC_cal function in Reserved memory */
IQTABLES : origin = 0x3FE000, length = 0x000b50 /* IQ Math Tables in Boot ROM */
IQTABLES2 : origin = 0x3FEB50, length = 0x00008c /* IQ Math Tables in Boot ROM */
FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0 /* FPU Tables in Boot ROM */
ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */
RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */
VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */
PAGE 1 : /* Data Memory */
/* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
/* Registers remain on PAGE1 */
BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */
RAMM0 : origin = 0x000050, length = 0x000080 /* on-chip RAM block M0 */
RAMM1 : origin = 0x0000D0, length = 0x000730 /* on-chip RAM block M1 */
RAML4 : origin = 0x00C000, length = 0x002500 /* on-chip RAM block L1 */
/* RAML5 : origin = 0x00D000, length = 0x001000 */ /* on-chip RAM block L1 */
RAML6 : origin = 0x00E600, length = 0x000300 /* on-chip RAM block L1 */
RAML7 : origin = 0x00F000, length = 0x001000 /* on-chip RAM block L1 */
ZONE7B : origin = 0x20FC00, length = 0x000400 /* XINTF zone 7 - data space */
FLASHB : origin = 0x330000, length = 0x008000 /* on-chip FLASH */
}
- 在CCS的Memory Allocation窗口看一下未使用的存储空间(比如
RAML2
)
- 然后在
SECTIONS
中指定RAML2
用来存放State
结构
SECTIONS
{
/* ***************略************* */
/* 原来SECTIONS中的东西不要动 */
/*只添加这一行即可*/
State : > RAML2 PAGE = 0
/* ***************略************* */
}
- 在主函数之前,使用编译预处理指令,指定指针
motor1
的存放地址
#pragma DATA_SECTION (motor1, "State");
- 最后编译下就行了,可以在Memory Allocation看到RAML2分配了空间
State
给结构指针motor1
RAM不够用的话,可以在Flash中分配空间
同样的方法,比如放在FLASHC
中
SECTIONS
{
/* ***************略************* */
/*只改动这一行即可*/
State : > FLASHC PAGE = 0
/* ***************略************* */
}
F28335的Flash大的很,尽管用,可以多用一些牺牲空间换时间的操作~