Question:
I'm using the 21489 to run some complex algorithm, it should define many big arrays.when I was running the project, I get the error code like this:
error: attempt to write to ROM ... with PC at 0x1271f1
address supplied is invalid with PC at 0x12cd1c
apparently there is not enough SRAM to run the project. unfortunately, for cost saving, I cannot use SDRAM to store the big array.
I have four questions:
1. I want to define variable on the specified sections, such as "mem_block3_dm32" or "mem_sdram_swco", what should I do?
(suppose I use 21489 + CCES2.1, and the IDE using the default setting)
2. How to allocate variable on the external memory?
3. Can I modified the LDF to resize the data memory space as I want? How to do it?
4. sometimes l find variable will modified by unkown reason, what should I do to protect these global variable? using "static"?
======================
Answer:
1. I want to define variable on the specified sections, such as "mem_block3_dm32" or "mem_sdram_swco", what should I do?
ANS>>
#pragma section is used to declare a variable name in specified section
Refer in CCES help for more information
CrossCore Embedded Studio 2.x.x > Blackfin Development Tools Documentation > C/C++ Compiler and Library Manual for Blackfin Processors > Compiler > C/C++ Compiler Language Extensions > Pragmas > Linking Control Pragmas> #pragma section/#pragma default_section
2. How to allocate variable on the external memory?
ANS>>
To place global variables in external memory, use the section pragmas. The Default LDF has sections and commands defined to allow the placement of data in external memory. For example, the MEMORY{...} block in the LDF contains the section:
seg_ext_dmda { TYPE(DM RAM) START(0x00900000) END(0x01DFFFFD) WIDTH(16) }
Later, in the SECTIONS{...} block, there is the following 'output section' command:
seg_sdram_data
{
INPUT_SECTIONS( $OBJECTS(seg_dmda) $LIBRARIES(seg_dmda))
INPUT_SECTIONS( $OBJECTS(seg_ext_data) $LIBRARIES(seg_ext_data))
INPUT_SECTIONS( $OBJECTS(seg_sdram) $LIBRARIES(seg_sdram))
} > seg_ext_dmda
To place a global variable in this location, and ensure it doesn't get placed in internal memory, just use either of the two 'input section' names listed here that are not "seg_dmda". So, either of these would work:
#pragma input_section("seg_ext_data")
int GlobalVariable1
#pragma input_section("seg_sdram")
int GlobalVariable2
Similarly, to make sure a function is placed in SDRAM, there is a "seg_ext_code" section defined in the MEMORY{...} block, with a matching set of INPUT_SECTIONS commands, and a 'section' pragma can be used to force the function in here.
To allocate local data from SDRAM, we would need to move the stack/heap to SDRAM by editing the LDF. It is possible to work with multiple heaps (see the section "C/C++ Compiler Manual for SHARC(r) Processors > 1 Compiler > C/C++ Run-Time Model and Environment > Using Multiple Heaps"), however there can only be one stack.
3. Can I modified the LDF to resize the data memory space as I want? How to do it?
ANS>>
To modify the LDF, refer the below linked Ezone FAQ might helps:
FAQ: How do you modify a generated LDF during project creation in CCES?
How do you modify a generated LDF during project creation in CCES? Audit
Also ,refer the below given CCES help path:
CrossCore Embedded Studio > System Run-Time Documentation>Startup Code
CrossCore Embedded Studio > Integrated Development Environment > System Configuration > Startup Code/LDF Add-in > Startup Code/LDF Configuration for SHARC Projects > Startup Code/LDF Tab for SHARC Processors>LDF Configuration Page
4. sometimes l find variable will modified by unkown reason, what should I do to protect these global variable? using "static"?
ANS>>
If you are reporting that the global variables in an application (using default ldf) get reset to "zero" (statically) explicitly. Please note that this is a feature of the C programming languages - static storage duration objects that are not explicitly initialized are implicitly initialized to zero. When an application is downloaded using VisualDSP++ or CCES initializations are done by the emulation support. When not connecting using VisualDSP++ or CCES, initializations are done by the boot kernel.
You can avoid specific global or static variable being initialized using #pragma section with the NO_INIT section qualifier to place the data in a non-default input section. That would also require an LDF addition to map the new section containing the NO_INIT variables to memory appropriately.
For example in C source you would have:
#pragma section("no_init_data", NO_INIT)
char noInitBuffer[N];
And in the LDF would include the input as follows in the SECTION() area:
seg_dmda_noinit NO_INIT
{
INPUT_SECTIONS( $OBJECTS(no_init_data) $LIBRARIES(no_init_data))
} > seg_dmda
Obviously, you would have to ensure that variables defined in this way are initialized appropriately before being read.
Documentation for #pragma section is available in the VisualDSP++ help system and will be fouind by searching for "#pragma section/#pragma default_section".