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

На STM32F072 при включенном RDP не работает NRST

Всем привет!

Имеется МК STM32F072RBT6, который программируется и отлаживается с помощью OpenOCD через кабель на базе FT2232H. Всё прекрасно работает, пока не выполняется включение защиты от чтения. После отдачи команды lock 0 через OpenOCD (установка защиты от чтения RDP Level 1) начинаются странные эффекты: команда reset halt в OpenOCD перестает работать, при этом МК уходит в HardFault:

> reset halt
adapter speed: 1000 kHz
SWD DPIDR 0x0bb11477
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0xc1000003 pc: 0xfffffffe msp: 0xfffffffc

И после этого начинается самое интересное: МК перестаёт реагировать на внешний сигнал NRST. При этом его по-прежнему возможно отресетить путем записи в память, например, с помощью команды mww 0x40022010 0x2080, которая устанавливает бит OBL_LAUNCH в регистре FLASH_CR и перезагружает МК изнутри. При этом повторный reset halt приводит МК в то же самое состояние.

Что это может быть? Это проявление какого-то встроенного механизма защиты STM32, который блокирует ресет при попытке чтения внутренней памяти?

PS: Не то чтобы эта особенность очень мешает жить, но хочется разобраться в этом странном поведении МК.

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


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

Приветствую!
 

Цитата

После отдачи команды lock 0 (установка защиты от чтения RDP Level 1) команда reset halt в OpenOCD перестает работать, при этом МК уходит в HardFault...

Ну а чего Вы хотели, как бы?

Цитата

Level 1: read protection
...
Debug, boot RAM and boot loader modes
In debug mode (with SWD) or when code is running from boot RAM or boot loader, the main Flash memory and the backup registers (RTC_BKPxR in the RTC) are totally inaccessible. In these modes, even a simple read access generates a bus error and a Hard Fault interrupt. The main Flash memory is program/erase protected to prevent malicious or unauthorized users from reprogramming any of the user code with a dump routine. Any attempted program/erase operation sets the PGERR flag of Flash status register (FLASH_SR)...


То, что сбросить по внешней ноге NRST невозможно - это да, есть такое. Скорее всего, баг. Надо бы осциллом глянуть, не держит ли сам МК NRST в нуле.

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


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

Можно попробовать передернуть питание после установки защиты.

Нужно проверить, что все option-биты описаны для данного МК верно.

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


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

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

Ну а чего Вы хотели, как бы?

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

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

Надо бы осциллом глянуть, не держит ли сам МК NRST в нуле.

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

4 минуты назад, adnega сказал:

Можно попробовать передернуть питание после установки защиты.

Это помогает, но неудобно до жути. В качестве альтернативы я сейчас использую запись в регистр FLASH_CR, которая одновременно обновляет действующее состояние RDP.

5 минут назад, adnega сказал:

Нужно проверить, что все option-биты описаны для данного МК верно.

Что Вы имеете в виду?

Есть, кстати, подобный вопрос на SourceForge: https://sourceforge.net/p/openocd/tickets/179/

Только на него нет ни одного ответа.

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


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

4 минуты назад, makc сказал:

Это помогает, но неудобно до жути...

Видимо, не зря они сами пишут об этом

Цитата

3.3.1 Read protection
The read protection is activated by setting the RDP option byte and then, by applying a system reset to reload the new RDP option byte.
Note: If the read protection is set while the debugger is still connected through SWD, apply a POR (power-on reset) instead of a system reset.

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


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

С другой стороны из описания регистра FLASH_CR:

Цитата

Bit 13 OBL_LAUNCH: Force option byte loading When set to 1, this bit forces the option byte reloading. This operation generates a system reset.

0: Inactive

1: Active

 

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


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

У меня так и не получилось через OBL_LAUNCH перезагрузить. Только передергивание питания помогает.

Пару раз словил нетикающий SysTick, пока не сбросишь питание.

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


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

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

У меня так и не получилось через OBL_LAUNCH перезагрузить. Только передергивание питания помогает.

В OpenOCD перед записью нужно сделать poll off. После этого запись OBL_LAUNCH во FLASH_CR проходит нормально и МК успешно перезагружается. Если не сделать poll off, то после записи получаем новый HardFault и естественно ничего не работает.

8 минут назад, adnega сказал:

Пару раз словил нетикающий SysTick, пока не сбросишь питание.

За два дня экспериментов ни разу не наблюдалось таких проблем. Все тикает как надо.

Кстати, после сброса с помощью OBL_LAUNCH NRST снова начинает работать как ни в чем не бывало.

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


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

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

У меня так и не получилось через OBL_LAUNCH перезагрузить. Только передергивание питания помогает.

У меня в загрузчике практически первой стартует функция

#define LockNVMOp()    FLASH->CR      = FLASH_CR_LOCK
#define UnlockROMOp()  FLASH->KEYR    = 0x45670123, FLASH->KEYR = 0xCDEF89AB
#define UnlockOptOp()  FLASH->OPTKEYR = 0x45670123, FLASH->OPTKEYR = 0xCDEF89AB
#define ClrROMOpSReg() FLASH->SR      = FLASH_SR_PGERR | FLASH_SR_WRPERR | FLASH_SR_EOP
#define UpdSysOpt()    FLASH->CR      = FLASH_CR_OBL_LAUNCH
#define isROMBsy()     (FLASH->SR & FLASH_SR_BSY)


void hw_InitOpt(void)
{
#define RDP_LVL0 0xAA
#define RDP_LVL1 0x12
#define WRP_SECT (B1 | B0)
#define RDP(t)   (OPT(t)[0])
#define WRP      (&OPT(u16)[4])
#define OPT(t)   ((volatile t *)MCU_OPT_BEG)
  if(RDP(u8) == RDP_LVL0)
  {
    UnlockROMOp();
    UnlockOptOp();
    FLASH->CR |= FLASH_CR_OPTER;
    FLASH->CR |= FLASH_CR_STRT;
    while(isROMBsy()){} ClrROMOpSReg();
    FLASH->CR = FLASH_CR_OPTPG |
                FLASH_CR_OPTWRE;
    RDP(u16)  = RDP_LVL1;
    while(isROMBsy()){} ClrROMOpSReg();
    WRP[0] = WRP_SECT << 8 | (u8)~WRP_SECT;
    while(isROMBsy()){} ClrROMOpSReg();
    LockNVMOp();
    UpdSysOpt();
  }
}


Она после первого включения устройства настраивает байты опций, в том числе ставит защиту от чтения/записи.

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


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

5 часов назад, Arlleex сказал:

Видимо, не зря они сами пишут об этом

Цитата

3.3.1 Read protection
The read protection is activated by setting the RDP option byte and then, by applying a system reset to reload the new RDP option byte.
Note: If the read protection is set while the debugger is still connected through SWD, apply a POR (power-on reset) instead of a system reset.

Сильно не разбирался, но действительно, когда прошиваю STM32L151 через SWD при помощи консольного варианта ST-Link и установкой защиты Level 1, в конце программирования команда рестарта МК не выполняется (хотя есть, и ST-Link дергает за ресет). МК находится в "подвешенном" состоянии, пока не передернешь питание.

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


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

5 часов назад, Baser сказал:

МК находится в "подвешенном" состоянии, пока не передернешь питание

Коллеги, простите, я правильно понял, что не работает внешняя железная нога сброса?????

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


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

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

Коллеги, простите, я правильно понял, что не работает внешняя железная нога сброса?????

Да, именно так. Я пробовал сбрасывать МК с помощью шупа, подключенного к земле и не было никакой реакции.

7 часов назад, Baser сказал:

МК находится в "подвешенном" состоянии, пока не передернешь питание.

Или пока не сбросишь с помощью OBL_LAUNCH.

Пробовал генерировать внутренний сигнал сброса через NVIC, но это ничего не дало. Хотя сегодня ещё проверю, может быть при этом я забыл отключить poll в OpenOCD.

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


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

49 минут назад, makc сказал:

Да, именно так. Я пробовал сбрасывать МК с помощью шупа, подключенного к земле и не было никакой реакции.

Удивительно! Это бросает вызов моей системе знаний об устройстве мира. Выходит, что в некоторых ситуациях внешний сторожевой пёс не сможет привести устройство в норму?

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


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

Получается что так. Но есть ведь и внутренний. А вообще надёжнее чем передёргивание питания ничего нет. :boredom:

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


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

6 минут назад, makc сказал:

Но есть ведь и внутренний.

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

8 минут назад, makc сказал:

А вообще надёжнее чем передёргивание питания ничего нет. :boredom:

Ох, где-то я уже слышали или читал об этом... Видимо, да, вы правы!

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


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

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

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

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

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

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

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

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

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

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