Написал загрузчик для 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 и т.д.? Может чего-то не хватает? Просто я в них не особо шарю...