Я работаю над прошивкой для микроконтроллера PIC32MX. Память программы должна быть разделена на три сегмента:
- Раздел 1: процедура обслуживания прерывания и основная функция (
startup_region
) - Раздел 2: 50% оставшейся программной памяти (
program1
) - Раздел 3: 50% оставшейся программной памяти (
program2
)
Прошивка хранится только в разделе 2 или 3. Другой зарезервирован для будущих обновлений. Таким образом, активная область может безопасно переопределить другую для хранения обновления. Бит конфигурации перевернут, и функция main() раздела 0 теперь переходит к другой программе при перезагрузке.
Таким образом, мне нужно, чтобы компоновщик поместил все функции, кроме isr
и main
, в раздел 1, а все остальное — в раздел 2. Раздел 3 нужно оставить полностью пустым, так как в будущем он может быть переопределен.
Я уже пытался добиться этого, изменив сценарий компоновщика по умолчанию, однако безуспешно.
linkerscript.ld:
/* [...] */
INCLUDE procdefs.gld
/* [...] */
SECTIONS
{
/* [...] */
.text :
{
/* isr() and main() should be at the very first locations in program memory */
*(.text.isr)
*(.text.main)
/* [...] */
. = ALIGN(4) ;
} >kseg0_program_mem
.program1 :
{
*(*.text)
} >program1
/* [...] */
}
procdefs.gld:
/* [...] */
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0x10000
startup_region (rx) : ORIGIN = 0x9D000000, LENGTH = 0x01000
program1 (rx) : ORIGIN = 0x9D002000, LENGTH = 0x07000
program2 (rx) : ORIGIN = 0x9D009000, LENGTH = 0x07000
kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0x970
/* [...] */
}
/* [...] */
Это приводит к следующему:
isr()
и main()
там, где они должны быть (0x9D00000
- виртуальный адрес KSEG0
начала прошивки программы)
.text 0x9d000000 0x94
*(.text.isr)
.text.isr 0x9d000000 0x60 build/default/production/main.o
0x9d000000 isr
*(.text.main)
.text.main 0x9d000060 0x34 build/default/production/main.o
0x9d000060 main
Область program1
размещена правильно, и большинство объектных файлов перечислены правильно (заметьте, однако, что main.o
указан снова — он уже использовался).
.program1 0x9d002000 0xc44
*(*.text)
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX330F064H/crt0_mips32r2.o
.text 0x9d002000 0x0 /opt/microchip/xc32/v2.10/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/debug-exception-return.o
.text 0x9d002000 0x0 build/default/production/main.o
.text 0x9d002000 0x0 build/default/production/commands.o
/* [...] */
.text 0x9d002000 0x0 build/default/production/micro-ecc/uECC.o
Однако некоторые функции расположены за пределами этой области:
.text.uECC_verify
0x9d000b04 0x7c0
.text.uECC_verify
0x9d000b04 0x7c0 build/default/production/micro-ecc/uECC.o
0x9d000b04 uECC_verify
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520
.text.vli_mmod_fast_secp256r1
0x9d0012c4 0x520 build/default/production/micro-ecc/uECC.o
Я не понимаю, почему это происходит.
Мои вопросы:
- Как я могу заставить компоновщик поместить все функции (кроме
main
иisr
) вprogram1
. - Как мне запретить компоновщику что-либо класть в
program2
, чтобы он оставался свободным.
Я компилирую ПО с переключателем -ffunction-segments
, чтобы каждой функции достался свой сегмент.
Оригинальный линкерскрипт также содержит подозрительный комментарий:
/* Code Sections - Note that input sections *(.text) and *(.text.*)
are not mapped here. Starting in C32 v2.00, the best-fit allocator
locates them, so that .text may flow around absolute sections
as needed.
*/
*(.text.*)
в разделе .program1? - person Ctx   schedule 20.02.2020