SapegoAL 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба Спасибо друзья. Буду разбираться. Ночь длинна. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 4 октября, 2007 Опубликовано 4 октября, 2007 · Жалоба Это дало существенный выигрыш в WinAVR, в IAR не пробовал.Скорее всего ничего не даст. Насколько я помню, IAR ещё древней версии компилятора 1.30 при ужимании на размер очень неплохо выстригал общие подвыражения в подпрограммы, так что тут он сам такое действие произведёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 14 октября, 2007 Опубликовано 14 октября, 2007 · Жалоба Караул!!! Спасайте кто знает и разбирался с данным примером. :( Короче сама передача работает(сделал по прерываниям - уже жалею). Декодирование тоже проходит. Сигнатуры совпадают. Почему то сама запись не происходит. Флэш после операции девственно чист. И сама операция идёт - уснуть можно. Да и выспаться тоже. То ли JTAGом нельзя при данной операции, то ли ещё что-то. Не понимаю также записи вида spm #endif dw 0xFFFF nop В даташите тоже такого не нашёл. PS: ATMEGA640 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bodja74 0 15 октября, 2007 Опубликовано 15 октября, 2007 · Жалоба До сих пор мучаешся :) Выкладывай ,что и в каком порядке и в какие регистры заносиш при записи страницы. spm #endif dw 0xFFFF nop Это типа трех нопов - не актуально ,для этого кирпича :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 22 июля, 2013 Опубликовано 22 июля, 2013 · Жалоба Почему то сама запись не происходит. Флэш после операции девственно чист. ... PS: ATMEGA640 Доброго времени суток, коллеги! Столкнулся с подобной проблемой, не пишется FLASH из бутлоадера. Бутлоадер немного переделанный под себя из AES-аппнота, подобных бутлоадеров понаделано прилично под меги 16/32/64, все работают. А вот под 640 - не шьет :( Исходные данные: камень Atmega640-16AU, питание схемы 5В, кварц 14.7456МГц. Фузы: E:0xF4 H:0xDA L:0xD7 L:0x3F (вообще последний должен быть 0x0C, но ставлю 0x3F для тестов, чтобы уж точно была разрешена запись spm и чтобы потом FLASH можно было прочитать для сравнения) Вот кусочки исходников, откуда пишется во FLASH else if (type == TYPE_PROGRAM) { // Program page buffer into flash page unsigned int *q = (unsigned int *) pageBuffer; unsigned char APPFLASH *r = address; do { spmWriteWord(r, *q++); r += 2; } while (--size); spmErasePage(address); spmProgramPage(address); } Вот исходник spm640.asm (сделал специальный под 640, обрезав "лишнее") NAME spm(16) PUBLIC spmWriteWord PUBLIC spmErasePage PUBLIC spmProgramPage PUBLIC spmEEWriteByte #define __ENABLE_BIT_DEFINITIONS__ #include INCLUDE_FILE #if !defined( EEMWE ) #define EEMWE EEMPE #endif #if !defined( EEWE ) #define EEWE EEPE #endif //============================================================================= // I/O registers used RSEG CODE //============================================================================= // Writes one word to a temporary page buffer spmWriteWord: movw r1:r0, r19:r18 ldi r22, (1 << SPMEN) rjmp spmSPM //============================================================================= // Erases one flash page spmErasePage: ldi r22, (1 << PGERS) | (1 << SPMEN) rjmp spmSPM //============================================================================= // Programs the temporary buffer to flash memory spmProgramPage: ldi r22, (1 << PGWRT) | (1 << SPMEN) //============================================================================= // Executes self-programming command spmSPM: ; movw r31:r30, r17:r16 ; в целях тестирования по адресу 0 всегда пишем константу 0x1357 ldi r31, 0 ldi r30, 0 ldi r19, 0x13 ldi r18, 0x57 movw r1:r0, r19:r18 rcall spmWait in r20, SREG cli sts SPMCSR, r22 spm dw 0xFFFF nop out SREG, r20 ret spmWait: wdr __spmWait: lds r23, SPMCSR andi r23, (1 << SPMEN) brne __spmWait ret //============================================================================= // Writes one byte to EEPROM memory spmEEWriteByte: rcall spmWait rcall spmEEWriteByteComplete out EEARL, r16 out EEARH, r17 out EEDR, r18 sbi EECR, EEMWE sbi EECR, EEWE spmEEWriteByteComplete: sbic EECR, EEWE rjmp spmEEWriteByteComplete ret END Вот настройки линкера -ca90 -w29 //============================================================================= // Interrupt vectors -Z(CODE)INTVEC=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1) -H1895 -h(CODE)(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-BOOT_SIZE+IVT_SIZE-1) //============================================================================= // Code memory -Z(CODE)NEAR_F,HUGE_F,SWITCH,INITTAB,DIFUNCT,CODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1) -Z(FARCODE)FAR_F,FARCODE=(FLASH_SIZE-BOOT_SIZE)-(FLASH_SIZE-1) //============================================================================= // RAM -Z(DATA)NEAR_I,NEAR_Z=RAM_BASE-(RAM_BASE+RAM_SIZE-1) -Z(DATA)RSTACK+100=RAM_BASE-(RAM_BASE+RAM_SIZE-1) -Z(DATA)CSTACK+(RAM_SIZE-300-APP_SRAM_USAGE)=RAM_BASE-(RAM_BASE+RAM_SIZE-1) Вот вывод map-а **************************************** * * * MODULE MAP * * * **************************************** DEFINED ABSOLUTE ENTRIES PROGRAM MODULE, NAME : ?ABS_ENTRY_MOD Absolute parts ENTRY ADDRESS REF BY ===== ======= ====== APP_SRAM_USAGE 0000042E RAM_BASE 00000200 RAM_SIZE 00002000 IVT_SIZE 000000E4 FLASH_SIZE 00010000 BOOT_SIZE 00001000 ************************************************************************* .............. SEGMENTS IN THE MODULE ====================== INTVEC Common segment, address: CODE 0000F000 - 0000F063 (0x64 bytes), align: 0 Segment part 0. **************************************** * * * SEGMENTS IN ADDRESS ORDER * * * **************************************** SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN ======= ===== ============= =========== ==== ==== ===== INTVEC CODE 0000F000 - 0000F063 64 com 1 NEAR_F CODE 0000F064 - 0000F097 34 rel 0 SWITCH CODE 0000F098 dse 0 HUGE_F CODE 0000F098 dse 0 INITTAB CODE 0000F098 - 0000F09D 6 rel 0 DIFUNCT CODE 0000F09E dse 0 CODE CODE 0000F09E - 0000F9C9 92C rel 1 ABSOLUTE DATA 0000001F rel 0 DATA 00000020 DATA 00000021 DATA 00000027 - 00000028 2 DATA 0000002A - 0000002B 2 DATA 0000002D - 0000002E 2 DATA 00000030 - 00000031 2 DATA 00000033 - 00000034 2 DATA 00000036 - 00000036 1 DATA 0000004C - 0000004E 3 DATA 00000055 - 00000055 1 DATA 00000060 - 00000060 1 DATA 0000006F - 0000006F 1 DATA 0000007C - 0000007C 1 DATA 00000080 - 00000082 3 DATA 00000084 - 00000085 2 DATA 000000C0 - 000000C1 2 DATA 000000C4 - 000000C6 3 DATA 00000101 - 00000102 2 DATA 00000104 - 00000105 2 DATA 00000107 - 00000108 2 DATA 0000010A - 0000010B 2 NEAR_I DATA 00000200 dse 0 NEAR_Z DATA 00000200 - 0000061F 420 rel 0 RSTACK DATA 00000620 - 0000071F 100 dse 0 CSTACK DATA 00000720 - 00001FF1 18D2 dse 0 **************************************** * * * END OF CROSS REFERENCE * * * **************************************** 2 506 bytes of CODE memory 7 666 bytes of DATA memory (+ 41 absolute ) Errors: none Warnings: none Пишу бутлоадер, обновляю через него прошивку, читаю FLASH - чистая с 0-го адреса (0xFFFF), с 0xF000 - бутлоадер. Пишу бутлоадер и рабочую прошивку, обновляю через бутлоадер прошивку, читаю FLASH - прошивка по адресу 0 на константу 0x1357 не затирается, с 0xF000 - бутлоадер. Прошу помощи, уже весь мозг сломал, в чем может быть причина, куда копать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 22 июля, 2013 Опубликовано 22 июля, 2013 · Жалоба Пишу бутлоадер, обновляю через него прошивку, читаю FLASH - чистая с 0-го адреса (0xFFFF), с 0xF000 - бутлоадер. Вы после записи страницы разрешаете RWW section? По исходникам непонятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hmm 0 22 июля, 2013 Опубликовано 22 июля, 2013 · Жалоба Что-бы не плодить темы, спрошу здесь: Поскольку существует возможность "вывалиться" в загрузчик (jump, call, ..) , то и вероятность "слёта" прошивки не равна нулю? Т.е. использовать этот способ обновления ПО в случаях ответственного применения нельзя. Командировки по разным странам обременительны. Извиняюсь, если это обсуждалось, но сходу не нашел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 23 июля, 2013 Опубликовано 23 июля, 2013 · Жалоба Вы после записи страницы разрешаете RWW section? По исходникам непонятно. Вообще нет, и до этого случая все прекрасно работало. Не хочется думать, что мне просто несказанно везло, но за несколько лет сбоев не наблюдалось. Возможно используется какой-то хитрый трюк, давно это было. По теме - я об этом думал и даже делал тест, в котором реализовывал такой алгоритм - стирание страницы, разрешение RWW, запись в буфер, запись страницы, разрешение RWW. Результат был тем же - не работало. Но если Вы считаете, что это критически важно, я повторю тест и выложу результат с исходником. Что-бы не плодить темы, спрошу здесь: Поскольку существует возможность "вывалиться" в загрузчик (jump, call, ..) , то и вероятность "слёта" прошивки не равна нулю? Т.е. использовать этот способ обновления ПО в случаях ответственного применения нельзя. Командировки по разным странам обременительны. Извиняюсь, если это обсуждалось, но сходу не нашел. Смотря что Вы имеете в виду под "слетом" прошивки. Если несанкционированный вылет рабочей прошивки в код загрузчика - то да, такое теоретически возможно, и да, теоретически возможно, что МК попадет в такое место загрузчика, в котором зациклится. Но на этот случай есть WDT, который сбросит МК и все восстановится, если конечно а) в этом "цикле" не встретится команда wdr б) сам WDT не окажется временно отключенным. Повторюсь из предыдущего поста - я с таким не сталкивался. А если Вы боитесь, что во время обновления произойдет сбой, прошивка "недообновится" и привет - то нет. Принцип такой - сначала ВСЕГДА стартует бутлоадер, смотрится некий признак, переходить ли в режим обновления. Если признака нет (тут каждый на что горазд придумывает по каким критериям переходить, смотря какой интерфейс используется, таймауты и пр.), считается CRC всей памяти МК (application, т.е. от 0 до бутлоадера), если CRC сошлась, управление передается на 0-ой адрес рабочей прошивке. Рабочая прошивка тоже должна уметь "ловить" какие-то признаки, по которым она передает управление бутлоадеру в целях обновления. Как она это делает? Тупо и цинично :) - встает колом и по WDT ресетится, попадая в бутлоадер. Ну а если бутлоадер "понял", что кто-то извне хочет обновлять - он и обновляет, ну там целый набор команд в аппноте, опять же Вы можете оставить себе только необходимые. Например я оставил только запись FLASH/EEPROM, старт/стоп, все чтения удалил, и все остальное. А фузы блокировки выставил таким образом, что из рабочей прошивки нельзя ни читать ни писать область бутлоадера, и нельзя ни читать ни писать application область, и поскольку прошивки формирую только я, и прошивки эти шифрованные (ключ внутри бутлоадера, на каждый тип устройства свой), получилось очень удобно - вероятность взлома прошивки или ее воровства практически нулевая. Да, забыл добавить, если происходит сбой при обновлении, надо просто запустить процесс повторно - в 99.99% случаев помогает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 23 июля, 2013 Опубликовано 23 июля, 2013 · Жалоба Вот исходник с разрешением RWW else if (type == TYPE_PROGRAM) { // Program page buffer into flash page unsigned int *q = (unsigned int *) pageBuffer; unsigned char APPFLASH *r = address; spmErasePage(address); spmEnableRWW(address); do { spmWriteWord(r, *q++); r += 2; } while (--size); spmProgramPage(address); spmEnableRWW(address); } Вот исходник spm640.asm NAME spm(16) PUBLIC spmWriteWord PUBLIC spmErasePage PUBLIC spmEnableRWW PUBLIC spmProgramPage PUBLIC spmEEWriteByte #define __ENABLE_BIT_DEFINITIONS__ #include INCLUDE_FILE #if !defined( EEMWE ) #define EEMWE EEMPE #endif #if !defined( EEWE ) #define EEWE EEPE #endif //============================================================================= // I/O registers used RSEG CODE //============================================================================= // Writes one word to a temporary page buffer spmWriteWord: movw r1:r0, r19:r18 ldi r22, (1 << SPMEN) rjmp spmSPM //============================================================================= // Erases one flash page spmErasePage: ldi r22, (1 << PGERS) | (1 << SPMEN) rjmp spmSPM //============================================================================= // Re-enables RWW section spmEnableRWW: ldi r22, (1 << RWWSRE) | (1 << SPMEN) rjmp spmSPM //============================================================================= // Programs the temporary buffer to flash memory spmProgramPage: ldi r22, (1 << PGWRT) | (1 << SPMEN) //============================================================================= // Executes self-programming command spmSPM: ; movw r31:r30, r17:r16 ldi r31, 0 ldi r30, 0 ldi r19, 0x13 ldi r18, 0x57 movw r1:r0, r19:r18 rcall spmWait in r20, SREG cli sts SPMCSR, r22 spm dw 0xFFFF nop out SREG, r20 ret spmWait: wdr __spmWait: lds r23, SPMCSR andi r23, (1 << SPMEN) brne __spmWait ret //============================================================================= // Writes one byte to EEPROM memory spmEEWriteByte: rcall spmWait rcall spmEEWriteByteComplete out EEARL, r16 out EEARH, r17 out EEDR, r18 sbi EECR, EEMWE sbi EECR, EEWE spmEEWriteByteComplete: sbic EECR, EEWE rjmp spmEEWriteByteComplete ret END Увы, результат печальный - FLASH не пишется :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hmm 0 24 июля, 2013 Опубликовано 24 июля, 2013 · Жалоба Процесс обновления думаю некритичен, а вот наличие в адресном пространстве кода способного стереть/записать страницу "мусора" может окончится неприятностями. Почему не реализована, например, возможность программно устанавливать флаг RWWSB? Непонятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 24 июля, 2013 Опубликовано 24 июля, 2013 · Жалоба Процесс обновления думаю некритичен, а вот наличие в адресном пространстве кода способного стереть/записать страницу "мусора" может окончится неприятностями. Почему не реализована, например, возможность программно устанавливать флаг RWWSB? Непонятно. Так этот код же находится в пространстве бутлоадера, стереть/записать самого себя он не может, а если по ошибке программиста/мантейнера прошивки зальется "левая" прошивка, которая не позволит штатным образом переходить в бутлоадер, то это проблема программиста/мантейнера. Если же произойдет сбой и запишется "мусор", то не сойдется CRC прошивки, и бутлоадер просто не передаст на нее управление, ожидая загрузки по новой. По моей проблеме - ни у кого не возникло идей? Куда рыть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 24 июля, 2013 Опубликовано 24 июля, 2013 · Жалоба Почему не реализована, например, возможность программно устанавливать флаг RWWSB? Зачем его устанавливать? Скорее нужен бит, установка которого запрещает использование функции самопрограммирования. И чтобы его сбросить можно было только сбросом МК. Так этот код же находится в пространстве бутлоадера, стереть/записать самого себя он не может, Себя - может, но это редко кому надо. По моей проблеме - ни у кого не возникло идей? Куда рыть? Код бута расположен там где ему положено в соответсвии с фузами? P.S. Проще может оказаться не искать ошибку, а взять готовый код у атмела и вставить в свою программу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 24 июля, 2013 Опубликовано 24 июля, 2013 · Жалоба Себя - может, но это редко кому надо. Ну можно же и проверку адреса в бутлоадере вставить, чтобы запретить самоперезапись. Код бута расположен там где ему положено в соответсвии с фузами? P.S. Проще может оказаться не искать ошибку, а взять готовый код у атмела и вставить в свою программу. Да, бутлоадер на своем месте, проверено считыванием из МК всей памяти. В моем случае - F000. У меня все нормально работает на мегах 16/32/64, и только на 640 затык :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hmm 0 25 июля, 2013 Опубликовано 25 июля, 2013 · Жалоба Я наверное не внятно описал гипотетическую ситуацию. Целость бутлоадера по уязвимости проблема N2. Речь про штатный режим, а не момент обновления. По проблеме N1: "левая" прошивка, которая не позволит штатным образом переходить в бутлоадер Это каким способом можно "не позволить", если в результате сбоя в СК окажется код из пространства бутлоадера. RWWSB? Зачем его устанавливать? Не этот бит так другой, позволяющий запретить самопрограммирование или делающее область загрузчика недоступной, при удачном старте основного кода. Похоже выхода нет - придется ставить внешний чип. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Costa 0 25 июля, 2013 Опубликовано 25 июля, 2013 · Жалоба Я наверное не внятно описал гипотетическую ситуацию. Целость бутлоадера по уязвимости проблема N2. Речь про штатный режим, а не момент обновления. По проблеме N1: Это каким способом можно "не позволить", если в результате сбоя в СК окажется код из пространства бутлоадера. Хм, это интересный поворот. Надо будет на досуге сымитировать подобное. Но полагаю, что вероятность порчи основной прошивки в этом случае исчезающе мала, т.к. нужно точно "попасть" в код записи/стирания, иначе весь ущерб - нештатный переход в бутлоадер и как следствие - перезагрузка в рабочую прошивку или штатно, или по WDT. Внешний чип не обеспечит защиты от копирования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться