Задача VX, почему предопределенный файл данных связан дважды
Не могу понять, почему мой файл (содержащий только байты DataFlash0) дважды связан с выходным гексом. Я компилирую для Infineon TC1797 с компилятором Tasking VX.
Помимо программы, у меня есть файл с именем data_flash_bank_0.asm, который включает только предопределенные байты данных.
Компилятор правильно размещает его по ожидаемому адресу 0x8FE00000, который представляет собой флеш-память 0 в аппаратном обеспечении.
Что не так, так это то, что тот же код появляется в программе как вторая копия, тратя место и не тратя времени.
Все настройки в свойствах проекта, кажется, хорошо, "удалить дубликаты" включены.
Чтобы проиллюстрировать проблему, я сделал один ОЧЕНЬ МАЛЕНЬКИЙ проект, в котором всего 3 файла: функция test.c с main(), функция короткой сборки, считывающая флэш-данные, и флэш-память данных предопределена.
test.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 |
1 ответ
Компоновщик Tasking VX определяет тип сегмента и другие метаданные на основе имени раздела. .data
в .data.dflash0
означает инициализированные данные. Это оперативная память для чтения и записи, для которой начальное состояние копируется из ПЗУ во время запуска. Второй экземпляр в PFLASH
который вы видите, это копия инициализации.
Решение состоит в том, чтобы использовать .rodata
вместо этого префикс раздела, который предназначен для данных только для чтения.
Фактически, компоновщику был дан абсолютный адрес, и ему было приказано инициализировать его, и поэтому он должен предполагать, что он поддерживается ОЗУ. Помимо потери места, конечно, также плохая идея, чтобы попытка запуска ЭЛТ записать во FLASH.
Кстати .data
а также .rodata
не магические жестко закодированные имена. Сценарий компоновщика, в данном случае по умолчанию, включает в себя групповые директивы, указывающие, в какую область памяти должен быть помещен каждый из отдельных разделов, а также такие атрибуты, как nocopy
контролировать инициализацию.