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

Защита секция кода во FLASH в ATmega

На этом форуме вообще-то не принято друг-друга подкалывать.

И не думал. Ведь я как никто заинтересован этой темой и в нормальных ответах в ней, а не в обсуждении моей персоны

А я Дон Амброзио спасибо хочу сказать. Только в этой ветке про STATE узнал. Теперь буду применять. Пусть некоторые меня после этого признания будут ламером считать. Сам-то я знаю, что я ого-го! А те, кто на безобидные приколы обижается, сами виноваты. Дон Амброзио - токо не надо меня прикалывать. Мы ведь с вами друзья...

Поделиться сообщением


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

А кто как организует код программы, чтобы программа детектировала (обнаруживала) случайные переходы из одной точки программы в другую, вызванные воздействием помехонесущего электромагнитного поля

Детектировать случайный переход из одной точки программы в другую своевременно и безболезненно для текущей выполняющейся программы невозможно. Стало быть вопрос лишь в масштабах последствий такого сбоя (по убыванию):

1. Нарушение памяти программ.

2. Нарушение содержимого регистров / памяти данных - в последствии к "подвисанию" неверной работе части программы.

3. Порча незначительных данных например пакета защищенного кодом защиты. (плохо конечно, но с этим можно смириться).

4. Чисто везение, прыжек в участок кода - который ничего не испортил (например из финализации одной функции в финализацию другой с подобными параметрами). Везение рассматривать не будем.

 

Итого лечить надо только 1 и 2.

 

Первое лечится с помощью дублирования кода программы. Определяется и устраняется эта ошибка при очередной перезагрузке устройства. Как правило после такого сбоя устройство перезагружается по WDT.

 

Второе - система продолжает работать но часть функций отказала. Лечится перезагрузкой, перезагрузка делается опять с помощью WDT.

 

Вопрос в том где и как сбрасывать WDT чтобы последствия сбоя были 100% устранены. Решить этот вопрос можно например введя мониторинг статуса каждой задачи. Если используется RTOS, то сделать это достаточно просто - idle task (задача с самым низким приоритетом) периодически оцнивает состояние каждой задачи, если все задачи в порядке - WDT сбрасывается. Состояние же каждой задачи должно определяться индивидуально, для каждой задачи свой отдельный таймаут.

 

Пусть имеется некое устройство, которое занимается опросом некоторых датчиков по одному интерфейсу, и отправляет результаты - по другому. Тогда работу этого устройства можно разбить на 5 задач:

1. idle (занимается контролем WDT)

2. обслуживание передачи по интерфейсу датчиков.

3. обслуживание приема по интерфейсу датчиков.

4. обслуживание передачи по интерфейсу хоста.

5. обслуживание приема по интерфейсу хоста.

 

Статус первой задачи всегда Ок (коль уж в нее попали, то стало быть она работает).

Статус 2-й задачи переходит в состояние Alert если счетчик отправленных пакетов не изменяется в течение заданного таймаута.

Статус 3-й задачи определяется таймаутом "за n секунд не принято ни одного байта"

Статус 4-й задачи определяется аналогично 2-й

и наконец статус 5-й - аналогично 3-й.

 

Если хотя бы одна задача не в порядке, то в задаче 1 запрещаем прерывания и подвешиваем систему циклом

while( K * WDT_CYCLE)

__no_operation();

 

где

WDT_CYCLE - константа, соответвующая количеству циклов эквивалентное интервалу WDT.

K - коэффициен >1, для гарантии сброса МК.

 

Если вдруг получается так, что мы выходим из этого цикла. Тогда WDT вероятно тоже сбойнул - пытаемся:

1. Выполнить аппаратный сброс (если заранее предусмотрели управление внешней схемой сброса).

2. Выполнить прыжек по RESET вектору (т.к. хуже уже все равно не будет).

 

 

PS: До сих пор, против "случайных прыжков" этих программных мер мне хватало с головой.

Поделиться сообщением


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

Детектировать случайный переход из одной точки программы в другую своевременно и безболезненно для текущей выполняющейся программы невозможно.

В корне не согласен с этой аксиомой(откуда Вы это взяли). 100% случайных джампов конечно никогда не отловить. А вот если предположить что джампы на любую величину смещения относительно заданной точки равновероятны, то можно отловить большинство случайных джампов.. Отловить в смысле обнаружить в программе, что случайный джамп имел место. Выше уже приводилось по крайней мере 2 метода как это сделать

 

Как правило после такого сбоя устройство перезагружается по WDT.

С чего Вы это взяли? Допустим во FLASH некоторый код изменился так, что вместо команды установки флага "Пришёл пакет извещения о пожаре" будет команды сброса этого флага. И девайс будет работать нормально просто в любом случае будет считать, что у него всё ОК и никакого пожара нет. И соответственно никакого зацикливания/зависания не произойдёт, а девайс при этом будет находиться в неисправном состоянии

 

Второе - система продолжает работать но часть функций отказала. Лечится перезагрузкой

Сама по себе перезагрузка, как таковая, ничего не лечит. Она просто сбрасывает MCU периферию в исходное состояние. Более того, она не позволит установить причину перезагрузки. Например если зацикливание было вызвано самопроизвольным изменением регистра UBRR из-за чего UART перестал принимать пакеты извне или случайым сбросом флага разрешения прерываний от UART, то после перезагрузки вся периферия сброситься в исходное состояние и мы не узнаем "а чё это было-то?"

 

 

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

А кто будет считать этот тайм-аут?

Поделиться сообщением


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

В корне не согласен с этой аксиомой(откуда Вы это взяли). 100% случайных джампов конечно никогда не отловить.

Потому что:

1. Они случайны, а это значит что можно прыгнуть из "RET" одной функции на "RET" другой.

2. Есть вероятность сбоя детектора, поясню - достаточно мощная EM помеха, способная привести к прыжку бог знает куда, также легко может нарушить содержимое памяти.

 

Ну и Вы сами говорите что 100% нельзя отловить, а раз 100% нельзя отловить то зачем их ловить?!

 

Чаще выгоднее мониторить конкретные узлы МК. И делать recovery там где это возможно, но не всегда это возможно вообще...

 

А вообще, советую поработать с ARM, прыжки случайные там отлавливаются самим процессором на раз аппаратурой процессора. Сильная EM помеха приводящая к случаному прыжку и Вы раньше или позже, но 100% попадете в один из трех Exception'ов DABT/PABT/UNDEFABT.

Поделиться сообщением


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

то после перезагрузки ...

Пардон..Пардон..Прошу прощения

 

Совсем упустил из вида , что Вы юзаете Меги у которых при наступлении тайм-аута WDT проц не сбрасывается, а переходит на вектор прерывания

Поделиться сообщением


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

С чего Вы это взяли? Допустим во FLASH некоторый код изменился так, что вместо команды установки флага

Не о том речь. Конечно сбой надо продетектить, и он продетектится в idle таск'е, если система до этого сама не прыгнет по reset вектору.

Речь о том, что до сброса мы не сможем отдетектить нарушение FLASH. Ну это просто очень накладно пересчитывать CRC флеша постоянно в процессе работы.

 

Сама по себе перезагрузка, как таковая, ничего не лечит.

Ну здрасти. Она переводит устройство в безопастное состояние.

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

 

Например если зацикливание было вызвано самопроизвольным изменением регистра UBRR из-за чего UART перестал принимать пакеты извне или случайым сбросом флага разрешения прерываний от UART, то после перезагрузки вся периферия сброситься в исходное состояние и мы не узнаем "а чё это было-то?"

Это уже не важно, т.к. боримся мы с EM помехой по условию задачи, а не со сбоем UART'a.

Ну всмысле какая нам разница что UBRR изменялся до перезагрузки, если мы его все равно перенастраиваем заново.

 

А кто будет считать этот тайм-аут?

idle таск'е - в той единственной задаче, которая может сбрасывать WDT.

Поделиться сообщением


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

Потому что:

1. Они случайны, а это значит что можно прыгнуть из "RET" одной функции на "RET" другой.

Можно.. Но так как эти реты составляют от силы 1% в программе, то это процесс маловероятный... Я ещё раз повторюсь: все 100% "прыжков" обнаружить не возможно, но 90% - вполне. А это значит, что мы увеличим надёжность нашего девайса в 10 раз: раньше было 100 необнаруживаемых сбоев, а стало 10

 

 

Есть вероятность сбоя детектора

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

 

Ну и Вы сами говорите что 100% нельзя отловить, а раз 100% нельзя отловить то зачем их ловить?!

Ответил выше (см. "в 10 раз").

Т.е. Вы считаете, что если я применив спец.методы построения программы сделаю так, что она будет обнаруживать всего лишь 90% случайных джампов, то Вы считаете уменьшение количества не обнаруженных сбоев в 10 раз эта такая мелочь, ради которой и не стоило утруждаться?

Поделиться сообщением


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

Т.е. Вы считаете, что если я применив спец.методы построения программы сделаю так, что она будет обнаруживать всего лишь 90% случайных джампов, то Вы считаете уменьшение количества не обнаруженных сбоев в 10 раз эта такая мелочь, ради которой и не стоило утруждаться?

Вообще-то да. Потому что к фатальным последствиям приведет как раз неучтенный случай из оставшихся 10%. А раз все не покрывается, то "овчинка выделки не стоит".

Поделиться сообщением


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

А вообще, советую поработать с ARM, прыжки случайные там отлавливаются самим процессором на раз аппаратурой процессора.

Здорово... Я бы конечно лучше бы юзал процессоры, в которых АППАРАТНО заложен контроль доступа к отдельным логическим сегментам кода.. Представляете как бы было здорово.. Разметил флешь на сегменты и потом чтобы перейти из сегмента А в сегмент В нужно записать сначала номер В в спец. регистр защиты памяти... Пусть мы скаканули из-за помехи из А в В... Но проц этот аппаратно обнаруживает путём анализа: соответствует ли содержимое регистра защиты памяти и номер сегмента , в котором мы находимся в данный момент... Хотя и в этом случае прыжки из одной части сегмента в другую часть этого же сегмента были бы не обнаруживаемымм

 

Ну здрасти. Она переводит устройство в безопастное состояние.

Не согласен.... Сброс может длиться 64 мС и более.. А я ручками обнаружив случайный джам через 50 мкС переведу все порты в безопасное состояние.

 

Дык всё же Вы какие процы используете? Вы вроде говорили, что те, у которых по таймауту WDT происходит не сброс , а прерывание

 

Ну всмысле какая нам разница что UBRR изменялся до перезагрузки, если мы его все равно перенастраиваем заново.

Большая... Нам нужно вести статистику сбоев... А она подразумевает классификацию сбоев... Эта статистика позволит нам потом выявить самое слабое место устройства и принять соответствующие меры

 

 

idle таск'е - в той единственной задаче, которая может сбрасывать WDT.
А поподробней... Т.е. эта задача обслуживает счётчики всех потоков и если какой-то оказывает, что наступил тайм-аут, то idle поток выполняет команду wdr и ждёт сброса? Так чтоли?

Поделиться сообщением


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

Здорово... Я бы конечно лучше бы юзал процессоры, в которых АППАРАТНО заложен контроль доступа к отдельным логическим сегментам кода.. Представляете как бы было здорово..

Так в чем вопрос - переходите на ARM с MMU. В старших моделях (920T и выше) мало того, что каждому килобайту памяти можно настроить параметры доступа, так еще определяется и "выровнянность" кода. А если прыгнули внутри одного блока - то DATA_ABORT обеспечен, т.к. сбой произойдет из-за искаженных данных. Но и в младших моделях некоторые прелести MMU есть, а цена такая же как и на меги.

 

Дык всё же Вы какие процы используете? Вы вроде говорили, что те, у которых по таймауту WDT происходит не сброс , а прерывание

разные. и те что с прерывание от WDT и те, что только со сбросом..

 

Большая... Нам нужно вести статистику сбоев... А она подразумевает классификацию сбоев... Эта статистика позволит нам потом выявить самое слабое место устройства и принять соответствующие меры

Может тогда проще снимать слепок всей периферии и RAM'a. Складывать куда-то во внешний eeprom. Потом вычитывать его и анализировать. Это будет много надежней, достоверней и информативней чем то, что программа сможет обнаружить сама.

 

А поподробней... Т.е. эта задача обслуживает счётчики всех потоков и если какой-то оказывает, что наступил тайм-аут, то idle поток выполняет команду wdr и ждёт сброса? Так чтоли?

Да именно так, чтобы свести риск пропуска сбоя до минимума.

Критическим задачам короткий таймаут, некритическим - большой.

Поделиться сообщением


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

Вообще-то да. Потому что к фатальным последствиям приведет как раз неучтенный случай из оставшихся 10%. А раз все не покрывается, то "овчинка выделки не стоит".

Странная логика... Но ведь если не применить эти методы то вероятность этих фатальных последствий возрастёт в 10 раз.... А если учесть , что у вас 10 000 девайсов работают.. Получается вообще говоря не хилая защита... Т.е. вместо 100 000 не обнаруженных сбоев у Вас будет только 10 000... А 90 000 (каждый из которых мог бы если его не обнаружить стать фатальным) Вам удасться предотвратить... И эта по Вашему ерунда?

 

Может тогда проще снимать слепок всей периферии и RAM'a. Складывать куда-то во внешний eeprom. Потом вычитывать его и анализировать. Это будет много надежней, достоверней и информативней чем то, что программа сможет обнаружить сама.

Да это было бы здорово, но для атмег на практике не реализуемо

 

Да именно так, чтобы свести риск пропуска сбоя до минимума.

Критическим задачам короткий таймаут, некритическим - большой.

 

Да...Но дело всё в том, что время между двумя запусками IDLE задачи может оказаться в десятки раз больше тайма-аута самых критических задач... Например у меня для самых критических по времени задач тайм-аут составляет 6 мС... А Время между запусами IDLE-потока колеблется от 1 до 10 Сек

Поделиться сообщением


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

Да это было бы здорово, но для атмег на практике не реализуемо

Почему?!

Что мешает по прерыванию WDT вычитать все регистры периферии, переинициализировать UART и выдать слепок памяти "как есть" в консоль. После чего девайс уходит на перезагрузку.

 

Как минимум

m88/m168/m640/1/m1280/1/ и т.п.

позволяют так сделать.

 

Но дело всё в том, что время между двумя запусками IDLE задачи может оказаться в десятки раз больше тайма-аута самых критических задач... Например у меня для самых критических по времени задач тайм-аут составляет 6 мС... А Время между запусами IDLE-потока колеблется от 1 до 10 Сек

Ну это уже конкретная реализация системы..

Для такой реализации можно перенести WDR в kernel-level задачу. Но идея остается неизменной - команда WDR должна быть одна на всю программу, и должна вызываться только тогда когда достоверно известно, что все задачи в порядке.

Поделиться сообщением


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

Почему?!

Что мешает по прерыванию WDT вычитать все регистры периферии, переинициализировать UART и выдать слепок памяти "как есть" в консоль. После чего девайс уходит на перезагрузку.

 

Как минимум

m88/m168/m162/m640/1/m1280/1/ и т.д.

позволяют так сделать.

Но в этом случае опять же устройство будет делать всё это само.... Я думал Вы подразумеваете "вычитывание" содержимого периферии внешним узлом например с помощью SPI.

А так как Вы говорите конечно можно сделать.. Но ведь не факт, что не покоцался сам код передатчика по UART

Поделиться сообщением


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

Но в этом случае опять же устройство будет делать всё это само.... Я думал Вы подразумеваете "вычитывание" содержимого периферии внешним узлом например с помощью SPI.
Нет, внешним узлом никак....

А так как Вы говорите конечно можно сделать.. Но ведь не факт, что не покоцался сам код передатчика по UART

Дык, разместите этот код в секции бутлоадера и поставьте Fuse защиты от SPM. Будет полная гарантия того, что код обработчика WDT - жив.

Поделиться сообщением


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

Объясните, как-же у вас в таких корпусах от наносекундных помех ничего не сбивается? Вы экраны ставите? Или как вы этого добиваетесь?

 

Да нет там экранов. Просто выполнено как положено, не раз тут методики правильного проектирования обсуждали. Хотя, кое-где этими методиками пренебрегли и имели на первой итерации испытаний бледный вид и зад в мыле (потому как отправляли человека, который проводил испытания, пить кофе, а за это время костылями переделывали, потом, конечно, правили платы (как один прибор испытания прошел, до сих пор поражаюсь, там такая петля была по земле, жуть... видно было, что сейчас упадет, но асилил. Быстренько бросили гвоздь поверх и все сразу полегчало) и схемотехнику (тут обычно ничего страшного, просто там забыли суппрессор или там забыли что-то)). А с другой стороны, например, центральный прибор с основным мозгом четыре круга нарезал по нс и мкс, потому как мелочь всякая в комплекте с ним проверялась и хоть бы хны...

 

Только без обид. Rst7, заранее извиняюсь! Простите, что первое на ум пришло написал. А стирать жалко.

 

Да ладно. Не увлекайтесь только...

Поделиться сообщением


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...