|
|
  |
Не выходит одолеть прерывания в Bootloader'е |
|
|
|
Apr 11 2011, 00:06
|
Местный
  
Группа: Участник
Сообщений: 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 = (  ? (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]
|
|
|
|
|
Apr 11 2011, 02:41
|
Участник

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

|
Скорее всего заморочка с измерением памяти программ: В GCC - байты, у Atmel - слова. Настройте фъюзы на 2k.
Сообщение отредактировал Vetal-Soft - Apr 11 2011, 10:30
|
|
|
|
|
Apr 11 2011, 21:57
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата Скорее всего... Скорее всего. Кто бы носом ткнул. Цитата Настройте фъюзы на 2k
Полученый на выходе HEX: :02000002 1000EC :10 F0000011241FBECFEFD0E1DEBFCDBF11E0A0E0E5 :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, значит последующее значение за ней - это адрес стартапа программы, и на эту строку можно забить при парсинге.
|
|
|
|
|
Apr 12 2011, 08:36
|
Участник

Группа: Участник
Сообщений: 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 кСлова
|
|
|
|
|
Apr 12 2011, 13:00
|

кекс
     
Группа: Свой
Сообщений: 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 */
|
|
|
|
|
Apr 12 2011, 15:01
|
Частый гость
 
Группа: Участник
Сообщений: 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 такта на изменение начала таблицы векторов.
|
|
|
|
|
Apr 12 2011, 18:29
|
Местный
  
Группа: Участник
Сообщений: 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 :02000002 1000EC :10 F0000011241FBECFEFD0E1DEBFCDBF11E0A0E0E5 :10F01000B1E0ECECF0EF01E00BBF02C007900D9205 Вроде как сходится
|
|
|
|
|
Apr 12 2011, 20:10
|

Чайник, 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
|
|
|
|
|
Apr 12 2011, 21:18
|
Местный
  
Группа: Участник
Сообщений: 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]
|
|
|
|
|
Apr 12 2011, 21:52
|
Местный
  
Группа: Участник
Сообщений: 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. Огромнейшее спасибо, вроде как ОНО. По поводу Цитата если это не опечатка, то alag57 пусть... простите, беру свои слова обратно.
|
|
|
|
|
Apr 13 2011, 06:22
|
Частый гость
 
Группа: Участник
Сообщений: 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. Ну да не помешало
Сообщение отредактировал alag57 - Apr 13 2011, 06:26
|
|
|
|
|
Apr 14 2011, 22:20
|
Местный
  
Группа: Участник
Сообщений: 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Спасибо всем тем, кто пнул меня в правильном направлении. з.ы. будут сложности, буду ныть дальше.
Сообщение отредактировал IgorKossak - Apr 15 2011, 06:46
Причина редактирования: [codebox] !!!
|
|
|
|
|
Apr 15 2011, 11:11
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата Раньше вас ныть начнёт МК Безусловно, но этот исходник для понимания сути, а не для CopyPaste p.s. Прошивка основной программы в бутлоадер не влезет
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|