pyroman 2 February 26 Posted February 26 (edited) · Report post 16 hours ago, jcxz said: unsigned Tst(unsigned const *p) { _Z3TstPKj: (+1) 0xB510 PUSH {R4,LR} 0x4602 MOV R2,R0 int n = 32; unsigned j = 0; 0x2000 MOVS R0,#+0 0x2120 MOVS R1,#+32 0xF04F 0x34FF MOV R4,#+4294967295 do j |= *p++ ^ -PFLASH_CLEAN; ??Tst_0: (+1) 0xF852 0x3B04 LDR R3,[R2], #+4 0x4063 EORS R3,R4,R3 0x4318 ORRS R0,R3,R0 while (--n); 0x1E49 SUBS R1,R1,#+1 0xD1F9 BNE.N ??Tst_0 return j; 0xBD10 POP {R4,PC} } Пробовал компилить этот же код GCC v12.2.0 - там всё ок: 0000 0346 mov r3, r0 0002 00F18002 add r2, r0, #128 0006 0020 movs r0, #0 .L2: 0008 53F8041B ldr r1, [r3], #4 000c 9A42 cmp r2, r3 000e 60EA0100 orn r0, r0, r1 0012 F9D1 bne .L2 0014 7047 bx lr Неужто IAR-овцы до сих пор так и не освоили систему команд Thumb-2??? Или может более новые версии всё-таки поумнели? У IAR в вашем случае всё нормально с оптимизацией, образцовая. А вы подумайте... Edited February 26 by pyroman Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 1 минуту назад, pyroman сказал: У IAR в вашем случае всё нормально с оптимизацией. А вы подумайте... Над чем думать-то? "Нормально" - это ставить 3 команды вместо одной? Странные у вас понятия нормальности..... Quote Share this post Link to post Share on other sites More sharing options...
pyroman 2 February 26 Posted February 26 · Report post 27 minutes ago, jcxz said: Над чем думать-то? "Нормально" - это ставить 3 команды вместо одной? Странные у вас понятия нормальности..... Нормально. В этом случае... Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 14 часов назад, Arlleex сказал: Ясно. Ресурс экономите (и время). 4 часа назад, VladislavS сказал: А потом вспоминаешь про 100K циклов записи и смену прошивки несколько раз в год в первые пару лет эксплуатации и становится грустно 😅 Да - совсем забыл: Ресурс флеши экономится моим алгоритмом весьма существенно. Критики видимо не задумывались над возможностью, что в момент когда пришло обновление прошивки (например по сети передачи данных), устройство может иметь нестабильное питание. И постоянно сбрасывается, через произвольное количество секунд. Что будет в этом случае? В этом случае мой алгоритм отработает корректно. Только медленнее естественно. И потратит ровно столько же ресурса флеши, как если бы питание было стабильным. А что же будет если всегда тупо стирать сектора флешь и всегда писать? В таком случае - первое же обновление прошивки намертво убьёт флешь МК, протерев её до дыр. В реальной моей практике на позапрошлой работе у нас были заказчики, у которых было множество постоянно включенных наших устройств (счётчиков э/энергии). И подключенных к сети сбора. Но имеющих постоянно дергающееся питание. Заказчика это нисколько не волновало, так как в данный момент этот счётчик не используется, а просто висит на проводах (просто питающий фидер от ячейки подстанции ничего не питает). Факт постоянных перезагрузок мы обнаруживали, когда анализировали журналы работы счётчика. Заказчику это нисколько не мешает. Но что будет, если по такой сети сбора пройдёт обновление прошивки счётчиков, а алгоритм обновления реализован тупо? При тупом алгоритме, счётчик 100500 раз запустит процедуру обновления прошивки, 1000+ раз сотрёт флешь и убьёт её. С моим алгоритмом - не убьёт. Прошьётся в конце концов нормально. Пусть и дольше. С такой целью этот алгоритм и был разработан. Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 311 February 26 Posted February 26 · Report post 1 час назад, jcxz сказал: Критики видимо не задумывались над возможностью, что в момент когда пришло обновление прошивки (например по сети передачи данных), устройство может иметь нестабильное питание. А еще подлые мыши-диверсанты грызут провода, ага🙂 1 час назад, jcxz сказал: При тупом алгоритме, счётчик 100500 раз запустит процедуру обновления прошивки, 1000+ раз сотрёт флешь и убьёт её. Ну и супер - протрут до дыр, придут просить отремонтировать, попутно пусть чинят перебои питания, которые не иначе, как целенаправленные диверсии. P.S. Я делал загрузчики в том числе и с проверкой содержимого нового сектора с содержимым флешки. Она, правда, гораздо проще (без всяких пометок и битовых карт): пришел блок данных на обновление, я считываю содержимое сектора флешки - если совпадает, иду дальше (ничего не делаю). Если не совпадает - откатываюсь до границы сектора, стираю, запрашиваю данные по откатанной границе - шуршу дальше. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 23 минуты назад, Arlleex сказал: Ну и супер - протрут до дыр, придут просить отремонтировать, попутно пусть чинят перебои питания, которые не иначе, как целенаправленные диверсии. Нет, они просто пришлют счётчик производителю с рекламацией - "самопроизвольно вышел из строя при штатной работе". И будут правы. Так как счётчик должен корректно работать при любых сбоях питания. И обновления по сети сбора данных в любой момент - тоже обычное явление. 23 минуты назад, Arlleex сказал: Она, правда, гораздо проще (без всяких пометок и битовых карт): пришел блок данных на обновление, я считываю содержимое сектора флешки - если совпадает, иду дальше (ничего не делаю). Если не совпадает - откатываюсь до границы сектора, стираю, запрашиваю данные по откатанной границе - шуршу дальше. А если страница не совпадает, но можно записать её без стирания (так как во флешь - стёртое содержимое)? У вас будет лишнее стирание сектора. А если питание дёргается - так и протрёте сектор до дыры. Кроме того - проще, когда у вас образ не шифрованный. А у меня - образ шифрованный AES256. И большой - ОЗУ на весь образ не хватит. А значит - откатиться всего лишь до границы сектора не получится. Нужно запускать процесс чтения/дешифровки от самого начала. Вот для того и битовые карты. Чтобы сперва сделать все сравнения, составить "план работ" так сказать, а потом - выполнять его попунктно. Так требуется всего 2 цикла прохода/дешифровки образа. И минимум стираний/записей флеши. Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 311 February 26 Posted February 26 · Report post 38 минут назад, jcxz сказал: А если страница не совпадает, но можно записать её без стирания (так как во флешь - стёртое содержимое)? У вас будет лишнее стирание сектора. А если питание дёргается - так и протрёте сектор до дыры. Нет конечно - если минимальное слово записи (16 бит) полностью 0xFFFF, т.е. его можно записать без стирания - я пишу. Поэтому лишних стираний не будет. 38 минут назад, jcxz сказал: И большой - ОЗУ на весь образ не хватит. А значит - откатиться всего лишь до границы сектора не получится. Нужно запускать процесс чтения/дешифровки от самого начала. А. Вы про шифровку. Ну опять же - нельзя шифровать небольшие куски (блоки), умещающиеся в достаточный объем ОЗУ? Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 1 час назад, Arlleex сказал: Нет конечно - если минимальное слово записи (16 бит) полностью 0xFFFF, т.е. его можно записать без стирания - я пишу. Поэтому лишних стираний не будет. Ну вот шли вы шли по сектору - всё или совпадало или были 0xFFFF - писали, и вдруг - не совпадающее и не 0xFFFF! Нужно откатываться и стирать и писать по новой. Т.е. - какие-то данные будете писать по два раза, тормозя и тратя ресурс. 1 час назад, Arlleex сказал: А. Вы про шифровку. Ну опять же - нельзя шифровать небольшие куски (блоки), умещающиеся в достаточный объем ОЗУ? В смысле - не шифровать как единый файл, а шифровать кусками по объёму свободного ОЗУ? Так вроде - минусы очевидны: 1. Сперва всё равно нужно всё прочитать и проверить валидность прошивки. Т.е. - один цикл дешифрующий все куски, с подсчётом SHA-256 всего образа. 2. Затем - какого размера куски шифровать? Сегодня алгоритм работает на одном МК, завтра на другом: размеры свободного ОЗУ - разные; размеры секторов стирания - тоже разные. И в МК могут быть сектора размера больше свободного размера ОЗУ (сектора 128/256 КБ в МК - не редкость уже). Придётся и утилиты шифрования переписывать каждый раз и сам алгоритм дешифровки. А в чём бонус такого подхода? Всё равно - раз сектор может быть больше размера свободной ОЗУ - то один фиг придётся карты страниц строить. Только уже не на весь образ, а на каждый сектор по-отдельности. Получится ещё сложнее чем у меня. У меня всего 2 прохода дешифровки - сперва сбор данных/построение карт, потом - прошивка страниц по карте. И ОЗУ требуется минимум - только на карты страниц (256-байтных) и на один сегмент дешифровки AES. 3. Увеличится размер образа - каждому куску нужен будет заголовок. Заголовок не кратный размеру страницы - опять проблемы с выравниванием. 4. У меня нет полной уверенности, что общая криптостойкость образа прошивки не уменьшится при таком способе шифрования. При шифровании данные для каждого последующего сегмента шифрованного образа зависят от предыдущего - XOR-ятся и шифруются. Если шифровать независимыми кусками - как минимум каждому куску потребуется заголовок с какими-то случайными данными. Кусок станет некратного странице размера (странице внутренней флешь или странице внешней флешь) и т.д. 5. Усложнение утилит шифрования/проверки образов прошивок. Вобщем - в чём плюсы такого метода? непонятно. Только хуже станет. имхо. Quote Share this post Link to post Share on other sites More sharing options...
VladislavS 46 February 26 Posted February 26 · Report post Блочный шифр с размером блока целое кол-во раз укладывающимся в странцу. Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 311 February 26 Posted February 26 · Report post 1 минуту назад, jcxz сказал: Ну вот шли вы шли по сектору - всё или совпадало или были 0xFFFF - писали, и вдруг - не совпадающее и не 0xFFFF! Нужно откатываться и стирать и писать по новой. Ну да. А как иначе? Если хочется записать в не стертое слово пусть даже наполовину грязного сектора (в котором уже лежат данные), то этот сектор в любом случае придется стирать. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 16 минут назад, VladislavS сказал: Блочный шифр с размером блока целое кол-во раз укладывающимся в странцу. И что? Предлагаете заголовок перед каждой независимой шифруемой частью сделать равным размеру страницы? В этом случае суммарный размер образа сильно вырастет. О чём я выше писал. 4 минуты назад, Arlleex сказал: Ну да. А как иначе? Если хочется записать в не стертое слово пусть даже наполовину грязного сектора (в котором уже лежат данные), то этот сектор в любом случае придется стирать. Ну вот у вас и получается, что некоторые страницы будут писаться по 2 раза. У меня - всегда только 1 раз. Каждая страница пишется не более одного раза. "Иначе" - сразу построить карту стираний/записей. Что я и делаю. Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 311 February 26 Posted February 26 · Report post 4 минуты назад, jcxz сказал: "Иначе" - сразу построить карту стираний/записей. Что я и делаю. Построили. Выявили, что надо стереть память. Стерли. Стали писать - выключили питание. Включили. Начали снова пытаться строить карту, видим, что сектор записан не полностью, и одно из слов не совпадает с тем, которой лежит в образе. Т.е. слово флешки уже не перезаписать. Т.е. надо стирать сектор. У меня то же самое. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 20 минут назад, Arlleex сказал: Построили. Выявили, что надо стереть память. Стерли. Стали писать - выключили питание. Включили. Начали снова пытаться строить карту, видим, что сектор записан не полностью, и одно из слов не совпадает с тем, которой лежит в образе. Т.е. слово флешки уже не перезаписать. Почему не перезаписать? Делаем OR или AND - и просто дописываем поверх. 20 минут назад, Arlleex сказал: Т.е. надо стирать сектор. У меня то же самое. Передёргиваете. У вас не то же самое. У вас повторная запись будет и без выключения питания. А у меня после включения питания продолжит писать с места прошлой остановки. Без стирания этого сектора. Quote Share this post Link to post Share on other sites More sharing options...
Arlleex 311 February 26 Posted February 26 · Report post 24 минуты назад, jcxz сказал: Почему не перезаписать? Делаем OR или AND - и просто дописываем поверх. В STM если я в ячейку, которая имеет значение != 0xFFFF (стертое), попытаюсь "дописать" данные, то контроллер покажет кукиш, и ничего не запишет. Если в Вашем МК флешка умеет дописывать - отлично. Но тогда и мой алгоритм мог бы пройтись 1 раз. И вообще в контроллерах флешки с ECC дописывать в гранулу, охраняемую ECC, нельзя (если специально разработчики не заморочились и каким-то чудом не делают перезапись ECC при дозаписи основной гранулы памяти). Quote Share this post Link to post Share on other sites More sharing options...
jcxz 342 February 26 Posted February 26 · Report post 25 минут назад, Arlleex сказал: В STM если я в ячейку, которая имеет значение != 0xFFFF (стертое) попытаюсь "дописать" данные, то контроллер покажет кукиш, и ничего не запишет. Это в ячейку, запись которой полностью завершилась. Т.е. - к которой в конец были добавлены ECC-биты. Но вы же говорите про случай сбоя питания? А в этом случае вангую - какая-то часть данных успела записаться, остальная - нет. И ECC-биты ещё не записаны (имеют стёртое состояние). А значит запись "поверх" по идее - должна пройти. 25 минут назад, Arlleex сказал: Если в Вашем МК флешка умеет дописывать - отлично. Но тогда и мой алгоритм мог бы пройтись 1 раз. Ещё раз ваш алгоритм: Сравниваем страницу 0: нет изменений? Ничего не делаем. Сравниваем страницу 1: есть изменения? Но можно записать без стирания. Пишем. Сравниваем страницы 2...P-2: нет изменений? Ничего не делаем. Сравниваем страницу P-1: есть изменения? И нельзя записать без стирания. Нужно стирать весь сектор, а потом писать заново. Вот здесь у вас страница 1 пишется 2 раза. Даже без всяких сбоев питания. А если таких страниц будет - с 0-й по (P-2)-ю? Вы все эти страницы запишете по 2 раза. 25 минут назад, Arlleex сказал: И вообще в контроллерах флешки с ECC дописывать в гранулу, охраняемую ECC, нельзя (если специально разработчики не заморочились и каким-то чудом не делают перезапись ECC при дозаписи основной гранулы памяти). Ещё раз - если эти самые ECC-биты записаны. Но если как вы говорите - был сбой питания, и даже биты данных не успели записаться, то видимо биты ECC должны быть стёртыми? Почему тогда не запишется? И вы уверены - что запись невозможна если ECC есть? По моим экспериментам - запись проходит нормально, только потом читается мусор из-за неверного ECC-контроля. Но это же не мешает писать поверх. PS: Вообще тестил когда-то свой алгоритм очень жёстко - с многократными случайными перезагрузками - сбоев не было ни разу. А ECC в XMC имеется. И даже ещё более жёсткая, чем в STM. ЗЫ: Где-то в RM XMC видел явное утверждение о том, что при программировании флешь, байты страницы пишутся последовательно - один за другим: от 0-го байта к последнему. Очевидно ECC-биты должны добавляться уже после последнего байта данных. В XMC в API программирования flash использую постраничный режим программирования. Quote Share this post Link to post Share on other sites More sharing options...