реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Не выходит одолеть прерывания в Bootloader'е
Sirko
сообщение Apr 11 2011, 00:06
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



За основу было взято вот Это. Вернее хочу использовать Makefile от сюда.
CODE
#include <stdint.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#if defined(BOOTLOADERHASNOVECTORS)
#warning "This Bootloader does not link interrupt vectors - see makefile"
/* make the linker happy - it wants to see __vector_default */
// void __vector_default(void) { ; }

void __vector_default(void) { ; }
#endif

volatile unsigned char b = 0;

ISR(TIMER0_COMP_vect){
b = 1;
}

ISR(TIMER0_OVF_vect){
b = 1;
}

int main(void){

TCCR0 = _BV(CS02) | _BV(CS00);
OCR0 = 100;
TIMSK |= _BV(OCIE0) | _BV(TOIE0);
MCUCR |= (1<<IVCE); // Enable change of Interrupt Vectors
MCUCR |= (1<<IVSEL); // Move interrupts to Boot Flash section


DDRE |= _BV(PE7);
unsigned long x = 0;
while(1){
asm("sei");
x = (cool.gif ? (1UL<<15) : (1UL<<18);
while(--x){asm("nop");}
PORTE ^= _BV(PE7);
}
return 0;
}
Тест не мудреный, Если прерывания запретить, то лампа моргает редко. Если разрешить, - то почащще. А в моем случае, при разрешении прерывания она не горит вовсе. Вероятно при наступлении прерывания происходит улет в ???.
Проц - Mega128, компилятор - WinAVR-20100110.
LDFLAGS += -Wl,--section-start=.text=0x1E000, наверное
НЕХ на выходе начинается вот так:
:020000021000EC
:10E0000011241FBECFEFD0E1DEBFCDBF11E0A0E0F5
Фьюзы настроены на 4кБ, addr-$F000

Что где править, ума не приложу.
А проект, если понадобится прилагаю.
Прикрепленный файл  Bootloader.zip ( 31.25 килобайт ) Кол-во скачиваний: 112


Сообщение отредактировал Sirko - Apr 11 2011, 22:02
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Vetal-Soft
сообщение Apr 11 2011, 02:41
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 16-06-05
Пользователь №: 6 074



Скорее всего заморочка с измерением памяти программ: В GCC - байты, у Atmel - слова.
Настройте фъюзы на 2k.

Сообщение отредактировал Vetal-Soft - Apr 11 2011, 10:30
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 11 2011, 21:57
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Скорее всего...

Скорее всего. Кто бы носом ткнул.

Цитата
Настройте фъюзы на 2k

Прикрепленное изображение


Полученый на выходе HEX:
:020000021000EC
:10F0000011241FBECFEFD0E1DEBFCDBF11E0A0E0E5
:10F01000B1E0E0EDF0EF01E00BBF02C007900D9210
:10F02000A030B107D9F711E0A0E0B1E001C01D9216
:10F03000A130B107E1F70E9440F80C9466F80C94F7
:10F0400021F808951F920F920FB60F9211248F93FB
:10F0500081E0809300018F910F900FBE0F901F9061
:10F0600018951F920F920FB60F9211248F9381E083
:10F07000809300018F910F900FBE0F901F901895F5
:10F0800085E083BF84E681BF87B7836087BF85B78C
:10F09000816085BF85B7826085BF179A789480911B
:10F0A0000001882329F480E090E0A4E0B0E006C0ED
:10F0B00080E090E8A0E0B0E001C000000197A10965
:10F0C000B109D9F783B1805883B9E8CFF894FFCF5D
:040000031000F000F9
:00000001FF

т.е. 0x1F000 байт / 2 = 0xF800 слов, что вроде сходится с картинкой программатора.
Прерывания разрешил, страницу векторов тоже поменял, какого рожна ему нужно?



Кстати, за одно хочу уточнить такой момент:
:02 0000 02 1000 EC
Если здесь двойка, значит последующее за ней двухбайтовое значение отражает: на сколько последующие данные будут сдвинуты относительно их текущего адреса. Если значение - 0000, значит заполняется первая половина флэша (mega128); если 1000 - значит вторая половина; если 2000 - значит сегмент будет 128 - 192КБ (в более емких процах).
Поправьте, если я ошибаюсь. И еще, для EEPROM какие то обрамления секций будут в хексе, или разница только в расширении? Если в приведенной строке вместо 02 будет 03, значит последующее значение за ней - это адрес стартапа программы, и на эту строку можно забить при парсинге.

Go to the top of the page
 
+Quote Post
Vetal-Soft
сообщение Apr 12 2011, 08:36
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 16-06-05
Пользователь №: 6 074



У Вас в makefile:
Код
#/* Select Boot Size in Words (select one, comment out the others) */
## NO! BOOTSIZE=128
## NO! BOOTSIZE=256
## BOOTSIZE=512
## BOOTSIZE=1024
BOOTSIZE=2048
## BOOTSIZE=4096


2 кБайта, а в программаторе 2 кСлова
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 12 2011, 13:00
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Sirko @ Apr 11 2011, 03:06) *
LDFLAGS += -Wl,--section-start=.text=0x1E000, наверное

0x1E000 - это начало 8kbyte'ой boot секции.


Для примера кусочек xml из IAR'а
/* Code (flash) segments 8KB BOOT section */
-D_..X_INTVEC_SIZE=8C /* 4 bytes * 35 vectors */
-D_..BOOT_START=1E000
-D_..BOOT_INTVEC_END=1E08C
-D_..BOOT_FLASH_TEND=1E0FF
-D_..BOOT_FLASH_NEND=1FFFF /* End of near BOOT flash memory */
-D_..BOOT_FLASH_END=1FFFF /* End of BOOT flash memory */
Go to the top of the page
 
+Quote Post
alag57
сообщение Apr 12 2011, 15:01
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355



Попробуйте так:
Код
    //MCUCR = (1<<IVCE);        // Enable change of Interrupt Vectors
    //MCUCR = (1<<IVSEL);        // Move interrupts to Boot Flash section
    asm("ldi r24, 1");
    asm("out 0x35, r24");
    asm("ldi r24, 2");
    asm("out 0x35, r24");

Похоже вы не укладываетесь в отведенные 4 такта на изменение начала таблицы векторов.
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 12 2011, 18:29
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Похоже вы не укладываетесь в... Попробуйте так:

Обратил внимание, что в "Попробуйте так:" в регистре MCUCR сначала выставляется флаг IVCE, а в последствии вместо него флаг IVCEL. В моем коде эти биты в конечном итоге взводились оба.
Исправил код исходя из совета:

MCUCR = (1<<IVCE); // Enable change of Interrupt Vectors
MCUCR = (1<<IVSEL); // Move interrupts to Boot Flash section

Лампа заморгала, - заморгала с частотой отражающей отсутствие деятельности обработчиков прерывания.
Так же само ведет себя и мой код, если закоментировать SEI.

Стало быть в отведенные 4 такта я укладываюсь, прерывания таки генерятся и теоретически обрабатываются. Только вот что на самом деле творится в момент перехода к обработчику, - неясно. Лампа не горит вовсе.
Так, что если это не опечатка, то alag57 пусть возьмет это на заметку.

Цитата
0x1E000 - это начало 8kbyte'ой boot секции

Вырезка из Маке
Код
## BOOTSIZE=1024
BOOTSIZE=2048
## BOOTSIZE=4096
.
.
.
ifeq ($(BOOTSIZE), 2048)
MT_BOOTLOADER_ADDRESS = 0x1F000
endif

0x1F000 / 2 = 0xF800 т.е. два "киловорда до финиша", во всяком случае в фьюзах программатора фигурирует это значение

Вырезка из HEX
:020000021000EC
:10F0000011241FBECFEFD0E1DEBFCDBF11E0A0E0E5
:10F01000B1E0ECECF0EF01E00BBF02C007900D9205
Вроде как сходится
Go to the top of the page
 
+Quote Post
SysRq
сообщение Apr 12 2011, 20:10
Сообщение #8


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Sirko @ Apr 12 2011, 22:29) *
Лампа заморгала, - заморгала с частотой отражающей отсутствие деятельности обработчиков прерывания.
И правильно, ибо у вас таблицы векторов-то нету:
Цитата
# /* Select if bootloader should include the inverrupt-vectors
# when selecting 'no' here, the bootloader must not use
# any interrupts and the modified linker-scripts are used. */
##BOOTINTVEC=yes
BOOTINTVEC=no

Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 12 2011, 21:18
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



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

Попробовал запустить HEX в отладчике студии. Курсор стартует с адреса 0x00. Ну это скорее всего глюк студии. Переставляю курсор на 0xF800. Стартую. Выставляю флажок TOV0 и наблюдаю перелет к 0xF020. Если учесть, что номер вектора перепелнения T0 - №16 тобишь 0x20, значит таблица начинается с 0xF000. А мне нужно 0xF800. Это конечно тоже можно списать на отладчик, но железо по прежнему мертво.

Прилагаю дизасемблер, может пригодится.
CODE
+0000F7FD: FFFF ??? Data or unknown opcode
+0000F7FE: FFFF ??? Data or unknown opcode
+0000F7FF: FFFF ??? Data or unknown opcode

+0000F800: 940CF846 JMP 0x0000F846 Jump
+0000F802: 940CF865 JMP 0x0000F865 Jump
+0000F804: 940CF865 JMP 0x0000F865 Jump
+0000F806: 940CF865 JMP 0x0000F865 Jump
+0000F808: 940CF865 JMP 0x0000F865 Jump
+0000F80A: 940CF865 JMP 0x0000F865 Jump
+0000F80C: 940CF865 JMP 0x0000F865 Jump
+0000F80E: 940CF865 JMP 0x0000F865 Jump
+0000F810: 940CF865 JMP 0x0000F865 Jump
+0000F812: 940CF865 JMP 0x0000F865 Jump
+0000F814: 940CF865 JMP 0x0000F865 Jump
+0000F816: 940CF865 JMP 0x0000F865 Jump
+0000F818: 940CF865 JMP 0x0000F865 Jump
+0000F81A: 940CF865 JMP 0x0000F865 Jump
+0000F81C: 940CF865 JMP 0x0000F865 Jump
+0000F81E: 940CF867 JMP 0x0000F867 Jump <---- Вроде, как оно
+0000F820: 940CF876 JMP 0x0000F876 Jump <----
+0000F822: 940CF865 JMP 0x0000F865 Jump
+0000F824: 940CF865 JMP 0x0000F865 Jump
+0000F826: 940CF865 JMP 0x0000F865 Jump
+0000F828: 940CF865 JMP 0x0000F865 Jump
+0000F82A: 940CF865 JMP 0x0000F865 Jump
+0000F82C: 940CF865 JMP 0x0000F865 Jump
+0000F82E: 940CF865 JMP 0x0000F865 Jump
+0000F830: 940CF865 JMP 0x0000F865 Jump
+0000F832: 940CF865 JMP 0x0000F865 Jump
+0000F834: 940CF865 JMP 0x0000F865 Jump
+0000F836: 940CF865 JMP 0x0000F865 Jump
+0000F838: 940CF865 JMP 0x0000F865 Jump
+0000F83A: 940CF865 JMP 0x0000F865 Jump
+0000F83C: 940CF865 JMP 0x0000F865 Jump
+0000F83E: 940CF865 JMP 0x0000F865 Jump
+0000F840: 940CF865 JMP 0x0000F865 Jump
+0000F842: 940CF865 JMP 0x0000F865 Jump
+0000F844: 940CF865 JMP 0x0000F865 Jump
+0000F846: 2411 CLR R1 Clear Register
+0000F847: BE1F OUT 0x3F,R1 Out to I/O location
+0000F848: EFCF SER R28 Set Register
+0000F849: E1D0 LDI R29,0x10 Load immediate
+0000F84A: BFDE OUT 0x3E,R29 Out to I/O location
+0000F84B: BFCD OUT 0x3D,R28 Out to I/O location
+0000F84C: E011 LDI R17,0x01 Load immediate
+0000F84D: E0A0 LDI R26,0x00 Load immediate
+0000F84E: E0B1 LDI R27,0x01 Load immediate
+0000F84F: E5E8 LDI R30,0x58 Load immediate
+0000F850: EFF1 LDI R31,0xF1 Load immediate
+0000F851: E001 LDI R16,0x01 Load immediate
+0000F852: BF0B OUT 0x3B,R16 Out to I/O location
+0000F853: C002 RJMP PC+0x0003 Relative jump
+0000F854: 9007 ELPM R0,Z+ Extended load program memory and postincrement
+0000F855: 920D ST X+,R0 Store indirect and postincrement
+0000F856: 30A0 CPI R26,0x00 Compare with immediate
+0000F857: 07B1 CPC R27,R17 Compare with carry
+0000F858: F7D9 BRNE PC-0x04 Branch if not equal
+0000F859: E011 LDI R17,0x01 Load immediate
+0000F85A: E0A0 LDI R26,0x00 Load immediate
+0000F85B: E0B1 LDI R27,0x01 Load immediate
+0000F85C: C001 RJMP PC+0x0002 Relative jump
+0000F85D: 921D ST X+,R1 Store indirect and postincrement
+0000F85E: 30A1 CPI R26,0x01 Compare with immediate
+0000F85F: 07B1 CPC R27,R17 Compare with carry
+0000F860: F7E1 BRNE PC-0x03 Branch if not equal
+0000F861: 940EF885 CALL 0x0000F885 Call subroutine
+0000F863: 940CF8AA JMP 0x0000F8AA Jump
+0000F865: 940CF800 JMP 0x0000F800 Jump
+0000F867: 921F PUSH R1 Push register on stack
+0000F868: 920F PUSH R0 Push register on stack
+0000F869: B60F IN R0,0x3F In from I/O location
+0000F86A: 920F PUSH R0 Push register on stack
+0000F86B: 2411 CLR R1 Clear Register
+0000F86C: 938F PUSH R24 Push register on stack
+0000F86D: E081 LDI R24,0x01 Load immediate
+0000F86E: 93800100 STS 0x0100,R24 Store direct to data space
+0000F870: 918F POP R24 Pop register from stack
+0000F871: 900F POP R0 Pop register from stack
+0000F872: BE0F OUT 0x3F,R0 Out to I/O location
+0000F873: 900F POP R0 Pop register from stack
+0000F874: 901F POP R1 Pop register from stack
+0000F875: 9518 RETI Interrupt return
+0000F876: 921F PUSH R1 Push register on stack
+0000F877: 920F PUSH R0 Push register on stack
+0000F878: B60F IN R0,0x3F In from I/O location
+0000F879: 920F PUSH R0 Push register on stack
+0000F87A: 2411 CLR R1 Clear Register
+0000F87B: 938F PUSH R24 Push register on stack
+0000F87C: E081 LDI R24,0x01 Load immediate
+0000F87D: 93800100 STS 0x0100,R24 Store direct to data space
+0000F87F: 918F POP R24 Pop register from stack
+0000F880: 900F POP R0 Pop register from stack
+0000F881: BE0F OUT 0x3F,R0 Out to I/O location
+0000F882: 900F POP R0 Pop register from stack
+0000F883: 901F POP R1 Pop register from stack
+0000F884: 9518 RETI Interrupt return
+0000F885: E085 LDI R24,0x05 Load immediate
+0000F886: BF83 OUT 0x33,R24 Out to I/O location
+0000F887: E684 LDI R24,0x64 Load immediate
+0000F888: BF81 OUT 0x31,R24 Out to I/O location
+0000F889: B787 IN R24,0x37 In from I/O location
+0000F88A: 6083 ORI R24,0x03 Logical OR with immediate
+0000F88B: BF87 OUT 0x37,R24 Out to I/O location
+0000F88C: E081 LDI R24,0x01 Load immediate
+0000F88D: BF85 OUT 0x35,R24 Out to I/O location
+0000F88E: B785 IN R24,0x35 In from I/O location
+0000F88F: 6082 ORI R24,0x02 Logical OR with immediate
+0000F890: BF85 OUT 0x35,R24 Out to I/O location
+0000F891: 9A17 SBI 0x02,7 Set bit in I/O register
+0000F892: 9478 SEI Global Interrupt Enable
+0000F893: 91800100 LDS R24,0x0100 Load direct from data space
+0000F895: 2388 TST R24 Test for Zero or Minus
+0000F896: F429 BRNE PC+0x06 Branch if not equal
+0000F897: E080 LDI R24,0x00 Load immediate
+0000F898: E090 LDI R25,0x00 Load immediate
+0000F899: E0A4 LDI R26,0x04 Load immediate
+0000F89A: E0B0 LDI R27,0x00 Load immediate
+0000F89B: C006 RJMP PC+0x0007 Relative jump
+0000F89C: E080 LDI R24,0x00 Load immediate
+0000F89D: E890 LDI R25,0x80 Load immediate
+0000F89E: E0A0 LDI R26,0x00 Load immediate
+0000F89F: E0B0 LDI R27,0x00 Load immediate
+0000F8A0: C001 RJMP PC+0x0002 Relative jump
+0000F8A1: 0000 NOP No operation
+0000F8A2: 9701 SBIW R24,0x01 Subtract immediate from word
+0000F8A3: 09A1 SBC R26,R1 Subtract with carry
+0000F8A4: 09B1 SBC R27,R1 Subtract with carry
+0000F8A5: F7D9 BRNE PC-0x04 Branch if not equal
+0000F8A6: B183 IN R24,0x03 In from I/O location
+0000F8A7: 5880 SUBI R24,0x80 Subtract immediate
+0000F8A8: B983 OUT 0x03,R24 Out to I/O location
+0000F8A9: CFE9 RJMP PC-0x0016 Relative jump
+0000F8AA: 94F8 CLI Global Interrupt Disable
+0000F8AB: CFFF RJMP PC-0x0000 Relative jump

+0000F86C: FFFF ??? Data or unknown opcode
+0000F86D: FFFF ??? Data or unknown opcode
+0000F86E: FFFF ??? Data or unknown opcode


Кстати, обратил внимание на HEX
:020000021000EC
:10F000000C9446F80C9465F80C9465F80C9465F82B
:10F010000C9465F80C9465F80C9465F80C9465F8FC
:10F020000C9465F80C9465F80C9465F80C9465F8EC
:10F030000C9465F80C9465F80C9465F80C9467F8DA
:10F040000C9476F80C9465F80C9465F80C9465F8BB
:10F050000C9465F80C9465F80C9465F80C9465F8BC
:10F060000C9465F80C9465F80C9465F80C9465F8AC
:10F070000C9465F80C9465F80C9465F80C9465F89C
:10F080000C9465F80C9465F80C9465F811241FBE77
:10F09000CFEFD0E1DEBFCDBF11E0A0E0B1E0E8E509
:10F0A000F1EF01E00BBF02C007900D92A030B10755
:10F0B000D9F711E0A0E0B1E001C01D92A130B10785
:10F0C000E1F70E9485F80C94AAF80C9400F81F92BE
:10F0D0000F920FB60F9211248F9381E0809300015D
:10F0E0008F910F900FBE0F901F9018951F920F9247
:10F0F0000FB60F9211248F9381E0809300018F91BE
:10F100000F900FBE0F901F90189585E083BF84E687
:10F1100081BF87B7836087BF81E085BF85B7826085
:10F1200085BF179A789480910001882329F480E0A4
:10F1300090E0A4E0B0E006C080E090E8A0E0B0E09D
:10F1400001C000000197A109B109D9F783B1805826
:08F1500083B9E9CFF894FFCF69
:040000031000F000F9
:00000001FF

Если я правильно понял, то здесь явно указано: стартовать с 0x1F000 т.е. 0xF800 слов. Значит глюк курсора это глюк отладчика.

Сообщение отредактировал IgorKossak - Apr 13 2011, 06:46
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
SysRq
сообщение Apr 12 2011, 21:23
Сообщение #10


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата
1. Write the Interrupt Vector Change Enable (IVCE) bit to one.
2. Within four cycles, write the desired value to IVSEL while writing a zero to IVCE.


PS: симулятор AVRStudio настройте, в опции его наведайтесь, - он умеет стартовать с секции загрузчика.
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 12 2011, 21:52
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
1. Write the Interrupt Vector Change Enable (IVCE) bit to one.
2. Within four cycles, write the desired value to IVSEL while writing a zero to IVCE.


Огромнейшее спасибо, вроде как ОНО. 08.gif

По поводу
Цитата
если это не опечатка, то alag57 пусть...
простите, беру свои слова обратно.



Go to the top of the page
 
+Quote Post
alag57
сообщение Apr 13 2011, 06:22
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355



Цитата
простите, беру свои слова обратно.

Да все нормально.
Код
+0000F88C:   E081        LDI       R24,0x01       Load immediate
+0000F88D:   BF85        OUT       0x35,R24       Out to I/O location
+0000F88E:   B785        IN        R24,0x35       In from I/O location
+0000F88F:   6082        ORI       R24,0x02       Logical OR with immediate
+0000F890:   BF85        OUT       0x35,R24       Out to I/O location

Вот как это происходит. Я специально привел инициализацию на ассемблере.
BOOTINTVEC=no в майкфайле я конечно же исправил, забыл напомнить.
Цитата
он умеет стартовать с секции загрузчика

Не получилось у меня, стартует с адреса 0х00007800. Ну да не помешало sm.gif

Сообщение отредактировал alag57 - Apr 13 2011, 06:26
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 14 2011, 22:20
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Добрался - таки я до загрузчика и, пользуясь случаем, решил немного расписать последовательность.
Думаю кому-нибудь вроде меня пригодится для пинка.

Значит так, лезем сюда, забираем вот это.
Кстати, спасибо DI HALT за то, что "озвучил" этот bootloader на родном языке.

Так вот, из всего этого мне понадобились makefile и папка со скриптами. В makefile необходимо: выбрать тип проца, выбрать размер загрузчика, разрешить прерывания, ну и вроде бы все. Дальше - творческая работа.
Чуть не забыл, после правки makefile необходимо выполнить Rebild All, иначе изменения не производятся.

Для примера приведу исходник демо-моргалки, которая при включении моргает десять раз с частотой 1Гц, затем прошивает основную программу, после чего передает ей управление. В задачу основной программы входит моргание сигнала "SOS".

CODE
#include <avr/io.h>
#include <avr/boot.h>
#include <avr/interrupt.h>

uint8_t Data[816] = { // Это бинарник основной (демо) программы, которую необходимо прошить
0x0C, 0x94, 0x46, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x67, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,
0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00,

0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x0C, 0x94, 0x65, 0x00, 0x11, 0x24, 0x1F, 0xBE,
0xCF, 0xEF, 0xD0, 0xE1, 0xDE, 0xBF, 0xCD, 0xBF, 0x11, 0xE0, 0xA0, 0xE0, 0xB1, 0xE0, 0xE0, 0xE3,
0xF3, 0xE0, 0x00, 0xE0, 0x0B, 0xBF, 0x02, 0xC0, 0x07, 0x90, 0x0D, 0x92, 0xA0, 0x30, 0xB1, 0x07,
0xD9, 0xF7, 0x11, 0xE0, 0xA0, 0xE0, 0xB1, 0xE0, 0x01, 0xC0, 0x1D, 0x92, 0xA1, 0x30, 0xB1, 0x07,
0xE1, 0xF7, 0x0E, 0x94, 0x82, 0x00, 0x0C, 0x94, 0x96, 0x01, 0x0C, 0x94, 0x00, 0x00, 0x1F, 0x92,
0x0F, 0x92, 0x0F, 0xB6, 0x0F, 0x92, 0x11, 0x24, 0x8F, 0x93, 0xDF, 0x93, 0xCF, 0x93, 0xCD, 0xB7,
0xDE, 0xB7, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0x29, 0xF0, 0x80, 0x91, 0x00, 0x01, 0x81, 0x50,
0x80, 0x93, 0x00, 0x01, 0xCF, 0x91, 0xDF, 0x91, 0x8F, 0x91, 0x0F, 0x90, 0x0F, 0xBE, 0x0F, 0x90,

0x1F, 0x90, 0x18, 0x95, 0xDF, 0x93, 0xCF, 0x93, 0xCD, 0xB7, 0xDE, 0xB7, 0xEE, 0xE4, 0xF0, 0xE0,
0x81, 0xE0, 0x80, 0x83, 0xA7, 0xE5, 0xB0, 0xE0, 0xE7, 0xE5, 0xF0, 0xE0, 0x80, 0x81, 0x84, 0x60,
0x8C, 0x93, 0xA2, 0xE2, 0xB0, 0xE0, 0xE2, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,
0x78, 0x94, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,
0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2,
0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x8F, 0x77, 0x8C, 0x93, 0x82, 0xE3, 0x80, 0x93,
0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2,
0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93, 0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91,

0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81,
0x8F, 0x77, 0x8C, 0x93, 0x82, 0xE3, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23,
0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,
0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2,
0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x8F, 0x77, 0x8C, 0x93, 0x84, 0xE6, 0x80, 0x93,
0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2,
0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93, 0x86, 0xE4, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91,
0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81,

0x8F, 0x77, 0x8C, 0x93, 0x88, 0xE2, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23,
0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,
0x86, 0xE4, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2,
0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x8F, 0x77, 0x8C, 0x93, 0x88, 0xE2, 0x80, 0x93,
0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2,
0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93, 0x86, 0xE4, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91,
0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81,
0x8F, 0x77, 0x8C, 0x93, 0x84, 0xE6, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23,

0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,
0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2,
0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x8F, 0x77, 0x8C, 0x93, 0x82, 0xE3, 0x80, 0x93,
0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2,
0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93, 0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91,
0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81,
0x8F, 0x77, 0x8C, 0x93, 0x82, 0xE3, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23,
0xE1, 0xF7, 0xA3, 0xE2, 0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x80, 0x68, 0x8C, 0x93,

0x84, 0xE1, 0x80, 0x93, 0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0xA3, 0xE2,
0xB0, 0xE0, 0xE3, 0xE2, 0xF0, 0xE0, 0x80, 0x81, 0x8F, 0x77, 0x8C, 0x93, 0x8A, 0xEF, 0x80, 0x93,
0x00, 0x01, 0x80, 0x91, 0x00, 0x01, 0x88, 0x23, 0xE1, 0xF7, 0x03, 0xCF, 0xF8, 0x94, 0xFF, 0xCF
};


// Функция writeFlashPage записывает одну страницу флэш,
// принимает: номер записываемой страницы
// размер записываемых данных (в байтах)
// адрес, откуда брать данные для записи

void writeFlashPage(uint8_t number, uint16_t size, uint8_t* pData){
uint32_t pagestart = number * SPM_PAGESIZE;
uint32_t baddr = pagestart;
uint16_t data;
uint8_t *tmp = pData;

do{
data = *tmp++;
data |= *tmp++ << 8;
boot_page_fill(baddr, data); // Заполнить буфер СЛОВАМИ данных

baddr += 2; // Перейти к следующему слову в памяти
size -= 2; //
}while(size); // Выполнять, пока не достигнут конец буфера

boot_page_write(pagestart); // Записать заполненный буфер во флеш
boot_spm_busy_wait(); // Дождаться окончания выполнения этой операции
boot_rww_enable(); // Разрешить доступ к секции RWW

return;
}

volatile uint8_t time = 0;

ISR(TIMER1_OVF_vect){ // Обработчик прерывания таймера
if(time)
--time;
}

void main(void){

TCCR1B = _BV(CS10); // clk
TIMSK |= _BV(TOIE1); // Разрешить прерывание по переполнению
MCUCR = (1<<IVCE); // Разрешить изменение положения таблицы прерываний
MCUCR = (1<<IVSEL); // Изменить положение таблицы
DDRE |= _BV(PE7); // Эта нога будет "дергаться"
asm("sei");

for(uint8_t i=0; i<20; ++i){ // Поморгать лампой десять раз
PORTE ^= _BV(PE7);
time = 100; // Задать время паузы
while(time); // Дождаться, пока таймер T1 обнулит time
}

// Далее начинается непосредственно перепрошивка контроллера
// В данном случае используется Mega128, размер страницы которой 256 байт, т.е SPM_PAGESIZE = 256

writeFlashPage(0, SPM_PAGESIZE, &Data[SPM_PAGESIZE*0]);
writeFlashPage(1, SPM_PAGESIZE, &Data[SPM_PAGESIZE*1]);
writeFlashPage(2, SPM_PAGESIZE, &Data[SPM_PAGESIZE*2]);
writeFlashPage(3, sizeof(Data) - 768, &Data[SPM_PAGESIZE*3]);

asm("cli");
MCUCR |= _BV(IVCE); // Вернуть положение таблицы прерываний на начало
MCUCR &= ~(_BV(IVSEL) | _BV(IVCE));

void (*funcptr)(void) = 0x0000; // Указатель на функцию с адресом 0x0000
funcptr(); // Запустить выполнение основной программы

return;
}


Прикрепленный файл  Bootloader.zip ( 15.56 килобайт ) Кол-во скачиваний: 110


Спасибо всем тем, кто пнул меня в правильном направлении. cheers.gif

з.ы. будут сложности, буду ныть дальше.

Сообщение отредактировал IgorKossak - Apr 15 2011, 06:46
Причина редактирования: [codebox] !!!
Go to the top of the page
 
+Quote Post
SysRq
сообщение Apr 15 2011, 07:55
Сообщение #14


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(Sirko @ Apr 15 2011, 02:20) *
буду ныть дальше
Раньше вас ныть начнёт МК, у которого станет дохнуть flash: перепрошивка при каждом старте убьёт его очень быстро.
Go to the top of the page
 
+Quote Post
Sirko
сообщение Apr 15 2011, 11:11
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
Раньше вас ныть начнёт МК

Безусловно, но этот исходник для понимания сути, а не для CopyPaste

p.s. Прошивка основной программы в бутлоадер не влезет biggrin.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 04:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01595 секунд с 7
ELECTRONIX ©2004-2016