Перейти к содержанию
    

BootLoader - странные команды

Пишу загрузчик дял AVR (Mega328) в IAR EWAVR 5.1.

 

Отредактировал файл настроек линкера:

/*                      - lnkm324s.xcl -
*
*   XLINK command file for the ICCAVR C-compiler using the --cpu=m324, -ms
*   options. 
*
*   Usage: xlink your_file(s) -f lnkm324s
*
*   File version: $Revision: 1.1 $
*/

/*=================== CONSTANTS =============================*/
/* Constants used in the ranges down below, 
* Do not change these lines, 
* if it is not stated otherwise 
*/


/* ÏÅÐÅÄÅËÀÍÎ ÏÎÄ ÇÀÃÐÓÇ×ÈÊ Ñ ÐÀÇÌÅÐÎÌ 2048 ñëîâ (4096 áàéò). Íà÷èíàåòñÿ ñ àäðåñà 7000 (â áàéòàõ) */
/* ÂÍÈÌÀÍÈÅ! Ëåíêåð ðàáîòàåò ñ áàéòîâîé àäðåñàöèåé (íå ñìîòðÿ íà òî, ÷òî Flash ïàìÿòü AVR ñîñòîèò èç ñëîâ 2 áàéòà) */


/* Code (flash) segments */
-D_..X_INTVEC_SIZE=7C   /* 31 Interrupt vectors * 4 bytes each */
-D_..X_FLASH_TEND=FF    /* End of tiny flash memory */
-D_..X_FLASH_NEND=7FFF  /* End of near flash memory */
-D_..X_FLASH_END=7FFF   /* End of flash memory */
/* Internal data memory */
-D_..X_SRAM_BASE=100    /* Start of ram memory */
-D_..X_SRAM_TEND=100    /* End of tiny ram memory */

-D_..X_SRAM_END=8FF     /* End of ram memory */
/* Internal EEPROM */
-D_..X_EEPROM_END=3FF   /* End of eeprom memory */
/*==================== END OF CONSTANTS =====================*/

/*
* Modify the lines below to alter the size of the RSTACK, CSTACK and HEAP
* segments. These need to be fine tuned to suit your specific application.
* The '_..X_' prefix is used by C-SPY as an indication that the label should
* not be displayed in the dissassembly window.
*/
-D_..X_CSTACK_SIZE=100  /* 256 bytes for auto variables and saved registers. */
-D_..X_RSTACK_SIZE=40   /* 64 bytes for return addresses, equivalent to 32 */
                        /* levels of calls, including interrupts. */
-D_..X_HEAP_SIZE=80     /* 128 bytes of heap. */
-D_..X_NEAR_HEAP_SIZE=80     /* 128 bytes of heap. */

/* Define CPU */
-ca90

/*
* The following segments are located in the internal memory of
* the ATmega324. Do not change these lines.
*/

/* Code memory */
-Z(CODE)INTVEC=7000-(7000+_..X_INTVEC_SIZE-1)                            /*-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)*/

/* Fill unused interrupt vector's with RETI */
-H1895
-h(CODE)7000-(7000+_..X_INTVEC_SIZE)                                        /*-h(CODE)0-_..X_INTVEC_SIZE*/

-Z(CODE)TINY_F=_..X_INTVEC_SIZE-_..X_FLASH_TEND
-Z(CODE)NEAR_F,SWITCH,INITTAB,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_END
-Z(CODE)CODE=(7000+_..X_INTVEC_SIZE)-_..X_FLASH_END                    /*-Z(CODE)CODE=_..X_INTVEC_SIZE-_..X_FLASH_END*/
-Z(CODE)TINY_ID,NEAR_ID=(7000+_..X_INTVEC_SIZE)-_..X_FLASH_END        /*-Z(CODE)TINY_ID,NEAR_ID=_..X_INTVEC_SIZE-_..X_FLASH_END*/
-Z(CODE)CHECKSUM#_..X_FLASH_END

/* Internal data memory */
-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_TEND
-Z(DATA)NEAR_I,NEAR_Z,NEAR_N=_..X_SRAM_BASE-_..X_SRAM_END

/*
* If external SRAM is available it is possible to place the stacks there.
* However, the external memory is slower than the internal so moving the
* stacks to the external memory will degrade the system performance.
*/
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END

/*
* If external SRAM is available it might be a good idea to move the
* heap segment there, i.e. remove the _..X_SRAM_BASE-_..X_SRAM_END range.
*/
-Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)IOSTREAM_N#_..X_SRAM_BASE-_..X_SRAM_END
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END

/* Internal eeprom memory */
-Z(XDATA)EEPROM_I,EEPROM_N=0-_..X_EEPROM_END

/* Select reduced "printf" support to reduce library size.
   See configuration section in manual concerning printf/sprintf. */

/*Dlib*/
-e_PrintfSmall=_Printf

/*Clib*/
-e_small_write=_formatted_write

/*Dlib and Clib*/
-e_small_write_P=_formatted_write_P

/* Disable floating-point support in "scanf" to reduce library size.
   See configuration section in manual concerning scanf/sscanf */

/*Dlib*/
-e_ScanfSmall=_Scanf

/*Clib*/
-e_medium_read=_formatted_read

/*Dlib and Clib*/
-e_medium_read_P=_formatted_read_P

/* Suppress one warning which is not relevant for this processor */
-w29

/* Code will now reside in file aout.a90 or aout.d90, unless -o is specified */
/* .d90 is the default if debug system is linked (option -r) */
/* .a90 is the default without debugging. Default format is -Fmotorola */

 

 

Код, как и указано, размещается с адреса 0x7000, работает без ошибок (включая прерывания). Но...

Начиная с адреса 0x7C (неиспользуемый сегмент памяти области приложения) появляется цепочка команд.

Дамп памяти:

a8bf5e8edd0f.jpg

 

Дизассемблер:

......

+0000003B:   FFFF        ???                      Data or unknown opcode
+0000003C:   FFFF        ???                      Data or unknown opcode
+0000003D:   FFFF        ???                      Data or unknown opcode
@0000003E: _..X_INTVEC_SIZE
+0000003E:   0013        ???                      Data or unknown opcode
+0000003F:   011A        MOVW      R2,R20         Copy register pair
@00000040: _..X_RSTACK_SIZE
+00000040:   0000        NOP                      No operation
@00000041: ?<Segment init: NEAR_I>
+00000041:   001A        ???                      Data or unknown opcode
+00000042:   0100        MOVW      R0,R0          Copy register pair
+00000043:   7DDA        ANDI      R29,0xDA       Logical AND with immediate
+00000044:   FFFF        ???                      Data or unknown opcode
+00000045:   FFFF        ???                      Data or unknown opcode
......

 

 

Вопрос. Что это за инициализация, откуда она берётся (в настройках линкера эти адреса нигде не фигурируют). И главное, что произоёдёт, когда в эту область памяти вместо этих команд будет загружена основная программа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В этом файле чёрт ногу сломит. Наёшл 2 записи

INITTAB

Relative segment

CODE 0000007C - 00000081

Segment part 12.

и

INITTAB

Relative segment

CODE 00000082 - 00000087

Segment part 18.

 

Вот так память бьётся на сегменты

a3be0c1274ce.jpg

 

Прикрепил файл к посту.

NoiseGen_BootLoader.html

Изменено пользователем Sergey_Aleksandrovi4

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашёл 2 записи
Сегмент INITTAB содержит таблицы, по которым startup-код обнуляет и присваивает начальные значения глобальным и статическим переменным. Почему именно этот сегмент линкер вынес - сложно сказать, но в строке -Z(CODE)NEAR_F,SWITCH,INITTAB,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_END вы разрешили ему положить этот сегмент в свободное место в диапазоне адресов 7C...7FFF, что он и сделал. Полагаю, тут надо использовать не _..X_INTVEC_SIZE, а 7000+_..X_INTVEC_SIZE. Причем "магическое число" 7000 удобнее также объявить константой через -D_..X_FLASH_START=7000 и дальше уже оперировать с ней.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за совет, помогло. Область приложений теперь девственно чиста (0xFF).

Запись

(CODE)NEAR_F,SWITCH,INITTAB,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_END

у самого подозрения вызывала, но боялся вносить правки в файл конфигурации (все изменения делал по мотивам предыдущих тем форума, посвящённым построению загрузчиков AVR). То же и с "магическим" 0x7000.

Прикрепляю файл конфигураци, вдруг кому ещё пригодится (не смог загрузить файл с расширением *.xcl, поэтому заменил на *.txt).

 

 

Вопрос вдогонку. После того, как в файле настроек линкера объявил константу -D_..X_FLASH_START=7000, можно ли как-нибудь использовать её при вычислениях в тексте программы? Или она доступна только линкеру?

lnkm324ps.txt

Изменено пользователем Sergey_Aleksandrovi4

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

боялся вносить правки в файл конфигурации
Так он-то писан был в расчете на приложение, которое начинается с 0.

После того, как в файле настроек линкера объявил константу -D_..X_FLASH_START=7000, можно ли как-нибудь использовать её при вычислениях в тексте программы? Или она доступна только линкеру?
Если объявить ее без начальных "_..", то можно, хоть и "с вывертом". Выверт заключается в следующем: фактически, все константы линкера для компилятора - адреса (переменных либо функций), а не собственно значения переменных. Поэтому вы можете объявить extern uint8_t const X_FLASH_START, но значение 0x7000 будет иметь адрес этой "переменной", т.е. использовать надо будет uintptr_t FLASH_START = (uintptr_t)&X_FLASH_START; и дальше работайте FLASH_START на здоровье. Но помните, что поскольку этот адрес не известен на этапе компиляции - компилятор скорее всего не сможет заранее просчитать константные арифметические выражения с этой переменной и будет вынужден вычислять их на этапе выполнения.

 

"_.." в начале константы говорит о том, что эта константа локальная для скрипта и она не будет фигурировать ни в объектном файле, ни в дизассемблированном коде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...