Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAP программирование Option Bytes (STM32F1)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Alt.F4
Здравствуйте.

Никак не получается программно изменить Option Bytes.
Использую примеры ST, но они не работают (по адресам 0x1FFF F800 - 0x1FFF F80F ничего не меняется):
FLASH_Unlock();
FLASH_EnableWriteProtection(FLASH_WRProt_Pages0to1 |FLASH_WRProt_Pages2to3);
NVIC_SystemReset();


Если перед записью добавить FLASH_EraseOptionBytes(), то каким-то чудесным образом включается защита от чтения и даже последующая FLASH_ReadOutProtection(DISABLE) не помогает ее выключить.

Может кто-то сталкивался с подобным?
Спасибо.
Сергей Борщ
Цитата(Alt.F4 @ Jan 15 2015, 09:31) *
Никак не получается программно изменить Option Bytes.
Использую примеры ST
Может именно поэтому? biggrin.gif

Я писал по документации, у меня все пишется:
Код
bool flash::rewrite_option_bytes(OB_TypeDef const * new_values)
{
    FLASH->OPTKEYR = 0x45670123;
    FLASH->OPTKEYR = 0xCDEF89AB;
    if(!(FLASH->CR & FLASH_CR_OPTWRE))
        return false;
    FLASH->CR |= FLASH_CR_OPTER;
    FLASH->CR |= FLASH_CR_STRT;
    if(!wait(PAGE_ERASE_TIMEOUT))
        return false;
    uint16_t const * pNew = (uint16_t const *)new_values;
    uint16_t * pOld = (uint16_t *)OB;
    for(uint_fast8_t i = 0; i < sizeof(*OB) / sizeof(uint16_t); ++i)
    {
        if((*pNew & 0xFF) != (*pOld & 0xFF))
        {
            FLASH->CR = FLASH_CR_OPTPG;
            *pOld = *pNew;
            wait();
            FLASH->CR = 0;
            if((*pNew & 0xFF) != (*pOld & 0xFF))
                return false;
        }
        pNew++;
        pOld++;
    }
    return true;
}



Цитата(Alt.F4 @ Jan 15 2015, 09:31) *
Если перед записью добавить FLASH_EraseOptionBytes(), то каким-то чудесным образом включается защита от чтения
Она включается полностью в соответствии с документацией. "Чтение документации вслух - 100 евро/час".
Alt.F4
Хочется использовать стандартную библиотеку, чтобы код был максимально читабелен и была высокая переносимость.

Цитата
Она включается полностью в соответствии с документацией.
А вот и неправда, в описании сказано "This functions erases all option bytes except the Read protection (RDP)." Т.е. она просто не затрагивает Read protection, да и в исходниках видно, что идет проверка, установлена ли защита и после стирания ячеек, она снова устанавливается, если была.

Еще вопрос, почему все байты продублированы с инверсией? При записи значений, они автоматически инвертируются?
Спасибо.
Сергей Борщ
Цитата(Alt.F4 @ Jan 15 2015, 11:42) *
Хочется использовать стандартную библиотеку, чтобы код был максимально читабелен и была высокая переносимость.
Мыши плакали, кололись... Про читабельность вообще молчу - экран исходника на действие, которое можно описать одной строкой. Переносимость тоже под вопросом.

Цитата(Alt.F4 @ Jan 15 2015, 11:42) *
А вот и неправда, в описании сказано "This functions erases all option bytes except the Read protection (RDP)."
В описании к чему? К библиотеке? Ну и продолжайте топтаться по граблям. Потому что в описании на процессор сказано, что Option Bytes стираются все целиком, что стертое состояние байтов RDP означает включенную защиту и попытка переписать их в состояние "Защита отключена" приводит к полному стиранию флеша перед записью нового значения. Но читать документацию - это для слабых.
Цитата(Alt.F4 @ Jan 15 2015, 11:42) *
Еще вопрос, почему все байты продублированы с инверсией? При записи значений, они автоматически инвертируются?
"Чтение документации вслух - 100 евро в час".
STM32F100xx value line Flash programming
Alt.F4
Да, в доке написано, что при стирании Option Bytes включается Read Protection, а при выключении этой защиты стирается флэш.
Однако проведя множество экспериментов удалось определить, что функция FLASH_EraseOptionBytes() работает как сказано в описании и не включает защиту от чтения при стирании Option Bytes, но есть один момент.

if(FLASH_GetWriteProtectionOptionByte() != ~FLASH_WRProt_Pages0to1) {
FLASH_Unlock();
FLASH_EraseOptionBytes();
FLASH_EnableWriteProtection(FLASH_WRProt_Pages0to1);
NVIC_SystemReset();}

Приведенный выше листинг работает правильно и в результате мы получаем выключенную защиту от чтения и включенную защиту от записи.
Правда немного смущает, что:
1) в дебагере IAR после NVIC_SystemReset() указатель не прыгает в Reset, а продолжает дальше выполнение кода (Почему?)
2) в остальных ячейках nWRP1-nWRP3 (в nWRP0 и WRP0 все верно) записаны 0xFF, хотя по идее там автоматом должна выставляться инверсия 0x00.

И самый изюм всего, если написать неверное условие (например, if(FLASH_GetWriteProtectionOptionByte() != 0), то на NVIC_SystemReset(); дебаг прекращается и мы ловим защиту от чтения.
Как это можно объяснить?
Спасибо.
Сергей Борщ
Цитата(Alt.F4 @ Jan 16 2015, 13:37) *
функция FLASH_EraseOptionBytes() работает как сказано в описании и не включает защиту от чтения при стирании Option Bytes,
Поздравляю, вы нашли брешь в защите sm.gif

Цитата(Alt.F4 @ Jan 16 2015, 13:37) *
2) в остальных ячейках nWRP1-nWRP3 (в nWRP0 и WRP0 все верно) записаны 0xFF, хотя по идее там автоматом должна выставляться инверсия 0x00.
После стирания не должна. И это тоже написано в документации. Я только что еще раз прочитал и убедился в этом, но сюда выкладывать выдержку не буду, чтобы вы тоже прочитали сами. Пока будете искать это место в документации, попутно найдете еще много полезного.

Цитата(Alt.F4 @ Jan 16 2015, 13:37) *
Как это можно объяснить?
При "правильном" условии оно не выполняется и стирания со всеми вытекающими не происходит.
ViKo
А как запрограммировать Option Bytes средствами самого Keil? Добавил я алгоритм Flash Options, а что ему подсовывать? В STLink Utility Option Bytes установил, и готово.
Ага... кажется, нужно задать Init File.
Сергей Борщ
Цитата(ViKo @ Jan 16 2015, 14:43) *
средствами самого Keil?
Я не знаю. У меня Eclipse+OpenOCD, у Alt.F4 IAR.
Alt.F4
Цитата
Поздравляю, вы нашли брешь в защите
Это скорее ошибка в доке, т.к. функция работает как описано в библиотеке.

Цитата
После стирания не должна. И это тоже написано в документации. Я только что еще раз прочитал и убедился в этом, но сюда выкладывать выдержку не буду, чтобы вы тоже прочитали сами. Пока будете искать это место в документации, попутно найдете еще много полезного.
После стриния я делаю запись EnableWriteProtection(), по которой должно быть: "The FPEC takes the LSB and automatically computes the MSB (which is the complement of
the LSB) and starts the programming operation." Но это не происходит...

Цитата
При "правильном" условии оно не выполняется и стирания со всеми вытекающими не происходит.
Я же дебагером захожу в него, условие выполняется. Да и как ему не выполняться, если по умолчанию защиты от записи нет.
ViKo
Цитата(Сергей Борщ @ Jan 16 2015, 15:53) *
Я не знаю. У меня Eclipse+OpenOCD, у Alt.F4 IAR.

Это понятно, но принципы те же. Неужели, чтобы задать защиту программы, ее нужно сначала запустить на выполнение?

Нашел. Нужно добавить в проект файл ...OPT.s
А дальше Keil-овский Wizard предложит свои услуги.
Аналогично для программирования Flash OTP, там свой файлик, ...OTP.s

Заблокировал прибор. Теперь не могу ни очистить флэш, ни...чего. И под сбросом не получается, сброс такой...
Пошел качать Flash Loader Demonstrator.
Сергей Борщ
Цитата(Alt.F4 @ Jan 16 2015, 14:55) *
Это скорее ошибка в доке, т.к. функция работает как описано в библиотеке.
Чудесатые чудеса. У меня все работает четко по документации: защиту снял - память стерлась.
Цитата(Alt.F4 @ Jan 16 2015, 14:55) *
После стриния я делаю запись EnableWriteProtection(), по которой должно быть: "The FPEC takes the LSB and automatically computes the MSB (which is the complement of the LSB) and starts the programming operation." Но это не происходит...
Я не знаю, что делает эта библиотечная функция. Вероятно она пишет только те байты, которые отличаются от 0xFF, оставляя остальные стертыми. У вас же есть ее исходник, посмотрите там.
Цитата(Alt.F4 @ Jan 16 2015, 14:55) *
Я же дебагером захожу в него, условие выполняется. Да и как ему не выполняться, если по умолчанию защиты от записи нет.
Вам виднее, но я в чудеса не верю. Защита от записи включается после сброса. Возможно вы наблюдаете все это не сбрасывая процессор.


Цитата(ViKo @ Jan 16 2015, 15:48) *
И под сбросом не получается, сброс такой...
Хм. У меня OpenOCD снимает защиту через SWD. На разъем сброс не выведен.
ViKo
Цитата(Сергей Борщ @ Jan 16 2015, 16:52) *
Хм. У меня OpenOCD снимает защиту через SWD. На разъем сброс не выведен.

Я задал Level 2. При этом, кажется, отрубается JTAG (SWD).
Alt.F4
Код
/**
  * @brief  Erases the FLASH option bytes.
  * @note   This functions erases all option bytes except the Read protection (RDP).
  * @note   This function can be used for all STM32F10x devices.
  * @param  None
  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
  */
FLASH_Status FLASH_EraseOptionBytes(void)
{
  uint16_t rdptmp = RDP_Key;

  FLASH_Status status = FLASH_COMPLETE;

  /* Get the actual read protection Option Byte value */
  if(FLASH_GetReadOutProtectionStatus() != RESET)
  {
    rdptmp = 0x00;  
  }

  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation(EraseTimeout);
  if(status == FLASH_COMPLETE)
  {
    /* Authorize the small information block programming */
    FLASH->OPTKEYR = FLASH_KEY1;
    FLASH->OPTKEYR = FLASH_KEY2;
    
    /* if the previous operation is completed, proceed to erase the option bytes */
    FLASH->CR |= CR_OPTER_Set;
    FLASH->CR |= CR_STRT_Set;
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation(EraseTimeout);
    
    if(status == FLASH_COMPLETE)
    {
      /* if the erase operation is completed, disable the OPTER Bit */
      FLASH->CR &= CR_OPTER_Reset;
      
      /* Enable the Option Bytes Programming operation */
      FLASH->CR |= CR_OPTPG_Set;
      /* Restore the last read protection Option Byte value */
      OB->RDP = (uint16_t)rdptmp;
      /* Wait for last operation to be completed */
      status = FLASH_WaitForLastOperation(ProgramTimeout);

      if(status != FLASH_TIMEOUT)
      {
        /* if the program operation is completed, disable the OPTPG Bit */
        FLASH->CR &= CR_OPTPG_Reset;
      }
    }
    else
    {
      if (status != FLASH_TIMEOUT)
      {
        /* Disable the OPTPG Bit */
        FLASH->CR &= CR_OPTPG_Reset;
      }
    }  
  }
  /* Return the erase status */
  return status;
}
Сергей Борщ
Цитата(ViKo @ Jan 16 2015, 15:56) *
Я задал Level 2. При этом, кажется, отрубается JTAG (SWD).
Какой Level 2 у STM32F1?
ViKo
Цитата(Сергей Борщ @ Jan 16 2015, 17:32) *
Какой Level 2 у STM32F1?

Какой STM32F1? sm.gif
Качаю DfuSe, может, с ней удастся разблокировать без подпайки к ноге BOOT0 питания. От попал!
STM32F207
Сергей Борщ
Цитата(ViKo @ Jan 16 2015, 16:39) *
Какой STM32F1? sm.gif
Из заголовка темы. Default value до тех пор, пока не будет переопределено sm.gif
Alt.F4
Интересную вещь еще заметил, если стоит защита от чтения, то после коннекта/дисконнекта по SWD, приложение перестает выполняться, даже RESET не помогает. Надо снимать питание.
Это так и должно быть?
Сергей Борщ
Цитата(ViKo @ Jan 16 2015, 16:39) *
От попал!
STM32F207
В топку. В другой раз осторожнее (или документацию читайте внимательнее):
Цитата
When the read protection Level 2 is set by writing 0xCC to the RDP option byte:
– All protections provided by Level 1 are active.
Booting from system memory is not allowed anymore. << Забудьте про BOOT0
– JTAG, SWV (single-wire viewer) are disabled.
User option bytes can no longer be changed. << И это навсегда

ViKo
Цитата(Сергей Борщ @ Jan 16 2015, 17:41) *
Из заголовка темы. Default value до тех пор, пока не будет переопределено sm.gif

#define STM32F1XX
#define STM32F2XX
#define STM32F3XX
#define STM32F4XX

И DfuSe не видит моего дивайса. Да, без BOOT0 не обойтись. Надо на будущее предусмотреть секретное подключение Hi на эту ножку.
Еще с размаху и второй прибор запрограммировал. Опции убрал, а скопмилировать забыл. Возьму третий... biggrin.gif
Сергей Борщ
Цитата(Alt.F4 @ Jan 16 2015, 16:50) *
Это так и должно быть?
А не отключаете ли вы случайно HSI?
ViKo
И что теперь, не стереть flash?! Шо за хня!?
ViKo
А если создать в своей программе функцию стирания памяти, и запускать ее после неких секретных манипуляций? Тогда возможно случайное стирание, что нехорошо. Но это лучше, чем "камень".
Жду советов. Неужели только "в топку"?
Сергей Борщ
Цитата(ViKo @ Jan 16 2015, 19:02) *
Жду советов. Неужели только "в топку"?
Нет оснований не верить документации. Доктор сказал - "в морг", значит в морг.
ViKo
Пошарил по Интернету... какая, однако, мощная защита. rolleyes.gif
Выпаивать, запаивать, программировать. Добавилось забот.
После этого... разве найдется кто-то в здравом уме, чтобы так безвозвратно рубить концы. maniac.gif

P.S. за одного (у)битого двух не(до)битых дают
P.P.S. А был бы свой загрузчик в программе, мог бы обновляться. Пора заняться и им!
toweroff
Цитата(ViKo @ Jan 16 2015, 20:02) *
А если создать в своей программе функцию стирания памяти, и запускать ее после неких секретных манипуляций?

если ставится максимальный црп, то очень желательно (если нет бута)
имхо
ViKo
Цитата(toweroff @ Jan 17 2015, 03:57) *
если ставится максимальный црп, то очень желательно (если нет бута)
имхо

Не поможет. Старое сотру, а нового все равно не записать.

DfuSe проверить не смогу, потому, что использую не те ноги МК. Но написано же, загрузка по ВOOT отключается. Странно, зачем столько защит? Как однократно программируемая память.
adnega
Цитата(Alt.F4 @ Jan 16 2015, 14:37) *
Да, в доке написано, что при стирании Option Bytes включается Read Protection, а при выключении этой защиты стирается флэш.
Однако...

Попробуйте после этого временно сбросить питание и получите Level1)

Цитата(Alt.F4 @ Jan 16 2015, 14:37) *
после NVIC_SystemReset() указатель не прыгает в Reset, а продолжает дальше выполнение кода (Почему?)

А кто обещал, что NVIC_SystemReset куда-то "прыгает"?
Это всего лишь возможность на некоторое время просадить NRST-пин на землю. Если у вас там жесткая "1", то RESETа не будет)
Alt.F4
Цитата
Попробуйте после этого временно сбросить питание и получите Level1)
Что значит Level1? Попробовал, все ОК, флэш не стерта и защита от чтения снята.

Цитата
А кто обещал, что NVIC_SystemReset куда-то "прыгает"?
Это всего лишь возможность на некоторое время просадить NRST-пин на землю. Если у вас там жесткая "1", то RESETа не будет)
В других местах кода прыгает в начало программы.
Сергей Борщ
Цитата(Alt.F4 @ Jan 17 2015, 18:17) *
В других местах кода прыгает в начало программы.
Я все понял. Никакие билиотеки не смогут обмануть производителя. При попытке снять защиту от чтения память стирается и процессор начинает исполнять команду с кодом 0xFFFF. А отладчик тупо ставит точку останова на адрес после вызова функции NVIC_SystemReset(). И поскольку память стерта, то и на месте вызова этой функции тоже стоит код операции 0xFFFF и ваша программа в NVIC_SystemReset() не входит (потому что больше нет ни NVIC_SystemReset() ни команды перехода на нее) - ядро просто тупо выполняет код 0xFFFF и переходит к следующему адресу, на котором встречает точку останова. А отладчик тупо продолжает показывать вам высокоуровневый исходник. Посмотрите содержимое памяти по адресам, из которых выполняется программа в окне memory или как оно называется в IARе.
Alt.F4
Сергей Борщ, не угадали, когда флэш стирается или включается защита от чтения на NVIC_SystemReset дебаг прекращается полностью.
Кстати, исходник библиотеки я скинул выше.
Сергей Борщ
Цитата(Alt.F4 @ Jan 20 2015, 00:04) *
Кстати, исходник библиотеки я скинул выше.
В нем нет ничего уникального. Такими же действиями openOCD снимает защиту от чтения. Память при этом автоматически стирается. Никакой магии.
Alt.F4
По всей видимости мне надо видео снять, как эта магия происходит в дебагере?
Сергей Борщ
Цитата(Alt.F4 @ Jan 20 2015, 09:08) *
По всей видимости мне надо видео снять, как эта магия происходит в дебагере?
Снимите. Только шагайте не по исходнику, а по дизассемблеру. У меня все стиралось в соответствии с документацией.
Alt.F4
Цитата
Снимите. Только шагайте не по исходнику, а по дизассемблеру. У меня все стиралось в соответствии с документацией.
Снял, вот ссылка на видео.
1. Дебаг по функциям библиотеки, показываю, что защита от записи не установилась, а все остальные позиции Option Byte прописались как надо.
2. Дебаг того же самого по дизассемблеру подвисает на самом интересном месте, но по итогу мы получаем тоже самое.
3. Пишем любое другое условие и ловит защиту от записи, причем без изменения других позиций Option Byte, магия?
Спасибо.

P.S. Чтобы обнулить Option Byte, необходимо изменить состояние Read Protection, поэтому в ST-Link Utility я сперва ее устанавливаю и затем сбрасываю.
Alt.F4
Если кому-нибудь интересно, то продолжение здесь.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.