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

Проблема С Бутлоадером Для Atmega8


KushlaVR

Рекомендуемые сообщения

Вопрос банальный: как из бутлоадера перейти в приложение?

Написал бутлоадер на AVR Studio (C++) Контроллер Atmega8a

Не пойму как мне из бутлоадера попасть в главное приложение.

В протусе - все работает... В реале - нет

Вариант 1:

asm("JMP 0x0000")

Не работает, при компиляции пишет - illegal op code for mcu atmega8a

Вариант 2:

asm("RJMP 0x0000")

не ругается но и не работает...

Вариант 3:

void (* appStart) = 0x0000;
void main()
{
while(ok)
{
...
};
appStart();
}

Работает только в протусе.... Прошил лоадер в контроллер. Запустил, залил приложение, после заливки - прошивку прочитал, сравнил с оригиналом, потом в EEPROM (по адресу 6) сталю байт = 0 (по дефолту та FF), потом ок = 0, и тут должно начатся приложение, но попадпю снова в бутлоадер....

Приложение даже не запускается, потому, что первая строка приложения : eeprom_write_byte(0,0x55);

Когда читаю eeprom - то по адресу 0 - стоит 0xFF (пусто)....

Кто делал бутлоадер, помогите пожалуйста...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

объявляем

void (*funcptr)( void ) = 0x0000;

вызываем

funcptr();

а еще можно так #define RESET() {asm("ldi r30,0"); asm("ldi r31,0"); asm("ijmp");}

Вариант void (*funcptr)( void ) = 0x0000; - ето вариант №3 (в посте я просто допустил опечатку)...

#define RESET() - чтото новенькое, буду пробовать

Спасибо.

И еще вопрос. А обязательно через #define, можно просто гдето в коде: asm("ldi r30,0"); asm("ldi r31,0"); asm("ijmp"); ???

На первый взгляд можно, но вдруг там есть каойто скрытый смысл....

Изменено пользователем KushlaVR
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

А полученный ассемблерный код не смотрели, может компилятор чудит?

можно попробовать asm volatile("rjmp 0x0000");

Если обе части, и лоадер и программа, на Сях, может какие-то регистры неправильно настраиваются, или не отключаются прерывания, или ресет происходит.

Писал на ассемблере, там компилятор не самодействует, и rjmp 0x0000 выполняется гарантированно. Хотя в некоторых случаях программа ведет себя странно, скорее это из-за тех же прерываний.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Не проще было выложить весь код? Да и стоит ли придумывать что-то, если у Atmel уже есть пример загрузчика на С (AVR109). Переход в рабочую программу там делается так:

#define _ENABLE_RWW_SECTION() __DataToR0ByteToSPMCR_SPM( 0x00, 0x11 )
#define _WAIT_FOR_SPM() while( SPMCR_REG & (1<<SPMEN) );
...
/* Initialization */   
void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector
....
else
{
   _WAIT_FOR_SPM();	   
   _ENABLE_RWW_SECTION();
   funcptr(); // Jump to Reset vector 0x0000 in Application Section.
}

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

Не проще было выложить весь код? Да и стоит ли придумывать что-то, если у Atmel уже есть пример загрузчика на С (AVR109). Переход в рабочую программу там делается так:

#define _ENABLE_RWW_SECTION() __DataToR0ByteToSPMCR_SPM( 0x00, 0x11 )
#define _WAIT_FOR_SPM() while( SPMCR_REG & (1<<SPMEN) );
...
/* Initialization */
void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector
....
else
{
_WAIT_FOR_SPM();	
_ENABLE_RWW_SECTION();
funcptr(); // Jump to Reset vector 0x0000 in Application Section.
}

Спасибо.

Нужно ли весь исходник... незнаю... там куча всего...

Вот фрагмент побольше


void (*StartApp)( void ) = 0x0000;

typedef struct{
unsigned char address;
word UpdateDate;//Дата прошивки починаючи з 2000 року
word CRC;
unsigned char BootMode;//0 - Нормальний режим; 1 - Програмна прошивка; 2 - Неправльне CRC програми; 255 - Початкова прошивка
unsigned char ShowAddresonstartup;//0 - не виводити; інакше виводити
} Signature;
Signature sng;

int main(void)
{
LastAddress = 0xFFFF;
tmp_buffer_address = 0xFFFF;
PaketLen=0;

cli();//Заборона переривань (якщо ми прийшли сюда з головної програми)
//Наступні два присвоєння повинні бути виконані за 4 цикла (між ними нічого не вставляти)
GICR = (1<<IVCE);//Дозволяєм зміну векторів переривань (IVCE - interrupt vrctor change enable)
GICR = (1<<IVSEL);//Переносимо вектор переривань в адрес BootLoader'a (IVSEL - Interrupt Vector Select)

//eeprom_write_byte((uint8_t*)1, 1);//Примусовий запис адреси пристрою в флешку

eeprom_read_block(&sng, (void *)1, sizeof(Signature));//sng - Налаштування

DDRB=0b00111111;
DDRC=0b11000000;
DDRD=0b11111100;
PORTD=(1<<0)|(1<<1);
PORTC=0b11010000;


OCR1A = (unsigned int)((F_CPU / 64UL) - 1UL);
TIMSK |= 1 << OCIE1A;
TCCR1B |= (1 << CS12); // 256 (Скидаєм пакет раз в секунду при 8MHz)

mb_Init(9600);
Beep();
sei();


unsigned char Step=0, Mode=0;
unsigned int Counter = 999;
while (((PINC & 0b00010000)==0b00000000)|(sng.BootMode!=0))
{
Counter++;
if (Counter==1000)
{
if (Mode==0){BL()/*вивід букв bL на індикатор*/;}else{Address()/*Вивід адреси прстрою на індикатор*/;};
Mode=!Mode;
Counter=0;
};
Step++;
if (Step==3) {Step = 0;};
DisplayDigit(Step,dec[step]);//Динамічна індикація
_delay_ms(1);
};
//asm("rjmp 0;");//не робить
StartApp();//тоже не робить...

}

А где взять исходники AVR109. Хочу посмотреть пример полностю.

Спасибо

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

http://www.atmel.com...x?tab=documents - документация для ATmega8.

И http://www.atmel.com/images/AVR109.zip нужный вам архив.

Спасибо!!!

Буду изучать дальше...

По результатам отпишусь.

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

Пишу о результатах.

Все 3 метода работаю ))) + метод "#define Reset" тоже работает.

Как оказалось проблема заключалась не в бутлоадере, а в приложении.

На плате предусмотрен конроль входного напряжения (до стабилизатора +12В). Реализован ка простой делитель на резисторах. При старте приложения Порт делался OUTPUT (DDRC=0xFF; PORTC = 0xFF) и происходило толи короткое замыкание, толе еще чего, что приводило к Ресету контроллера. После сборса, снова бутлоадер запускается...

Теперь все ОК.

Изменено пользователем KushlaVR
Ссылка на комментарий
Поделиться на другие сайты

дык, а я в посте 4 сразу сказал что это работает, т.к. чудес не бывает. :)

Да оно работало. Все верно. Но так как никакого отладочного инструмента, кроме тестера, у меня нет, создавалось впечетление, что лоадер переходин не в "0х0000" а в "0х1800".

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

  • 2 недели спустя...

Вопрос банальный: как из бутлоадера перейти в приложение?

Написал бутлоадер на AVR Studio (C++) Контроллер Atmega8a

Не пойму как мне из бутлоадера попасть в главное приложение.

В протусе - все работает... В реале - нет

Вариант 1:

asm("JMP 0x0000")

Не работает, при компиляции пишет - illegal op code for mcu atmega8a

Вариант 2:

asm("RJMP 0x0000")

не ругается но и не работает...

Вариант 3:

void (* appStart) = 0x0000;
void main()
{
while(ok)
{
...
};
appStart();
}

Работает только в протусе....

вариант 4

clr r30

clr r31

ijmp

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...