vitek101 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба Поставил. Стартует он откуда надо. У XMega только одна область для загрузчика, 8 Кб. Что-то не получается у меня отключить стандартную библиотеку. Если ее выкинуть, вылезает толпа разных ошибок. А если взять и в стандартном STARTUPе заменить строки RSEG CODE:CODE:NOROOT(1) на RSEG BOОT_ENTRY:CODE:NOROOT(1) Может так сработает? И main на boot Работает!!! :08: В общем поменял CODE на BOOT_ENTRY, а main оставил. Теперь следующая картина: Стартует с загрузчика, но без STARTUPа. Праметр bytesToRead так и не работает (см. первый пост). Но попробовал опять убрать address и все заработало. Стартап появляет в отладчике в начале основной программы. Непонятно вылезут дальше косяки какие-нибудь или нет, т.к. проблема с address так и не решена. Спасибо за помощь! :a14: Теперь стартап такой: ;---------------------------------------------------------------------------- ; Set up the INTVEC segment with a reset vector ;---------------------------------------------------------------------------- MODULE ?RESET COMMON INTVEC:CODE:ROOT(1); Align at an even address EXTERN ?C_STARTUP PUBLIC __program_start PUBLIC ?RESET ORG $0 __program_start: ?RESET: XJMP ?C_STARTUP ENDMOD ;---------------------------------------------------------------------------- ; Forward declarations of segments used in initialization ;---------------------------------------------------------------------------- RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) ;---------------------------------------------------------------------------- ; Perform C initialization ;---------------------------------------------------------------------------- MODULE ?C_STARTUP EXTERN __low_level_init EXTERN __segment_init #ifdef _ECLIB_ECPP EXTERN __call_ctors #endif /* _ECLIB_ECPP */ EXTERN main EXTERN exit EXTERN _exit ;---------------------------------------------------------------------------- ; If the return address stack is located in external SRAM, make sure that ; you have uncommented the correct code in __low_level_init!!! ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC ?C_STARTUP PUBLIC __RESTART EXTERN ?RESET __RESTART: ?C_STARTUP: #if A90_POINTER_REG_SIZE > 2 PUBLIC ?zero_reg_initialization ?zero_reg_initialization: CLR R15 OUT RAMPD,R15 #endif REQUIRE ?SETUP_STACK REQUIRE ?RESET RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC __RSTACK_in_external_ram __RSTACK_in_external_ram: LDI R16,0xC0 OUT 0x35,R16 ;Enable the external SRAM with a wait state RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC __RSTACK_in_external_ram_new_way EXTERN __?XMCRA __RSTACK_in_external_ram_new_way: LDI R16,0x8C ;SRE=1,SRL2=0,SRL1=0,SRL0=0,SRW11=1,SRW10=1,SRW01=0,SRW00=0 STS __?XMCRA,R16 ;Enable the external SRAM with maximum wait state. ;---------------------------------------------------------------------------- ; Set up the CSTACK and RSTACK pointers. ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) ?SETUP_STACK: ;; Return address stack (RSTACK) LDI R16,LOW(SFE(RSTACK)-1) OUT 0x3D,R16 #if A90_POINTER_REG_SIZE > 1 LDI R16,HIGH(SFE(RSTACK)-1) OUT 0x3E,R16 #endif ;; Data stack (CSTACK) LDI Y0,LOW(SFE(CSTACK)) #if A90_POINTER_REG_SIZE > 1 #if MEMORY_MODEL == TINY_MEMORY_MODEL LDI Y1,0 #else LDI Y1,HIGH(SFE(CSTACK)) #endif #if A90_POINTER_REG_SIZE > 2 LDI Z0,HWRD(SFB(CSTACK)) OUT RAMPY,Z0 #endif #endif #if A90_POINTER_REG_SIZE > 2 ; Nothing here, the things previously here has been done earlier. #else REQUIRE ?call_low_level_init ;---------------------------------------------------------------------------- ; Clear R15 so that it can be used as zero register by the code generator. ; The compiler will emit a "REQUIRE ?zero_reg_initialization" statement if ; this optimization has been enabled. ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC ?zero_reg_initialization ?zero_reg_initialization: CLR R15 ;---------------------------------------------------------------------------- ; Call __low_level_init to do low level initializatons. Modify the supplied ; __low_level_init module to add your own initialization code or to ; remove segment initialization (by returning 0). ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) #endif PUBLIC ?call_low_level_init ?call_low_level_init: XCALL __low_level_init REQUIRE ?cstartup_call_main ;---------------------------------------------------------------------------- ; Call __segment_init to initialize segments. ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC ?need_segment_init ?need_segment_init: TST P0 BREQ ?skip_segment_init XCALL __segment_init ?skip_segment_init: ;---------------------------------------------------------------------------- ; Call the constructors of all global objects. This code will only ; be used if any EC++ modules defines global objects that need to ; have its constructor called before main. ;---------------------------------------------------------------------------- #ifdef _ECLIB_ECPP RSEG DIFUNCT:CODE:NOROOT(0) RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC ?call_ctors ?call_ctors: #ifdef __HAS_ELPM__ LDI P0,LOW(SFB(DIFUNCT)) LDI P1,LOW(SFB(DIFUNCT) >> 8) LDI P2,SFB(DIFUNCT) >> 16 LDI Q0,LOW(SFE(DIFUNCT)) LDI Q1,LOW(SFE(DIFUNCT) >> 8) LDI Q2,SFE(DIFUNCT) >> 16 #else LDI P0,LOW(SFB(DIFUNCT)) LDI P1,SFB(DIFUNCT) >> 8 LDI P2,LOW(SFE(DIFUNCT)) LDI P3,SFE(DIFUNCT) >> 8 #endif XCALL __call_ctors #endif /* _ECLIB_ECPP */ ;---------------------------------------------------------------------------- ; Call main ;---------------------------------------------------------------------------- RSEG BOOT_ENTRY:CODE:NOROOT(1) PUBLIC ?cstartup_call_main ?cstartup_call_main: XCALL main XCALL exit XJMP _exit END ;---------------------------------------------------------------------------- ; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба Так у вас просто мешанина получилась, часть стартапа в начале флеша, часть с boot_entry. причем еще low_level_init вызыватеся, которая берестя из библиотеки по умолчанию. А когда вы бутлоадером прошьете новую программу вызов low_level_init будет непредсказуемым. Если ее конечно не определить в BOOT сегменте. Но лучше разобраться с линкером и библиотеками и написать свой простейший стартап. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба Разобраться конечно неплохо бы :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба А что за ошибки то возникают если библиотеку отключить? Вы используете библиотечные функции? вообще надо map файл смотреть! не должен бутлоадер содеражть лишних кусков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба В том то и дело, что я не могу ее отключить. В свойствах проекта в линкере поотключал что нашел, а он все равно на библиотеку ссылается. Попробовал ее удалить, тогда валятся ошибки, что библиотека не найдена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба В том то и дело, что я не могу ее отключить. В свойствах проекта в линкере поотключал что нашел, а он все равно на библиотеку ссылается. Попробовал ее удалить, тогда валятся ошибки, что библиотека не найдена. Так это в General Options Library Configuration Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MDD 0 12 ноября, 2009 Опубликовано 12 ноября, 2009 · Жалоба Не совсем в тему, но может будет полезно. Недавно тоже делал бутлоадер для Xмеги, только 32-й. Долго не мог побороть вот какую фигню - не смотря на то, что линкеру явно было указано размещать весь код в секции бутлоадера, тем не менее в файле прошивки наблюдалось следующее: весь код действительно сидел в нужной секции. Но стартовый jmp почему-то упорно пихался по нулевому адресу. Причем указывал этот jmp совсем не на начало секции бутлоадера (что можно было бы стерпеть), а куда-то вовнутрь него. Почитав форум, решил, что причина в стартапе и его нужно править(хотя смутно представлял что именно). Перетащил его исходник в папку проекта и подключил его к проекту. После этого проект пересобрал, чтобы проверить не возникает ли конфликтов с библиотекой. Конфликтов почему-то не возникло. Наверное "своему стартапу" отдается предпочтение. Но самое главное, глюк исчез без всякой правки! Теперь стартовый вектор находился где надо - в начале секции бутлоадера. Компилятор тоже 5.20 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 13 ноября, 2009 Опубликовано 13 ноября, 2009 · Жалоба Так это в General Options Library Configuration А, ну да, там тоже отключал (Library Configuration) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
D1ma 0 13 ноября, 2009 Опубликовано 13 ноября, 2009 · Жалоба Здравствуйте Впервые пишу будлоадер. (не судите строго) Пишу в IAR 5.2.1 под АТmega128. Создал проект, написал свой *.xcl Вектор ресет на адрес 0x0000 В *xcl указал адрес кода 0хf000-0xffff, в этом пространстве и вектора прерываний. Тоесть, если есть прога то она запускается если нет то бутлоадер(думаю). *.xcl : // The '_..X_' prefix is used by C-SPY as an indication that the label should // not be displayed in the dissassembly window. // // Set up XLINK -ca90 -w29 /* Code memory - this line is generated with preprocessor.xls */ -Z(CODE)INTVEC,FAR_F,SWITCH,CODE=F000-FFFF /*EEPROMMEMORY*/ -Z(XDATA)EEPROM_I,EEPROM_N=0-FFF ////////////////////////////////////////////////////////////////////////////// //SRAM -D_..X_CSTACK_SIZE=200 /* 512 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=100 /* 256 bytes of heap. */ -D_..X_SRAM_BASE=100 /* Start of ram memory */ -D_..X_SRAM_TEND=100 /* End of tiny ram memory */ -D_..X_SRAM_END=10FF /* End of ram memory */ -D_..X_EXT_SRAM_BASE=0 /* Start of exram memory */ -D_..X_EXT_SRAM_SIZE=0 /* End of exram memory */ -Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_TEND -Z(DATA)NEAR_I,NEAR_Z=_..X_SRAM_BASE-_..X_SRAM_END,_..X_EXT_SRAM_BASE-(_..X_EXT_SRAM_BASE+_..X_EXT_SRAM_SIZE) -Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END /* ,_..X_EXT_SRAM_BASE-(_..X_EXT_SRAM_BASE+_..X_EXT_SRAM_SIZE) */ -Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_SRAM_BASE-_..X_SRAM_END /* ,_..X_EXT_SRAM_BASE-(_..X_EXT_SRAM_BASE+_..X_EXT_SRAM_SIZE) */ -Z(DATA)HEAP+_..X_HEAP_SIZE=_..X_SRAM_BASE-_..X_SRAM_END,_..X_EXT_SRAM_BASE-(_..X_EXT_SRAM_BASE+_..X_EXT_SRAM_SIZE) Код бутлоадера: #include <ioavr.h> #pragma vector=USART1_RXC_vect __interrupt void irqINT0_vect (void) { } void main() { long address; unsigned int temp_int; unsigned char val; /*Initialization*/ void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector. /*Body*/ //..... /* Jump to Reset vector 0x0000 in Application Section.*/ funcptr(); } Прога которая загружается бутлоадером создана обычно, тоесть вектора сначала, код в адресе 0х0000-0xEFFF. Да, эта же прога должна и запускать бутлоадер думаю так void (*pBoot)( void ) = 0xf000; pBoot(); Вопрос: В бутлоадера есть свои вектора прерываний по адресу 0xf000 и свой стартап , переменные… в проги свои. Как себя поведет, контролер, если выполнится стартап проги потом будлоадера потом снова проги и так дали? В какие прерывания будет попадать бут.. и прога (по адресу 0х0000 или 0хf000)? Что будет делаться с теми переменами которые были в проге, какая была переписана другой (глобальные, внутренние ?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 13 ноября, 2009 Опубликовано 13 ноября, 2009 · Жалоба Тоесть, если есть прога то она запускается если нет то бутлоадер(думаю). Я бы на это не рассчитывал, если конечно FLASH стерт и заполнен 0xFF до доскачет конечно и до бутлоадера :). А если нет может где нибудь зависнуть. Обычно всегда стартует бутлоадер и проверяет либо целостность проги, либо условие запуска бутлоадера, или ... и решает что запускать прогу или себя! Вопрос: В бутлоадера есть свои вектора прерываний по адресу 0xf000 и свой стартап , переменные… в проги свои. Как себя поведет, контролер, если выполнится стартап проги потом будлоадера потом снова проги и так дали? да контроллеру пофиг - стартап обычно инитит стек, заполняет часть памяти 0 и копирует часть памяти из флеша и вызвает main, это можно делать сколько угодно раз! А вот с переферией могут быть проблемы - ее надо полностью инитить, даже не используемую раз выиспользуете перрывания и там и там, потому что проиниченная переферия с включенными прерываниями не используемая программой или бутлоадером даст глюки. IMHO лучший вариант переключения между бутлоадером и программой через ресет ( с помощью watchdog). Тем более что причину reset можно определить и память не сбрасывается, можно метку ставить. В какие прерывания будет попадать бут.. и прога (по адресу 0х0000 или 0хf000)? Есть бит IVSEL управляющий размещением векторов. Но вот прерывания в бутлоадере IMHO лучше не использовать, вернее обычно они не нужны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 13 ноября, 2009 Опубликовано 13 ноября, 2009 · Жалоба Тоесть, если есть прога то она запускается если нет то бутлоадер(думаю).Лучше специально заточенным фузом запускать всегда загрузчик. А уже он решит - отдавать управление программе или нет. Скрипт правильный. /*Body*/ //..... /* Jump to Reset vector 0x0000 in Application Section.*/ funcptr(); } В целом правильно, но я вместо этого после прошивки просто сбрасываю процессор собакой. Он рестартует, попадает в загрузчик, загрузчик (в __low_level_init) проверяет целостность приложения и отдает ему управление. Этот же код работает и при включении, то есть получается максимально быстрый запуск приложения при обычном включении - если надо запускать приложение, то не тратится время на исполнение всего стартапа загрузчика.Да, эта же прога должна и запускать бутлоадер думаю так void (*pBoot)( void ) = 0xf000; pBoot(); Правильно. У меня загрузчик определяет, что его вызвали из приложения по направлению одной из ног, которая штатно используется на вывод (при холодном старте все ноги настроены на ввод).Вопрос: В бутлоадера есть свои вектора прерываний по адресу 0xf000 и свой стартап , переменные… в проги свои. Как себя поведет, контролер, если выполнится стартап проги потом будлоадера потом снова проги и так дали? В какие прерывания будет попадать бут.. и прога (по адресу 0х0000 или 0хf000)? Что будет делаться с теми переменами которые были в проге, какая была переписана другой (глобальные, внутренние ?) Стартап на то и стартап, что подготавливает окружение для работы проги. То есть инициализирует указатель стека, переменные, настраивает периферию (в __low_level_init). Грамотная программа не должна полагаться на неинициализированные значения, а инициализированные будут подготовлены стартапом. Естественно, старые значения, оставшиеся от прги/загрузчика будут затерты. Если вам надо сохранять какие-то переменные - вынесите их в отдельный сегмент и на его месте в скрипте загрузчика зарезервируйте память. Для определения таких переменных вам понадобится квалификатор __no_init. Вектора вы переключаете сами - для этого есть специальный битик. P.S. В будущем не стоит встревать с отдельным вопросом в активную тему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
D1ma 0 14 ноября, 2009 Опубликовано 14 ноября, 2009 · Жалоба как написать свой стартап и ловлевелинит? щас у меня IAR генерит свои автоматически. если можно, пример, желательно на С Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 14 ноября, 2009 Опубликовано 14 ноября, 2009 · Жалоба как написать свой стартап и ловлевелинит? просто определить int __low_level_init( void ) в своей программе. если функция возвращает 0 то инициализация сегментов пропускается! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 14 ноября, 2009 Опубликовано 14 ноября, 2009 · Жалоба как написать свой стартапЗачем? Что вас не устраивает в библиотечном? Если очень необходимо - в папке с примерами есть его ассемблерный исходник. Копируйте файл в папку своего проекта и подключайте его к проекту. На C написать его будет затруднительно - компилятор формирует прологи/эпилоги для функций, которые в данном случае будут только мешать. и ловлевелинит?Определяете функцию int __low_level_init(). Она подменяет библиотчную. Если проект собирается в режиме С++, то объявите ее с квалификатором extern "C" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vitek101 0 17 ноября, 2009 Опубликовано 17 ноября, 2009 · Жалоба Почему может постоянно забиваться CSTACK? Читаю загрузчиком программу из FRAM, пишу ее во флеш страницами по 512 байт, когда дохожу до последней страницы выдается сообщение, что CSTACK забит на 98 процентов и все перестает работать (меняются многие переменные на кривые значения). Пробовал менять размер стека, все время забивается на 98 процентов. От размера загружаемой программы не зависит... :laughing: Да, загрузчик сделал отдельным проектом Снимаю вопрос. Одно условие прорустил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться