Я работаю над прошивкой для микроконтроллера 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
начала программы fla sh)
.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
Я не понимаю, почему это происходит.
* 104 6 * Мои вопросы:
- Как я могу заставить компоновщик поместить все функции (кроме
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.
*/