I have a bootloader that loads code into RAM at runtime. I have the ramcode linking and executing as I would expect but I still need to manually clear the .bss section.
Here is my linker script
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x20007000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x20000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x20007000;
define symbol __ICFEDIT_region_RAM_start__ = 0x1FFF0000;
define symbol __ICFEDIT_region_RAM_end__ = 0x20000000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_heap__ = 0x1000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_region_ROM_start__ { readonly section .init };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
And here is my startup code
extern int main(void);
extern int __vector_table[];
#pragma location=".init"
__interwork int __low_level_init(void)
{
char * from = __section_begin(".bss");
char * to = __section_end(".bss");
memset(to, from , 0x00);
memcpy(__vector_table, (unsigned char *)ROM_VECTOR_LOCATION, VECTOR_TABLE_SIZE);
SCB_VTOR = (unsigned int) & __vector_table;
main();
SCB_VTOR = (uint32_t)ROM_VECTOR_LOCATION;
}
but the .bss section doesn't really seem to exist in the context I'm trying to use it. I get the following error.
Error[Pa053]: section/block has not been declared using #pragma section/segment
How do I "define" the .bss section so that the start/end address is available to me in my C code.
Ryan
Try
#pragma segment=".bss"
and
unsigned char *start_of_bss =__sfb(".bss");
unsigned char *end_of_bss =__sfe(".bss");
Regards
Mark
P.S. I use __iar_program_start() as entry point in all cases since it then initialises .bss. It doesn't harm other things because it will see that initialised variables are at the same location as this values and so just jumps these parts. It then calls (your) main() when finished.
P.P.S. Your code is possibly only missing the
#pragma segment=".bss"
part (sfb() is just the assembler version of __section_begin)
Mark,
I'm having a hard time understanding your P.S. comment but I think its something I need to do. I have a global variable initialized to 1 but I see it takes on all kinds of values. I believe this is because the .data section is not being copied to RAM.
What must I do to make __iar_program_start() as the entry point? I want that code to live at 0x20000000 but that's the reset handler if I leave things as the default.
I really appreciate all your help. No one in my company has done this before so you and Google have been my only friends.
Ryan
Whether you need to initialise statics depends on how they are located - if you use the initilisation values directly as variables there is no need to copy them and less RAM is needed. However, this is not that practical for RAM debugging since the code needs to be reloaded each time it is reset so that the initial values are returned again - for your application it may however be efficient.
The linker script that I showed is suitable for RAM debugging and I don't actually know whether IAR allows the other technique (at least I don't remember trying to do it with IAR). In any case, I use __iar_program_start() to allow it to initialise all that it needs to.
In case you continue having difficulties contact me at "mark (at) utasker.com" and we can do a remote desktop session so I can see what your present code is doing and show you what may need to be modified. I work as a consultant and trainer to many companies developing Kinetis based parts but offer a free 45 minute session to new customers. This should be adequate to solve your issue so it won't cost anything.
Regards
Mark
Well something is missing because variables initialized to non-zero values
take on random values rather than the values I initialized them as.
I still don't understand how I force __iar_program_start() to be the entry
point without using the reset vector. Ive already disabled the watchdog in
the bootloader so I don't want to let the reset handler do it again in the
ramcode.
On Mon, Jan 22, 2018 at 8:27 PM, mjbcswitzerland <admin@community.nxp.com>
Mark,
You're my hero.
On Mon, Jan 22, 2018 at 12:37 PM, mjbcswitzerland <admin@community.nxp.com>