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

CH32V003 удалённое обновление прошивки

Всем привет!

У меня возникла необходимость реализовать удалённое обновление прошивки для CH32V003.

Из-за особенностей устройства его нельзя ресетить перед началом обновления прошивки - устройство помимо своих основных функций в добавок управляет питанием компа, который им управляет (холодный старт, включает комп только после прогрева > 5 градусов).

Если сбросить МК, питание с компа будет снято.

Казалось бы можно загнать цикл и функции для обновления прошивки в RAM и шить оттуда.

Раньше на STM32 я так и делал - шил из RAM и уже потом давал сброс чтобы перезапустить всю систему.

Но с CH32V003 возникла проблема - если код выполняется из FLASH, запись страницы FLASH памяти проходит успешно (пробовал перезаписывать самую последнюю неиспользуемую страницу), но если выполнить тот же самый код из RAM, контроллер вешается намертво. А если выполнять этот код из RAM, но в пошаговой отладке, ничего не зависает - подозреваю, что дело в каких-то времянках.

Также я попробовал разместить цикл и функции для обновления прошивки в System FLASH - если попытаться перейти в функцию обновления прошивки из основного кода, это вызывает HardFault.

Можно ли как-то решить проблему с зависанием записи FLASH при выполнении кода из RAM, либо выполнять функции размещённые в System FLASH вызывая их из основного кода?

Или может быть как-то можно перейти к выполнению кода из System FLASH не сбрасывая контроллер?

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


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

34 минуты назад, BSACPLD сказал:

Можно ли как-то решить проблему с зависанием записи FLASH при выполнении кода из RAM, либо выполнять функции размещённые в System FLASH вызывая их из основного кода?

Код полностью находится в RAM? Может какие-то хвосты остались во флешь? Например - таблица прерываний, где?

Советую проверить по .map-файлу.

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


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

3 minutes ago, jcxz said:

Код полностью находится в RAM? Может какие-то хвосты остались во флешь? Например - таблица прерываний, где?

Полностью - я по шагам прошелся, смотрел, что адреса везде из RAM.

Код без прерываний - только поллинг в while.

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


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

А железо переделывать нельзя? Поставили бы D-защелку на управление питанием, и никаких проблем с изворотами при сбросах и перешивках.

Из-за глюков или штатных, предусмотренных логикой, сбросов МК тоже питание будет скидываться - ИМХО, недоработка дизайна.

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


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

1 минуту назад, BSACPLD сказал:

Полностью - я по шагам прошелся, смотрел, что адреса везде из RAM.

Этого недостаточно. Нужно удостовериться по .map-файлу.

1 минуту назад, BSACPLD сказал:

Код без прерываний - только поллинг в while.

Вообще ни одного прерывания что-ли во всей программе?  :shok:

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


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

5 minutes ago, Arlleex said:

Из-за глюков или штатных, предусмотренных логикой, сбросов МК тоже питание будет скидываться - ИМХО, недоработка дизайна.

Штатный сброс только один - перезагрузка всей системы по питанию.

У МК предельно простая задача - подавать питание на комп после прогрева системы, а также опрос датчиков.

Этот функционал уже отлажен и работает, обновление прошивки как дополнительная необязательная опция.

2 minutes ago, jcxz said:

Вообще ни одного прерывания что-ли во всей программе?

В части перезаливки FLASH - да.

UART через DMA.

Перед перезаливкой FLASH отключаю все прерывания.

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


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

3 минуты назад, Arlleex сказал:

А железо переделывать нельзя? Поставили бы D-защелку на управление питанием, и никаких проблем с изворотами при сбросах и перешивках.

Защёлка может быть потенциально опасна тем, что при зависании МК, питание навсегда останется включенным. Имхо - лучше в базу управляющего ключа поставить конденсатор. Или ещё лучше - какую-то цифровую схему (типа ждущего мультивибратора) формирующую задержку на выключение. Например: TPS3809K33DBVT

40 минут назад, BSACPLD сказал:

Перед перезаливкой FLASH отключаю все прерывания.

Ещё раз вопрос: Каким именно образом удостоверяетесь, что обращений к флешь нет ни одного? Как код попадает во ОЗУ (который у вас "выполняется из ОЗУ")?

"я по шагам прошелся" - это не довод от слова "совсем".

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


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

37 minutes ago, jcxz said:

Ещё раз вопрос: Каким именно образом удостоверяетесь, что обращений к флешь нет ни одного? Как код попадает во ОЗУ (который у вас "выполняется из ОЗУ")?

"я по шагам прошелся" - это не довод от слова "совсем".

Все функции выполняемые из RAM объявлены подобным образом:

void ReadFlashPage64b (uint32_t* Buf64b, uint32_t Page_Address) __attribute__((section(".srodata"))) __attribute__((used)) ;
void WriteFlashPage64b (uint32_t* Buf64b, uint32_t Page_Address) __attribute__((section(".srodata"))) __attribute__((used)) ;

Кроме того и map и пошаговая отладка в дизассемблере показывают адреса RAM.

image.png.0108130f82cabd063601b8f0296a1626.png

image.png.17c1e00d48ebcc3be18753f1010f7172.png

 

Вот, я даже специально сейчас вынес функции для работы с FLASH в отдельный файл.

Выполняю из FLASH - работает нормально и штатно и в пошаговой отладке.

Выполняю из RAM - штатно виснет, а в пошаговой отладке работает.

flash.c flash.h

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


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

1 час назад, jcxz сказал:

Защёлка может быть потенциально опасна тем, что при зависании МК, питание навсегда останется включенным. Имхо - лучше в базу управляющего ключа поставить конденсатор. Или ещё лучше - какую-то цифровую схему (типа ждущего мультивибратора) формирующую задержку на выключение. Например: TPS3809K33DBVT

Это просто для размышления. Мы в реальные проекты с байпасами и разными штуками на безопасное переключение используем обычные WDT + защелка.

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


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

56 минут назад, BSACPLD сказал:

Кроме того и map и пошаговая отладка в дизассемблере показывают адреса RAM.

image.png.0108130f82cabd063601b8f0296a1626.png

Надо смотреть не наличие в .map адресов RAM, а отсутствие адресов FLASH.

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


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

11 minutes ago, jcxz said:

Надо смотреть не наличие в .map адресов RAM, а отсутствие адресов FLASH.

Проверил.

Внутри функции записи FLASH все команды в RAM.

Если поставить точку останова перед вызовом функции и пройтись по шагам, ничего не зависает.

Если поставить точки останова перед вызовом функции и сразу после выхода из функции, то до первой точки программа доходит, затем я снова запускаю Run и контроллер виснет.

После этого я попробовал добавить задержку после каждой команды обращения к регистрам FLASH - контроллер завис и перестал прошиваться, пришлось менять контроллер - он вообще перестал отвечать по SWIO.

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


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

10 минут назад, BSACPLD сказал:

После этого я попробовал добавить задержку после каждой команды обращения к регистрам FLASH - контроллер завис и перестал прошиваться, пришлось менять контроллер - он вообще перестал отвечать по SWIO.

Вы это всё делаете под отладчиком получается. Может у вас где-то в отладчике открыто окошко с константами находящимися во флешь? Или открыто окошко памяти с адресами из флешь? И отладчик читает иногда флешь для обновления состояния окон.

 

Я бы слинковал программу полностью в ОЗУ. Полностью удалив из командного файла компоновщика любые упоминания о том, что у контроллера есть какая-то флешь-память. И проверил работу так.

Ещё могут быть ошибки в программе. При которых происходит случайное чтение каких-то адресов флеши. Но которые не приводят к краху программы (потому и незаметные пока не идёт программирование флешь).

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


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

Чтение вызывается только два раза.

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

И второй раз по команде с UART.

Полностью слинковать программу в RAM нет возможности - она туда не поместится.

У CH32V003 всего 2КБ RAM.

Из окошек при отладке открыт только дизассемблер и исходник.

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


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

Прямо сейчас на ch32v307 подобным занимаюсь. Код слинкован с адреса 0x0000_0000, но шить нужно по адресам флешки 0x0800_0000, иначе FLASH_STATR_EOP не взводится.

Еще добавлю загадочный CSR 0xBC0. Туда пишется нечто, отвечающее за выборку. Может его как-то нужно сбрасывать, чтоб на флешку не влиял?

И стартап от WCH любит из M переключить в U-режим исполнения. Привилегий меньше, и при работе с CSR можно улететь в HF.

Кста, установка RDP блокирует от записи первые 4кБ.

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


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

Не ваш случай, но на старших камушках еще и с частотой непонятки: ядро может 144МГц, а флеш то ли 120, то ли 60 МГц максимум. Типа нужно замедлятся при работе с флешью. Причем, read тоже за работу считается - не понятно(

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


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

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

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

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

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

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

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

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

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

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