|
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 12 2009, 06:47
|

Участник

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

|
Поставил. Стартует он откуда надо. У XMega только одна область для загрузчика, 8 Кб. Что-то не получается у меня отключить стандартную библиотеку. Если ее выкинуть, вылезает толпа разных ошибок. А если взять и в стандартном STARTUPе заменить строки Код RSEG CODE:CODE:NOROOT(1) на Код RSEG BOОT_ENTRY:CODE:NOROOT(1) Может так сработает? И main на boot Работает!!! В общем поменял CODE на BOOT_ENTRY, а main оставил. Теперь следующая картина: Стартует с загрузчика, но без STARTUPа. Праметр bytesToRead так и не работает (см. первый пост). Но попробовал опять убрать address и все заработало. Стартап появляет в отладчике в начале основной программы. Непонятно вылезут дальше косяки какие-нибудь или нет, т.к. проблема с address так и не решена. Спасибо за помощь! Теперь стартап такой: Код ;---------------------------------------------------------------------------- ; 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
;---------------------------------------------------------------------------- ;
|
|
|
|
Сообщений в этой теме
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 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 D1ma Здравствуйте
Впервые пишу будлоадер. (не судите ст... Nov 13 2009, 16:27 KRS Цитата(D1ma @ Nov 13 2009, 19:27) Тоесть,... Nov 13 2009, 22:12 Сергей Борщ Цитата(D1ma @ Nov 13 2009, 18:27) Тоесть,... Nov 13 2009, 22:23 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
|
|
|