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

IAP программирование Option Bytes (STM32F1)

Здравствуйте.

 

Никак не получается программно изменить Option Bytes.

Использую примеры ST, но они не работают (по адресам 0x1FFF F800 - 0x1FFF F80F ничего не меняется):

FLASH_Unlock();

FLASH_EnableWriteProtection(FLASH_WRProt_Pages0to1 |FLASH_WRProt_Pages2to3);

NVIC_SystemReset();

 

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

 

Может кто-то сталкивался с подобным?

Спасибо.

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


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

Никак не получается программно изменить Option Bytes.

Использую примеры ST

Может именно поэтому? :biggrin:

 

Я писал по документации, у меня все пишется:

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;
}

 

 

Если перед записью добавить FLASH_EraseOptionBytes(), то каким-то чудесным образом включается защита от чтения
Она включается полностью в соответствии с документацией. "Чтение документации вслух - 100 евро/час".

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


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

Хочется использовать стандартную библиотеку, чтобы код был максимально читабелен и была высокая переносимость.

 

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

 

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

Спасибо.

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


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

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

 

А вот и неправда, в описании сказано "This functions erases all option bytes except the Read protection (RDP)."
В описании к чему? К библиотеке? Ну и продолжайте топтаться по граблям. Потому что в описании на процессор сказано, что Option Bytes стираются все целиком, что стертое состояние байтов RDP означает включенную защиту и попытка переписать их в состояние "Защита отключена" приводит к полному стиранию флеша перед записью нового значения. Но читать документацию - это для слабых.

Еще вопрос, почему все байты продублированы с инверсией? При записи значений, они автоматически инвертируются?
"Чтение документации вслух - 100 евро в час".

STM32F100xx value line Flash programming

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


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

Да, в доке написано, что при стирании 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(); дебаг прекращается и мы ловим защиту от чтения.

Как это можно объяснить?

Спасибо.

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


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

функция FLASH_EraseOptionBytes() работает как сказано в описании и не включает защиту от чтения при стирании Option Bytes,
Поздравляю, вы нашли брешь в защите :)

 

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

 

Как это можно объяснить?
При "правильном" условии оно не выполняется и стирания со всеми вытекающими не происходит.

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


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

А как запрограммировать Option Bytes средствами самого Keil? Добавил я алгоритм Flash Options, а что ему подсовывать? В STLink Utility Option Bytes установил, и готово.

Ага... кажется, нужно задать Init File.

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


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

средствами самого Keil?
Я не знаю. У меня Eclipse+OpenOCD, у Alt.F4 IAR.

 

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


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

Поздравляю, вы нашли брешь в защите
Это скорее ошибка в доке, т.к. функция работает как описано в библиотеке.

 

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

the LSB) and starts the programming operation." Но это не происходит...

 

При "правильном" условии оно не выполняется и стирания со всеми вытекающими не происходит.
Я же дебагером захожу в него, условие выполняется. Да и как ему не выполняться, если по умолчанию защиты от записи нет.

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


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

Я не знаю. У меня Eclipse+OpenOCD, у Alt.F4 IAR.

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

 

Нашел. Нужно добавить в проект файл ...OPT.s

А дальше Keil-овский Wizard предложит свои услуги.

Аналогично для программирования Flash OTP, там свой файлик, ...OTP.s

 

Заблокировал прибор. Теперь не могу ни очистить флэш, ни...чего. И под сбросом не получается, сброс такой...

Пошел качать Flash Loader Demonstrator.

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


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

Это скорее ошибка в доке, т.к. функция работает как описано в библиотеке.
Чудесатые чудеса. У меня все работает четко по документации: защиту снял - память стерлась.

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

Я же дебагером захожу в него, условие выполняется. Да и как ему не выполняться, если по умолчанию защиты от записи нет.
Вам виднее, но я в чудеса не верю. Защита от записи включается после сброса. Возможно вы наблюдаете все это не сбрасывая процессор.

 

 

И под сбросом не получается, сброс такой...
Хм. У меня OpenOCD снимает защиту через SWD. На разъем сброс не выведен.

 

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


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

Хм. У меня OpenOCD снимает защиту через SWD. На разъем сброс не выведен.

Я задал Level 2. При этом, кажется, отрубается JTAG (SWD).

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


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

/**
  * @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;
}

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


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

Я задал Level 2. При этом, кажется, отрубается JTAG (SWD).
Какой Level 2 у STM32F1?

 

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


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

Какой Level 2 у STM32F1?

Какой STM32F1? :)

Качаю DfuSe, может, с ней удастся разблокировать без подпайки к ноге BOOT0 питания. От попал!

STM32F207

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


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

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...