Cannot figure out, why is my file (containing only DataFlash0 byte defines) linked into the output hex twice. I am compiling for Infineon TC1797 with Tasking VX compiler.
Besides the program, I have a file named data_flash_bank_0.asm, which only includes predefined data bytes.
Compiler properly places it at the expected address of 0x8FE00000, which is the data flash 0 in hardware.
What is wrong is that the same code appears within the program as a second copy, wasting space and not wanted.
All the setting in the project properties seems fine, 'delete duplicate' enabled.
To illustrate the problem, I made one VERY SMALL project, where there are only 3 files: test.c function with main(), short assembly function reading the data flash, and the data flash predefines.
test.c:
#include <stdio.h>
extern void * loop_36(void); // call the main assembly function
int main(void)
{
loop_36();
}
assembly function jozo.asm:
.sdecl "PFLASH", CODE
.sect "PFLASH"
.global loop_36
loop_36:
movh.a a4, #0x8FE0
mov16 d2, #0 ; Move
lea a2, 0x3F ; Load Effective Address
loop:
ld16.w d15, [a4+]4 ; Load Word
or.ne d2, d15, #0 ; Not Equal Accumulating
loop16 a2, loop ; Loop
ret16 ; Return from Call
.end
and the actual predefined bytes area giving me the problem, file data_flash_bank_0.asm:
.sdecl ".data.dflash0", DATA AT 0x8FE00000
.sect ".data.dflash0" ; new edit: trying .rodata instead of .data
.byte 0xF2, 0x45, .... 32k more bytes
.end
Map file: (the last line is what I expect, but the 2 lines above it, also length 0x8000, I do not want)
+------------------------------------------------------------------------------------------------------------------------+
| Chip | Group | Section | Size (MAU) | Space addr | Chip addr | Alignment |
| ========================================================================================================================|
| spe:pflash0 | | .text._Exit.libc (191) | 0x00000004 | 0x80000008 | 0x00000008 | 0x00000008 |
| spe:pflash0 | | .text._c_init.libcs_fpu (98) | 0x0000000c | 0x8000000c | 0x0000000c | 0x00000002 |
| spe:pflash0 | | .text._c_init_entry.libcs_fpu (97) | 0x00000132 | 0x80000020 | 0x00000020 | 0x00000020 |
| spe:pflash0 | | table (202) | 0x00000030 | 0x80000154 | 0x00000154 | 0x00000004 |
| spe:pflash0 | | .text._ldmst_clear_byte.libcs_fpu (95) | 0x0000002e | 0x80000184 | 0x00000184 | 0x00000002 |
| spe:pflash0 | | .text._ldmst_copy_byte.libcs_fpu (96) | 0x00000044 | 0x800001b2 | 0x000001b2 | 0x00000002 |
| spe:pflash0 | | .text.cstart..cocofun_1 (14) | 0x0000001a | 0x800001f6 | 0x000001f6 | 0x00000002 |
| spe:pflash0 | | .text.cstart.__init_sp (12) | 0x0000001c | 0x80000210 | 0x00000210 | 0x00000002 |
| spe:pflash0 | | .text.cstart._start (13) | 0x000001c2 | 0x8000022c | 0x0000022c | 0x00000002 |
| spe:pflash0 | | .text.sync_on_halt._sync_on_halt (61) | 0x0000008e | 0x800003ee | 0x000003ee | 0x00000002 |
| spe:pflash0 | | .text.sync_on_halt._sync_on_halt_end (60) | 0x0000000c | 0x8000047c | 0x0000047c | 0x00000002 |
| spe:pflash0 | | .text.test.main (84) | 0x0000000c | 0x80000488 | 0x00000488 | 0x00000002 |
| spe:pflash0 | | [.data.dflash0] (203) | 0x00008000 | 0x80000494 | 0x00000494 | 0x00000001 |
| spe:pflash0 | | PFLASH (5) | 0x00000014 | 0x80008494 | 0x00008494 | 0x00000001 |
| spe:dflash0 | | .data.dflash0 (1) | 0x00008000 | 0x8fe00000 | 0x0 | 0x00000001 |
The Tasking VX linker infers the segment type and other metadata based on the name of a section. The .data
in .data.dflash0
signifies initialized data. That is read-write RAM memory for which an initial state gets copied from ROM during star-up. The second copy in PFLASH
which you are seeing is this initialization copy.
The solution is to use the .rodata
section prefix instead, which is intended for read-only data.
Effectively the linker has been given an absolute address and told to initialize it and so must assume that it is backed by RAM. Aside from wasting space it is of course also a bad idea to have the CRT start-up attempt to write into FLASH.
Incidentally the .data
and .rodata
are not magic hard-coded names. A linker script, in this case the default one, includes group directives indicating which memory area each of the individual sections is to be located into along with attributes such as nocopy
to control the initialization.