Попробую развить мысль дальше. Моя методика (описанная ниже) -- плохая. При компоновке программы с новой версией бутлоадера программа не работает с более старой. Даже если в ней ничего принципиально не менялось -- расположение функций в памяти просто другое. А ситуация старый бутлоадер + обновление программы -- типовая. Нужно делать структуру с указателями, как сказали. Кроме того, если я собираюсь экспортировать функции использующие .const сегмент, то нужно как-то менять PSVPAGE при их исполнении. Что неудобно (опять оборачивать каждую функцию ассемблером). Кроме того, мне не вернуть указатель на константные данные (если PSVPAGE у бутлоадера и рабочей программы разный). Единственное что приходит в голову -- сделать одинаковый PSVPAGE. А поскольку бутлоадер размещается в околонулевых адресах, то PSVPAGE должен быть равен нулю. Не так-то просто это. Написал в *.gld файле .const : AT(0x3000) { *(.const)...} Если менее 0x3000 -- пересекается с .text и не работает. Т.е. размер сегмента const у меня получается уже ограничен не в 0x8000, а в 0x5000 байт. Еле влезло. А если const сдвинуть ниже:
[ZX]
pic30-coff-ld: Link Error: section .const [002000 -> 006d49 ] overlaps section .text [000200 -> 002f45 ]Не совсем понимаю ошибку. Какая-то часть .text тяготеет к низу (но уже за пределами near -- первыми 0x2000 байт) и не хочет линковаться выше const, не понимаю почему. Кажется догадываюсь:
** Note that input sections *(.text) are not mapped here.
** The best-fit allocator locates them, so that .text
** may flow around PSV sections as needed.
*/
.text :
{
*(.init);
*(.user_init);
KEEP (*(.handle));
KEEP (*(.isr*));
*(.libc) *(.libm) *(.libdsp); /* keep together in this order */
*(.lib*);
} >program
Из-за комментария выше. Всё в .lib* кладётся обязательно до const. Не понимаю с какой целью. Особенно keep together in this order -- какой в этом смысл?
Написал так:
.lowtext :
{
*(.init);
*(.user_init);
KEEP (*(.handle));
KEEP (*(.isr*));
} >program
/*
** For PSV type sections, the Load Memory Address (LMA)
** should be specified as follows:
**
** userconst : AT(0x1234)
** {
** *(userconst);
** } >program
**
** Note that mapping PSV sections in linker scripts
** is not generally recommended.
**
** Because of page alignment restrictions, memory is
** often used more efficiently when PSV sections
** do not appear in the linker script.
**
** For more information on memory allocation,
** please refer to chapter 10, 'Linker Processing'
** in the Assembler, Linker manual (DS51317).
*/
.const : AT(0x1000)
{
___start_const = .;
*(.const);
___start_xsref = .;
*(xsref);
___stop_xsref = .;
___start_fsm = .;
*(fsm);
___stop_fsm = .;
___start_minit = .;
*(minit);
___stop_minit = .;
___stop_const = .;
} >program
.text :
{
*(.libc) *(.libm) *(.libdsp); /* keep together in this order */
*(.lib*);
} > program
Помогло... Но не понимаю такого отношения к секции libc, libm и т.п. Зачем?
Возвращаясь назад. Теперь т.к. const лежит от 0x1000 до чуть менее чем 0x5000 (меньше 0x8000 -- верхний лимит) PSVPAGE будет равен нулю. И я могу свободно передавать указатели на const-переменные из бутлоадера и обратно. И я могу сразу без модификации PSVPAGE вызывать функции экспортируемые бутлоадером (если они используют секцию const, что для более-менее сложного кода всегда). И могу сделать структуру со списком адресов экспортируемых функций и пытаться эту структуру расположить по фиксированному адресу (в ПЗУ). Что я ещё мог забыть?