|
Bootloader. Подскажите., Проблема наверно в языке... |
|
|
|
Nov 11 2009, 08:53
|

Участник

Группа: Участник
Сообщений: 39
Регистрация: 24-08-09
Пользователь №: 52 013

|
Написал загрузчик для XMega128, IAR5.20. Переделал его из примера Атмела 1605. Загрузчик расположен в одном проекте с основным приложением в секции #ifdef. По сбросу стартует загрузчик и проверяет наличие программы в FRAM, если есть заливает ее во флеш. Определил сегмент в XCL: -D_..X_FLASH_HUGE_END=21FFF -D_..X_BOOTSEC_SIZE=2000 -Z(CODE)BOOT_SEGMENT=(_..X_FLASH_HUGE_END-_..X_BOOTSEC_SIZE+1)-_..X_FLASH_HUGE_END Сам загрузчик: Код #pragma segment = "BOOT_SEGMENT" #pragma location="BOOT_SEGMENT"
#include <eeprom_driver.h> #include <sp_driver.h> #include <defines.h>
#define BOOT_F_CPU 2000000UL
........ // определение типов и констант для I2C
boot_TWI_Master_t twiMaster; // структура для работы с I2C uint8_t boot_sBuf[32];
// объявление функций для I2C __root bool boot_TWI_MasterWriteRead(boot_TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite, uint8_t bytesToRead) @ "BOOT_SEGMENT"; __root void boot_TWI_MasterInterruptHandler(boot_TWI_Master_t *twi) @ "BOOT_SEGMENT";
.........
__root void boot(void) @ "BOOT_SEGMENT"; // тело загрузчика __root void GoToApplication(void) @ "BOOT_SEGMENT"; // переход в приложение
__root void boot(void) @ "BOOT_SEGMENT" { boot_TWI_MasterInit(&twiMaster, // инициализирую I2C &TWIF, TWI_MASTER_INTLVL_HI_gc, BOOT_TWI_BAUDSETTING); PMIC.CTRL |= PMIC_HILVLEN_bm; boot_sBuf[0] = 0x00; // читаю из FRAM 6 байтов boot_sBuf[1] = 0x40; boot_TWI_MasterWriteRead(&twiMaster, 0xA0, &boot_sBuf[0], 2, 6);
while (twiMaster.status != boot_TWIM_STATUS_READY) // пишу и читаю пока надо { if ((TWIF.MASTER.STATUS & 0xCC) != 0x00) { boot_TWI_MasterInterruptHandler(&twiMaster); } } // в зависимости от результата что-то делаю ............ GoToApplication(); }
__root void GoToApplication(void) @ "BOOT_SEGMENT" { cli(); PMIC.CTRL = 0; SP_WaitForSPM(); SP_LockSPM(); EIND = 0x00; void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector. funcptr(); // Jump to Reset vector 0x0000 in Application Section. }
__root bool boot_TWI_MasterWriteRead(boot_TWI_Master_t *twi, uint8_t address, uint8_t *writeData, uint8_t bytesToWrite, uint8_t bytesToRead) @ "BOOT_SEGMENT" { /*Parameter sanity check. */ if (bytesToWrite > boot_TWIM_WRITE_BUFFER_SIZE) { return false; } if (bytesToRead > boot_TWIM_READ_BUFFER_SIZE) { return false; }
.......................... } Загрузчик стартует как надо, переход в тело работает. Теперь собственно в чем проблема: Инициализация I2C проходит нормально, регистры принимают нужное значение. При вызове boot_TWI_MasterWriteRead(...) смотрю в отладчике, а там параметр bytesToRead всегда равен 0. Пробовал убрать параметр address, тогда bytesToRead передается как надо. Т.е получается не может передать большое количество параметров. Но дальше все равно не работает чтение из FRAM. Пробовал вставлять этот кусок в основное тело приложения, там все работает хорошо. Мне кажется или что-то со стеком при работе в области загрузчика или не знаю. Помогите пожалуйста И еще: может проблема быть связана с __root, #pragma и т.д.? Может чего-то не хватает? Просто я в них не особо шарю...
|
|
|
|
|
 |
Ответов
|
Nov 13 2009, 16:27
|
Участник

Группа: Участник
Сообщений: 42
Регистрация: 8-11-07
Пользователь №: 32 165

|
Здравствуйте Впервые пишу будлоадер. (не судите строго) Пишу в 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)? Что будет делаться с теми переменами которые были в проге, какая была переписана другой (глобальные, внутренние ?)
|
|
|
|
|
Nov 13 2009, 22:23
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(D1ma @ Nov 13 2009, 18:27)  Тоесть, если есть прога то она запускается если нет то бутлоадер(думаю). Лучше специально заточенным фузом запускать всегда загрузчик. А уже он решит - отдавать управление программе или нет. Скрипт правильный. Цитата(D1ma @ Nov 13 2009, 18:27)  Код /*Body*/ //..... /* Jump to Reset vector 0x0000 in Application Section.*/ funcptr(); } В целом правильно, но я вместо этого после прошивки просто сбрасываю процессор собакой. Он рестартует, попадает в загрузчик, загрузчик (в __low_level_init) проверяет целостность приложения и отдает ему управление. Этот же код работает и при включении, то есть получается максимально быстрый запуск приложения при обычном включении - если надо запускать приложение, то не тратится время на исполнение всего стартапа загрузчика. Цитата(D1ma @ Nov 13 2009, 18:27)  Да, эта же прога должна и запускать бутлоадер думаю так Код void (*pBoot)( void ) = 0xf000; pBoot(); Правильно. У меня загрузчик определяет, что его вызвали из приложения по направлению одной из ног, которая штатно используется на вывод (при холодном старте все ноги настроены на ввод). Цитата(D1ma @ Nov 13 2009, 18:27)  Вопрос: В бутлоадера есть свои вектора прерываний по адресу 0xf000 и свой стартап , переменные… в проги свои. Как себя поведет, контролер, если выполнится стартап проги потом будлоадера потом снова проги и так дали? В какие прерывания будет попадать бут.. и прога (по адресу 0х0000 или 0хf000)? Что будет делаться с теми переменами которые были в проге, какая была переписана другой (глобальные, внутренние ?) Стартап на то и стартап, что подготавливает окружение для работы проги. То есть инициализирует указатель стека, переменные, настраивает периферию (в __low_level_init). Грамотная программа не должна полагаться на неинициализированные значения, а инициализированные будут подготовлены стартапом. Естественно, старые значения, оставшиеся от прги/загрузчика будут затерты. Если вам надо сохранять какие-то переменные - вынесите их в отдельный сегмент и на его месте в скрипте загрузчика зарезервируйте память. Для определения таких переменных вам понадобится квалификатор __no_init. Вектора вы переключаете сами - для этого есть специальный битик. P.S. В будущем не стоит встревать с отдельным вопросом в активную тему.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
Сообщений в этой теме
vitek101 Bootloader. Подскажите. Nov 11 2009, 08:53 KRS _root не надо писать у каждой функции!
достато... Nov 11 2009, 09:15 V_G Цитата(KRS @ Nov 11 2009, 19:15) А как вы... Nov 11 2009, 09:25  KRS Цитата(V_G @ Nov 11 2009, 12:25) Ну, и на... Nov 11 2009, 09:36 vitek101 А я тут и использую полинг. С прерываниями я так и... Nov 11 2009, 10:40 KRS примерно так
КодEXTERN boot
RSEG CSTACK:DA... Nov 11 2009, 11:25 vitek101 На всякий случай прошу прощения за возможно глупый... Nov 11 2009, 11:59 KRS Цитата(vitek101 @ Nov 11 2009, 14:59) На ... Nov 11 2009, 12:07 vitek101 Сделал так:
КодEXTERN boot
RSEG CSTACK:DAT... Nov 11 2009, 12:33 KRS Цитата(vitek101 @ Nov 11 2009, 15:33) Это... Nov 11 2009, 12:43 vitek101 Да, правильно
Но illegal effective address и ba... Nov 11 2009, 12:48 KRS А да про макрос забыл
Код//**********************... Nov 11 2009, 13:00 vitek101 А можно заменить
Код lda Z, SFB(NEAR_Z... Nov 11 2009, 13:51 KRS Цитата(vitek101 @ Nov 11 2009, 16:51) Все... Nov 11 2009, 14:24 V_G А фьюзы на запуск с bootloadera поставили? И на то... Nov 11 2009, 19:59 vitek101 Поставил. Стартует он откуда надо. У XMega только ... Nov 12 2009, 06:47 KRS Так у вас просто мешанина получилась, часть старта... Nov 12 2009, 10:42 vitek101 Разобраться конечно неплохо бы Nov 12 2009, 10:54 KRS А что за ошибки то возникают если библиотеку отклю... Nov 12 2009, 12:54 vitek101 В том то и дело, что я не могу ее отключить. В сво... Nov 12 2009, 14:16 KRS Цитата(vitek101 @ Nov 12 2009, 17:16) В т... Nov 12 2009, 15:22  vitek101 Цитата(KRS @ Nov 12 2009, 18:22) Так это ... Nov 13 2009, 05:10 MDD Не совсем в тему, но может будет полезно. Недавно ... Nov 12 2009, 16:04 KRS Цитата(D1ma @ Nov 13 2009, 19:27) Тоесть,... Nov 13 2009, 22:12 D1ma как написать свой стартап и ловлевелинит?
щас у ме... Nov 14 2009, 10:05 KRS Цитата(D1ma @ Nov 14 2009, 13:05) как нап... Nov 14 2009, 11:40 Сергей Борщ Цитата(D1ma @ Nov 14 2009, 12:05) как нап... Nov 14 2009, 13:41 vitek101 Почему может постоянно забиваться CSTACK?
Читаю за... Nov 17 2009, 13:41
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|