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

Обновление прошивки через CAN

Доброго Всем!

 

Делаю обновление прошивки по CAN. Один контроллер посылает другому пакеты по 8 байт с данными (оба STM). На принимающей стороне настроен фильтр и все работает. Но появились сомнения по поводу достоверного принятия каждого пакета по 8 байт. В CAN есть CRC16 которая приписывается к каждой посылки те для каждых 8 байт в моем случае . Вопрос в том примет ли принимающий контроллер те пропустит через фильтр сообщение если данные придут "кривые". Надо ли мне каждую посылку из 8 байт проверять на CRC после того как она прошла через фильтр и попала в майлбокс и сработало прерывание. Или все это делается аппаратно и если я попал в обработчик по этому фильтру значит эти 8 байт можно смело писать во флэш и отправлять запрос на след. посылку.

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

Поделитесь мыслями кто делал обновление и считали ли дополнительно контрольную сумму каждой посылки или все это было аппаратно.

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


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

Поделитесь мыслями кто делал обновление и считали ли дополнительно контрольную сумму каждой посылки или все это было аппаратно.

Я делал так:

Есть несколько контроллеров, соединенных между собой шиной CAN

Один контроллер (ведущий) принимает пакеты по UART с верхнего уровня. Если пакет адресован другому контроллеру, то он бьётся на куски и передается по шине CAN.

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

Ответ передается также, только в обратном порядке. Это решение универсальное и работает одинаково при обновлении ПО любого из контроллеров в связке.

При работе с ведомыми контроллерами ведущий предоставляет функции шлюза UART-CAN, и ничего более.

А так вообще CAN достаточно умный протокол на аппаратном уровне и гарантирует доставку пакетов согласно спецификации.

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


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

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

Про это я и спрашивал. Понятно что можно каждое сообщение проверять на CRC и если не совпадает то заново просить переотправить. Но хотел использовать аппаратную функцию модуля CAN если он действительно работает как я думаю и описал выше тогда мне просто надо писать во флэш принятое сообщение так как оно уже прошло фильтрацию и проверку CRC. А если не прошло то ведущий повторит автоматически. Сейчас у меня все работает "на столе" и обновление происходит и CRC32 всей новой прошивки по окончанию всей передачи совпадает. Но для меня надо понять это происходит просто пока на столе или потому что модули CAN сами отбрасывают и переотправляют сообщения и в итоге во флэш получается корректная CRC.

Т.е сейчас алгоритм такой пишу во флэш все что приходит когда я попадаю в прерывание от CAN и в конце CRC32 всего массива если не совпало то заново процесс обновления. Но так не очень правильно потому что нужно опять стирать флэш. Лучше уж сначала проверить пришедший пакет и потом записать.

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


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

Т.е сейчас алгоритм такой пишу во флэш все что приходит когда я попадаю в прерывание от CAN и в конце CRC32 всего массива если не совпало то заново процесс обновления. Но так не очень правильно потому что нужно опять стирать флэш. Лучше уж сначала проверить пришедший пакет и потом записать.

А зачем Вы каждые 8 байт во флешь пишете? Логично завести буфер в ОЗУ на несколько КБ, принимать туда до его заполнения, потом проверить CRC32 этого куска в буфере и записать во флешь.

И к тому же - обычно во время записи флешь в различных МК, выполнение кода из него невозможно. Учитываете это (у Вас ISR CAN в ОЗУ)? Или в вашем МК это не так?

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


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

Принимаю прошивку во вторую половину флэш. После принятия ресет контроллера и запуск бутлоадера который перепишет со второй половины в первую (рабочую) и затем снова ресет и запуск обновленного приложения (из первой половины). Может это конечно и лишнее переписывать с одного в другое но вторая часть все равно не используется прошивки меньше половины. Пишу по 8 байт так как сама функция записи находится в обработчике прерывания для CAN и считаю 8 байт быстро записываются.

И действительно если при записи выполнение останавливается то оно останавливается "не на долго". Можно конечно и буфер в озу сделать и писать во флэш например по сектору 1-16 кб но решил делать так. Не знаю время покажет может быть и переделаю.

Кстати нашел подтверждения для своего заключения в первом посте. На сайте https://www.can-cia.org/can-knowledge/can/crc/ нашел описание этого механизма.

The receivers use the same polynomial to calculate the check sum from the bits as seen on the bus-lines. The self-calculated check sum is compared with the received on. If it matches, the frame is regarded as correctly received and the receiving node transmits a dominant state in the ACK slot bit, overwriting the recessive state of the transmitter. In case of a mismatch, the receiving node sends an Error Frame after the ACK delimiter.

 

Если правильно перевел то сообщение сохраняется в FIFO и генерируется прерывание если crc аппаратно проверенное совпадает. Если нет то приемный узел начинает передавать Eror Frame и передатчик перепосылает сообщение. Все это без участия ядра контроллера и значит считать программно CRC каждого принятого пакет не стоит он уже проверен и можно писать во flash.

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


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

Если правильно перевел то сообщение сохраняется в FIFO и генерируется прерывание если crc аппаратно проверенное совпадает. Если нет то приемный узел начинает передавать Eror Frame и передатчик перепосылает сообщение. Все это без участия ядра контроллера и значит считать программно CRC каждого принятого пакет не стоит он уже проверен и можно писать во flash.

всё так, но от потери сообщения это не спасет, надо сверять контрольную сумму всей прошивки

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


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

Принимаю прошивку во вторую половину флэш. После принятия ресет контроллера и запуск бутлоадера который перепишет со второй половины в первую (рабочую) и затем снова ресет и запуск обновленного приложения (из первой половины). Может это конечно и лишнее переписывать с одного в другое но вторая часть все равно не используется прошивки меньше половины. Пишу по 8 байт так как сама функция записи находится в обработчике прерывания для CAN и считаю 8 байт быстро записываются.

И действительно если при записи выполнение останавливается то оно останавливается "не на долго". Можно конечно и буфер в озу сделать и писать во флэш например по сектору 1-16 кб но решил делать так. Не знаю время покажет может быть и переделаю.

"Вторая половина флешь" - это физически отдельный блок флешь, в который можно писать и при этом чтение из первого блока позволяется?

Если нет - так делать нельзя как бы ни быстро ни записывались сейчас данные. Завтра окружающая температура изменится и время уплывёт - и Ваше отлаженное на столе изделие перестанет работать. А ещё вроде время записи флешь увеличивается по мере деградации флешь. И причём сильно.

И что значит "функция записи находится в обработчике прерывания"? Уж не запись ли с ожиданием завершения сделали внутри ISR? :wacko: Если так - это тем более недопустимо если есть другие прерывания в системе. Да и от самого CAN можно прерывания потерять.

Мухи - отдельно, котлеты - отдельно: ISR, всё время готовый обслужить прерывание - отдельно (возможно в ОЗУ); процесс, пишущий flash - отдельно.

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


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

всё так, но от потери сообщения это не спасет

Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?

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


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

Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?

Не сообщение, а потеря прерывания. Пока Вы долго обрабатываете предыдущее событие, может прийти ещё несколько.

Да и даже такая реализация ISR, которая приводит к перезапросам в шине - это очень плохая реализация, так как ухудшает качество всей связи по данной шине.

Представьте что разработчики всех устройств на вашей CAN будут так писать свои ISR. Там будет куча перезапросов из-за этого. В нормальной ситуации перезапросы должны бороться с помехами (или коллизиями на шине), но никак не с кривостью ПО.

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


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

Уж не запись ли с ожиданием завершения сделали внутри ISR? wacko.gif

Да так и сделал :crying: Специально не считал но думал что запись 2 слов по 4 байта за раз во флэш не займет много времени. Тем более что в это время все равно останавливается выполнение инструкций из основной (рабочей ) части флэш. В stm32f429 можно флэш разбить на 2 части с выполнинием кода из одной из записи стирания другой. Но так не сделал потому что в сети есть stm32f10x контроллер и у них такой фичи нет потому решил делать общий алгоритм чтобы на оба типа можно было перенести. А в таком общем виде вторая половина и первая физически одно целое и выполниние инструкций останавливается.(последнюю фразу хочу уточнить у участников форума).

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


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

Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?

Ну это из разряда паранойи, но есть 2 варианта:

1. кто-то еще принял сообщение, он тоже может выставить бит ACK и отправитель успокоится

2. если некорректно написан драйвер CAN на стороне отправки или получения, возможна потеря или задваивание или перестановка пакетов.

Если прошивка окажется неработоспособной, какова цена вопроса? Повторный запуск прошивки или отказ изделия и срыв задачи?

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


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

Да так и сделал :crying: Специально не считал но думал что запись 2 слов по 4 байта за раз во флэш не займет много времени. Тем более что в это время все равно останавливается выполнение инструкций из основной (рабочей ) части флэш.

А Вы вообще проверили запись по 8 байт? Что-то мне подсказывает, что это возможно не будет работать.

Во многих МК флешь-память организована так, что позволяет дозаписывать только кусками не менее чем определённой величины и с определённым выравниванием.

Например в LPC17xx невозможно записать менее 16 байт за раз и с выравниванием 16. Т.е. - записать-то можно, только в реальности записаться может не то, что писали.

Это связано с тем, что внутри флешь имеет контроль целостности, который разбивает весь массив на блоки по 16 байт, для каждого такого блока считается контрольная область (избыточные данные) и пишется вместе с ним во флешь. Эта контрольная область не входит в адресное пространство флешь, её нельзя считать, она невидима, но она влияет на читаемые данные.

Таким образом если писать меньше чем по 16 байт или невыравненно, то потом при чтении этого места получаем белиберду.

Это описано в соответствующих AN. Думаю что в STM32 такая же система.

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

Это решается просто переносом в ОЗУ кода всех ISR, которые должны работать при записи флешь.

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


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

А Вы вообще проверили запись по 8 байт? Что-то мне подсказывает, что это возможно не будет работать.

Да проверял. я же писал выше что вся прошивка записывается и даже crc32 всего массива по окончанию записи совпадает. Меня интересовал вопрос в вычислении CRC дополнительно т е программно при принятии каждого пакета(8 байт).

В stm можно писать от 1 - до 4 байт за раз( можно еще 8 но там вроде нужен внешний источник). (В stm32f10 вроде минимум 4 байта двумя посылками по 2 байта может и наврал пока до них не дошел).

 

 

 

 

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...