This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我想在tms570ls3137芯片通过EMIF接口接片外PROM,如何将代码启动。程序在片外PROM中使用,不使用片内FLASH.谢谢
您好,
看到您在E2E上面也咨询了该问题。
我觉得KGreb的回答能够解决您的问题。
不知道您现在具体的问题是什么呢?
能否再描述得详细一点?是如何使用linker吗?
另外,Brian Fortman的建议也非常重要:
TMS570系列针对安全性能要求较高的系统设计的高可靠性微控制器,其内部flash和RAM都具有ECC功能。能够检测数据的错误,避免误操作的发生。但是您如果把代码放在外部存储器,那么相当于放弃了内部flash的ECC功能,可能会增加系统安全性风险。
所以也请您考虑是否真的需要使用外部存储器。
我是想知道,是不是我把初始化之类的程序在flash中运行,跑主程序时在跳转到片外去呢?我不知道如何跳转?使用linker是怎么操作?谢谢
还有就是ECC功能如何启动,flash是自主检测和修复的吗?谢谢
Zhangjie, 您好,
是的,您可以把初始化程序放在内部Flash中运行,主程序放在片外运行。
跳转的方式就是简单的函数调用即可。
关键是您对linker的操作,要把所有您需要放在外部存储器的内容(代码和数据)都映射到相应的位置。
这个具体方法您可以参考下面链接中的文档:
该文档中的举例如下:
如果您使用CCS作为编译环境,CMD文件如下:
/****************************************************************************/
/*** Specify the Memory Configurations ***/
/****************************************************************************/
MEMORY
{
FAST_MEM : org = 0x00000000 len = 0x00001000 /* PROGRAM MEMORY (ROM) */
SLOW_MEM : org = 0x00001000 len = 0x00001000 /* DATA MEMORY (RAM) */
PROM : org = 0x08000000 len = 0x00000400 /* COEFFICIENTS (PROM), 即您的外部存储器, 您需设置好相应的地址*/
}
/****************************************************************************/
SECTIONS
{
.text : {} > FAST_MEM /* Link all .text sections into ROM */
.intvecs : {} > 0x0 /* Link interrupt vectors at 0x0 */
.data : /* Link .data sections */
{
tables.obj(.data)
. = 0x400; /* Create hole at end of block */
} = 0xFF00FF00 > PROM /* Fill and link into PROM,这里只是把所谓的table.obj链接到外部存储器了,如果您需要把代码放在这边的话,也可以使用类似方法。*/
ctrl_vars: /* Create new sections for ctrl variables */
{
ctrl.obj(.bss)
} = 0x00000100 > SLOW_MEM /* Fill with 0x100 and link into RAM */
.bss : {} > SLOW_MEM /* Link remaining .bss sections into RAM */
}
/****************************************************************************/
/*** End of Command File ***/
/****************************************************************************/
关于ECC,是Error Correction Code的缩写。
TMS570LS3137支持单bit修正和双bit检测(SECDED)。
这个功能需要用户代码来使能,您可以查看TMS570LS3137数据手册中的4.10.3 ECC Protection for Flash Accesses一节。
数据手册:www.ti.com/.../tms570ls3137.pdf
另外,您也可以使用HALCoGen驱动代码生成工具。
下载地址: www.ti.com/.../halcogen
Zhangjie, 您好,
是的,您可以把初始化程序放在内部Flash中运行,主程序放在片外运行。
跳转的方式就是简单的函数调用即可。
关键是您对linker的操作,要把所有您需要放在外部存储器的内容(代码和数据)都映射到相应的位置。
这个具体方法您可以参考下面链接中的文档:
该文档中的举例如下:
如果您使用CCS作为编译环境,CMD文件如下:
/****************************************************************************/
/*** Specify the Memory Configurations ***/
/****************************************************************************/
MEMORY
{
FAST_MEM : org = 0x00000000 len = 0x00001000 /* PROGRAM MEMORY (ROM) */
SLOW_MEM : org = 0x00001000 len = 0x00001000 /* DATA MEMORY (RAM) */
PROM : org = 0x08000000 len = 0x00000400 /* COEFFICIENTS (PROM), 即您的外部存储器, 您需设置好相应的地址*/
}
/****************************************************************************/
SECTIONS
{
.text : {} > FAST_MEM /* Link all .text sections into ROM */
.intvecs : {} > 0x0 /* Link interrupt vectors at 0x0 */
.data : /* Link .data sections */
{
tables.obj(.data)
. = 0x400; /* Create hole at end of block */
} = 0xFF00FF00 > PROM /* Fill and link into PROM,这里只是把所谓的table.obj链接到外部存储器了,如果您需要把代码放在这边的话,也可以使用类似方法。*/
ctrl_vars: /* Create new sections for ctrl variables */
{
ctrl.obj(.bss)
} = 0x00000100 > SLOW_MEM /* Fill with 0x100 and link into RAM */
.bss : {} > SLOW_MEM /* Link remaining .bss sections into RAM */
}
/****************************************************************************/
/*** End of Command File ***/
/****************************************************************************/
关于ECC,是Error Correction Code的缩写。
TMS570LS3137支持单bit修正和双bit检测(SECDED)。
这个功能需要用户代码来使能,您可以查看TMS570LS3137数据手册中的4.10.3 ECC Protection for Flash Accesses一节。
数据手册:www.ti.com/.../tms570ls3137.pdf
另外,您也可以使用HALCoGen驱动代码生成工具。
下载地址: www.ti.com/.../halcogen
我使用的是KEIL编译环境,使用halcogen代码生成工具,导入到keil4中的。其中CMD文件
为
/*----------------------------------------------------------------------------*/
/* sys_link.cmd */
/* */
/* (c) Texas Instruments 2009-2010, All rights reserved. */
/* */
FLASH 0x00000000 0x00200000
{
VECTORS 0x00000000 0x00000020
{
*.o (intvecs, +First)
}
FLASH0 0x00000020 0x0017FFE0
{
*.o (reset, +First)
*(InRoot$$Sections)
.ANY3 (+RO)
}
FLASH1 0x00180000 0x00180000
{
.ANY2 (+RO)
}
ARM_LIB_STACK 0x08000000 EMPTY 0x00001500
{
}
RAM 0x08001500 0x00026B00
{
.ANY (+RW +ZI)
}
}
/*----------------------------------------------------------------------------*/
如果我想讲main函数开始的程序放置入片外程序存储器(地址为0x60000000),我如何更
改CMD文件。谢谢!还有就是ECC功能是只要启动就可以了吗?
Zhangjie, 您好,
抱歉,KEIL不是很熟悉。下面是使用CCS的操作方法,不过各家编译环境大同小异。
(这是个比较简单的办法,如果您需要高级操作,可以查看KEIL的编译器/连接器文档。)
1. 定义外部存储单元。
/*----------------------------------------------------------------------------*/
/* Memory Map */
MEMORY
{
VECTORS (X) : origin=0x00000000 length=0x00000020
FLASH0 (RX) : origin=0x00000020 length=0x0007FFE0
FLASH1 (RX) : origin=0x00080000 length=0x00080000
FLASH2 (RX) : origin=0x00100000 length=0x00080000
FLASH3 (RX) : origin=0x00180000 length=0x00080000
EXTFLASH (RX) : origin=0x60000000 length=0x00080000
STACKS (RW) : origin=0x08000000 length=0x00001500
RAM (RW) : origin=0x08001500 length=0x00026B00
}
2. 定义代码段".application"在外部存储器中。代码段的名字您可以自己定义
SECTIONS
{
.intvecs : {} > VECTORS
.text : {} > FLASH0 | FLASH1 | FLASH2 | FLASH3
.application : {} > EXTFLASH
.const : {} > FLASH0 | FLASH1 | FLASH2 | FLASH3
.cinit : {} > FLASH0 | FLASH1 | FLASH2 | FLASH3
.pinit : {} > FLASH0 | FLASH1 | FLASH2 | FLASH3
.bss : {} > RAM
.data : {} > RAM
}
3. 在源文件中定义需要放在.application section中的函数,比如需要把main()放在这个section中的话:
#pragma CODE_SECTION(main, ".application")
void main(void)
{
/* USER CODE BEGIN (3) */
while(1);
/* USER CODE END */
}
预编译语句#pragma CODE_SECTION是编译器相关的,也就是说在KEIL中的写法和用法可能稍有不同,但是大同小异。
一般都是放在函数定义的前面的。也有直接将整个.obj指定在某个section的操作办法,具体请参考您使用的环境的手册。
关于ECC,我们在TMS570LS3137中提供的是SECDED机制,也就是说,出现单bit错误时,ECC会直接将错误更正,并记录总的更正次数。
您可以设置一个阈值,超过一定次数,ECC就会产生中断来通知系统。当双bit或更多错误发生时,ECC的编码机制无法自动完成修复,但ECC可以探知问题存在并发出中断来通知系统。
所以具体如何使用这些安全功能跟您的系统设计息息相关,硬件本身只能提供最基础的帮助。
我使用类似方法在KEIL环境下试了一下,我将前20个字节和emif的初始化放置于FLASH中,其余程序放在片外rom中,我使用的ROM是at28bv256,程序可以跳转了,跳到0x60000000地址运行后,程序最终停止在 0x00000004 未定义的入口处,也就是说程序运行不正常,不知道对于芯片内部寄存器及堆栈的初始化可否放置于片外运行?谢谢!
Hi Zhangjie,
不是很清楚您说前20个字节的含义...
不过正常情况下,MCU上电后应该进行一些必要的初始化程序。这个过程一般叫做Boot Strap.
以我们的HALCoGen生成的代码为例的话,Boot Strap主要完成了下面的工作:
1. 初始化堆栈指针
2. 初始化内部Flash, 时钟树,清除RAM
3. 为有初值的全局变量赋值,或有需要在RAM上运行的代码进行copy
4. 跳转至用户程序,一般是main();
不知道这些操作您的程序是否完成了?
在您的应用里,EMIF的初始化部分是一定要放在内部flash中完成的,这一点没错。
另外,您说可以跳转至0x60000000,不知道是用什么样的调试方式,是否可以单步跟踪一下?看看是什么地方使程序跳回0x00000004了?
现在将所有初化都放置于片内,仅将主程序放置于片外,发现如果主程序是仅作简单运算,可以执行,程序不会跑飞到0x00000004,但是如果主程序调用gioinit()初化函数,程序走到此函数就飞至0x00000004,不明原因请指教!谢谢!