Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обновление прошивки через CAN
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
pvo125
Доброго Всем!

Делаю обновление прошивки по CAN. Один контроллер посылает другому пакеты по 8 байт с данными (оба STM). На принимающей стороне настроен фильтр и все работает. Но появились сомнения по поводу достоверного принятия каждого пакета по 8 байт. В CAN есть CRC16 которая приписывается к каждой посылки те для каждых 8 байт в моем случае . Вопрос в том примет ли принимающий контроллер те пропустит через фильтр сообщение если данные придут "кривые". Надо ли мне каждую посылку из 8 байт проверять на CRC после того как она прошла через фильтр и попала в майлбокс и сработало прерывание. Или все это делается аппаратно и если я попал в обработчик по этому фильтру значит эти 8 байт можно смело писать во флэш и отправлять запрос на след. посылку.
И еще такой момент если я правильно понимаю и все аппаратно отбрасывается или принимается то при принятии кривых данных на принимающем контроллере я не попаду в обработчик и сам принимающий контроллер не выставит подтверждение в ACK слоте и значит отправляющий контроллер автоматически перепошлет это сообщение.
Поделитесь мыслями кто делал обновление и считали ли дополнительно контрольную сумму каждой посылки или все это было аппаратно.
amiller
Цитата(pvo125 @ Feb 7 2017, 05:52) *
Поделитесь мыслями кто делал обновление и считали ли дополнительно контрольную сумму каждой посылки или все это было аппаратно.

Я делал так:
Есть несколько контроллеров, соединенных между собой шиной CAN
Один контроллер (ведущий) принимает пакеты по UART с верхнего уровня. Если пакет адресован другому контроллеру, то он бьётся на куски и передается по шине CAN.
На принимающей стороне исходный пакет собирается и анализируется, в том числе производится проверка CRC исходного пакета.
Ответ передается также, только в обратном порядке. Это решение универсальное и работает одинаково при обновлении ПО любого из контроллеров в связке.
При работе с ведомыми контроллерами ведущий предоставляет функции шлюза UART-CAN, и ничего более.
А так вообще CAN достаточно умный протокол на аппаратном уровне и гарантирует доставку пакетов согласно спецификации.
pvo125
Цитата
На принимающей стороне исходный пакет собирается и анализируется, в том числе производится проверка CRC исходного пакета.

Про это я и спрашивал. Понятно что можно каждое сообщение проверять на CRC и если не совпадает то заново просить переотправить. Но хотел использовать аппаратную функцию модуля CAN если он действительно работает как я думаю и описал выше тогда мне просто надо писать во флэш принятое сообщение так как оно уже прошло фильтрацию и проверку CRC. А если не прошло то ведущий повторит автоматически. Сейчас у меня все работает "на столе" и обновление происходит и CRC32 всей новой прошивки по окончанию всей передачи совпадает. Но для меня надо понять это происходит просто пока на столе или потому что модули CAN сами отбрасывают и переотправляют сообщения и в итоге во флэш получается корректная CRC.
Т.е сейчас алгоритм такой пишу во флэш все что приходит когда я попадаю в прерывание от CAN и в конце CRC32 всего массива если не совпало то заново процесс обновления. Но так не очень правильно потому что нужно опять стирать флэш. Лучше уж сначала проверить пришедший пакет и потом записать.
jcxz
Цитата(pvo125 @ Feb 7 2017, 09:05) *
Т.е сейчас алгоритм такой пишу во флэш все что приходит когда я попадаю в прерывание от CAN и в конце CRC32 всего массива если не совпало то заново процесс обновления. Но так не очень правильно потому что нужно опять стирать флэш. Лучше уж сначала проверить пришедший пакет и потом записать.

А зачем Вы каждые 8 байт во флешь пишете? Логично завести буфер в ОЗУ на несколько КБ, принимать туда до его заполнения, потом проверить CRC32 этого куска в буфере и записать во флешь.
И к тому же - обычно во время записи флешь в различных МК, выполнение кода из него невозможно. Учитываете это (у Вас ISR CAN в ОЗУ)? Или в вашем МК это не так?
pvo125
Принимаю прошивку во вторую половину флэш. После принятия ресет контроллера и запуск бутлоадера который перепишет со второй половины в первую (рабочую) и затем снова ресет и запуск обновленного приложения (из первой половины). Может это конечно и лишнее переписывать с одного в другое но вторая часть все равно не используется прошивки меньше половины. Пишу по 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.
novikovfb
Цитата(pvo125 @ Feb 7 2017, 13:01) *
Если правильно перевел то сообщение сохраняется в FIFO и генерируется прерывание если crc аппаратно проверенное совпадает. Если нет то приемный узел начинает передавать Eror Frame и передатчик перепосылает сообщение. Все это без участия ядра контроллера и значит считать программно CRC каждого принятого пакет не стоит он уже проверен и можно писать во flash.

всё так, но от потери сообщения это не спасет, надо сверять контрольную сумму всей прошивки
jcxz
Цитата(pvo125 @ Feb 7 2017, 11:01) *
Принимаю прошивку во вторую половину флэш. После принятия ресет контроллера и запуск бутлоадера который перепишет со второй половины в первую (рабочую) и затем снова ресет и запуск обновленного приложения (из первой половины). Может это конечно и лишнее переписывать с одного в другое но вторая часть все равно не используется прошивки меньше половины. Пишу по 8 байт так как сама функция записи находится в обработчике прерывания для CAN и считаю 8 байт быстро записываются.
И действительно если при записи выполнение останавливается то оно останавливается "не на долго". Можно конечно и буфер в озу сделать и писать во флэш например по сектору 1-16 кб но решил делать так. Не знаю время покажет может быть и переделаю.

"Вторая половина флешь" - это физически отдельный блок флешь, в который можно писать и при этом чтение из первого блока позволяется?
Если нет - так делать нельзя как бы ни быстро ни записывались сейчас данные. Завтра окружающая температура изменится и время уплывёт - и Ваше отлаженное на столе изделие перестанет работать. А ещё вроде время записи флешь увеличивается по мере деградации флешь. И причём сильно.
И что значит "функция записи находится в обработчике прерывания"? Уж не запись ли с ожиданием завершения сделали внутри ISR? wacko.gif Если так - это тем более недопустимо если есть другие прерывания в системе. Да и от самого CAN можно прерывания потерять.
Мухи - отдельно, котлеты - отдельно: ISR, всё время готовый обслужить прерывание - отдельно (возможно в ОЗУ); процесс, пишущий flash - отдельно.
pvo125
Цитата
всё так, но от потери сообщения это не спасет

Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?
jcxz
Цитата(pvo125 @ Feb 7 2017, 11:16) *
Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?

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

Да так и сделал crying.gif Специально не считал но думал что запись 2 слов по 4 байта за раз во флэш не займет много времени. Тем более что в это время все равно останавливается выполнение инструкций из основной (рабочей ) части флэш. В stm32f429 можно флэш разбить на 2 части с выполнинием кода из одной из записи стирания другой. Но так не сделал потому что в сети есть stm32f10x контроллер и у них такой фичи нет потому решил делать общий алгоритм чтобы на оба типа можно было перенести. А в таком общем виде вторая половина и первая физически одно целое и выполниние инструкций останавливается.(последнюю фразу хочу уточнить у участников форума).
novikovfb
Цитата(pvo125 @ Feb 7 2017, 13:16) *
Поясните пожалуйста. Как я понял в кан сети сообщение не может потеряться. Ведь если никто не принял сообщение передатчик также будет перепосылать последнее сообщение. Или Вы имеете ввиду случай когда кабель физически поврежден?

Ну это из разряда паранойи, но есть 2 варианта:
1. кто-то еще принял сообщение, он тоже может выставить бит ACK и отправитель успокоится
2. если некорректно написан драйвер CAN на стороне отправки или получения, возможна потеря или задваивание или перестановка пакетов.
Если прошивка окажется неработоспособной, какова цена вопроса? Повторный запуск прошивки или отказ изделия и срыв задачи?
jcxz
Цитата(pvo125 @ Feb 7 2017, 11:31) *
Да так и сделал crying.gif Специально не считал но думал что запись 2 слов по 4 байта за раз во флэш не займет много времени. Тем более что в это время все равно останавливается выполнение инструкций из основной (рабочей ) части флэш.

А Вы вообще проверили запись по 8 байт? Что-то мне подсказывает, что это возможно не будет работать.
Во многих МК флешь-память организована так, что позволяет дозаписывать только кусками не менее чем определённой величины и с определённым выравниванием.
Например в LPC17xx невозможно записать менее 16 байт за раз и с выравниванием 16. Т.е. - записать-то можно, только в реальности записаться может не то, что писали.
Это связано с тем, что внутри флешь имеет контроль целостности, который разбивает весь массив на блоки по 16 байт, для каждого такого блока считается контрольная область (избыточные данные) и пишется вместе с ним во флешь. Эта контрольная область не входит в адресное пространство флешь, её нельзя считать, она невидима, но она влияет на читаемые данные.
Таким образом если писать меньше чем по 16 байт или невыравненно, то потом при чтении этого места получаем белиберду.
Это описано в соответствующих AN. Думаю что в STM32 такая же система.
Цитата(pvo125 @ Feb 7 2017, 11:31) *
что в сети есть stm32f10x контроллер и у них такой фичи нет потому решил делать общий алгоритм чтобы на оба типа можно было перенести. А в таком общем виде вторая половина и первая физически одно целое и выполниние инструкций останавливается.(последнюю фразу хочу уточнить у участников форума).

Это решается просто переносом в ОЗУ кода всех ISR, которые должны работать при записи флешь.
pvo125
Цитата
А Вы вообще проверили запись по 8 байт? Что-то мне подсказывает, что это возможно не будет работать.

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



Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.