0

无法弄清楚,为什么我的文件(仅包含 DataFlash0 字节定义)链接到输出十六进制两次。我正在使用 Tasking VX 编译器为 Infineon TC1797 进行编译。

除了程序,我还有一个名为 data_flash_bank_0.asm 的文件,它只包含预定义的数据字节。

编译器将其正确放置在预期的地址 0x8FE00000,即硬件中的数据闪存 0。

问题是相同的代码作为第二个副本出现在程序中,浪费空间并且不需要。

项目属性中的所有设置似乎都很好,启用了“删除重复项”。

为了说明这个问题,我做了一个非常小的项目,其中只有 3 个文件:带有 main() 的 test.c 函数,读取数据闪存的短汇编函数,以及数据闪存预定义。

测试.c:

 #include <stdio.h>

 extern void * loop_36(void); // call the main assembly function

 int main(void)
 {
    loop_36();
 }

汇编函数 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

实际的预定义字节区域给了我问题,文件 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

地图文件:(最后一行是我所期望的,但它上面的2行,长度也是0x8000,我不要)

 +------------------------------------------------------------------------------------------------------------------------+
 | 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 |
4

1 回答 1

3

Tasking VX 链接器根据节的名称推断段类型和其他元数据。.datain.data.dflash0表示已初始化的数据。那是读写 RAM 存储器,在启动期间从 ROM 复制初始状态。您看到的第二个副本PFLASH是这个初始化副本。

解决方案是改用.rodata节前缀,该前缀用于只读数据。

实际上,链接器已被赋予一个绝对地址并被告知对其进行初始化,因此必须假设它由 RAM 支持。除了浪费空间之外,让 CRT 启动尝试写入 FLASH 当然也是一个坏主意。

顺便说一句,.dataand.rodata不是神奇的硬编码名称。链接描述文件,在这种情况下是默认的,包括组指令,指示每个单独的部分将位于哪个内存区域以及nocopy控制初始化等属性。

于 2017-02-19T09:09:49.557 回答