Jump to content

    
Sign in to follow this  
esaulenka

STM32F2xx, запись во флеш

Recommended Posts

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

 

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

  * @file    stm32f2xx_flash.c
  * @version V1.0.0
  * @date    18-April-2011

 

Вызываю

FLASH_Unlock ()

FLASH_EraseSector () - возвращает complete

FLASH_Unlock ()

FLASH_ProgramByte ()

 

ProgramByte выпадает в hardfault на команде branch на FLASH_WaitForLastOperation()

 

    /* if the previous operation is completed, proceed to program the new data */
    FLASH->CR &= CR_PSIZE_MASK;
    FLASH->CR |= FLASH_PSIZE_BYTE;
    FLASH->CR |= FLASH_CR_PG;
  
    *(__IO uint8_t*)Address = Data;
        
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation();

Пробовал перемещать весь модуль stm32f2xx_flash в ОЗУ, не помогло. (а надо ли? в reference manual сказано, что к flash нельзя обращаться в момент записи, но в примерах EEPROM Emulation ничего для этого не предпринимается).

 

Кто-нибудь вообще запись во флеш делал?

Share this post


Link to post
Share on other sites

Ну я делал, причем даже нулевой сектор прошивал, выполняясь при этом из флеша. Правда писал я через FLASH_ProgramWord, а не FLASH_ProgramByte, может в этом проблема..

Share this post


Link to post
Share on other sites
Ну я делал, причем даже нулевой сектор прошивал, выполняясь при этом из флеша. Правда писал я через FLASH_ProgramWord, а не FLASH_ProgramByte, может в этом проблема..

Спасибо, обнадёживает :-)

word'ами тоже пробовал, разницы никакой.

 

 

Скорее всего, в момент прошивки флеш ядро обращается к обработчику какого-нибудь прерывания.

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

Share this post


Link to post
Share on other sites

Я вот так пишу флэшь на STM32F205.

Проблем не было.

 

#define PAGE_SZ           ( (uint32_t)0x4000 )                    // Размер секторов 0..3 равен 16 кБ
#define CONST0_START      ( (uint32_t)0x08004000 )                // start address from sector1
#define CONST0_ID         FLASH_Sector_1
#define CONST1_START      ( CONST0_START + PAGE_SZ )              // start address from sector2
#define CONST1_ID         FLASH_Sector_2
#define VOLTAGE_RANGE     (uint8_t)VoltageRange_3                 // Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word


/* --- wr_sector() ---------------------------------------------------------------------------------------- **
* Запись сектора
*  adr - адрес во флэш, куда писать
*  dat - адрес от куда писать
*  len - размер данных в байтах
* -------------------------------------------------------------------------------------------------------- */
static FLASH_Status wr_sector( uint32_t adr, uint32_t *dat, int len )
{
FLASH_Status fs;

 for ( fs = FLASH_COMPLETE; len; len -= sizeof( uint32_t ), adr += sizeof( uint32_t ), dat++ )
   if (( fs =  FLASH_ProgramWord( adr, *dat )) != FLASH_COMPLETE )
     break;
 return( fs );
}

/* --- wr_const() ----------------------------------------------------------------------------------------- **
* Запись констант в копию number (0 или 1 )
* -------------------------------------------------------------------------------------------------------- */
static FLASH_Status wr_const( int number )
{
uint32_t id, adr;
FLASH_Status fs;

 id = CONST0_ID;
 adr = CONST0_START;
 if ( !number )
 { id = CONST1_ID;
   adr = CONST1_START;
 }
 FLASH_Unlock();
 if (( fs = FLASH_EraseSector( id, VOLTAGE_RANGE )) == FLASH_COMPLETE )
   fs = wr_sector( adr, (uint32_t *)&r_const, sizeof( ATM_Constant ));
 FLASH_Lock();
 return( fs );
}

Добавлено: Заметил опечатку в функции wr_const(),

  if ( !number )

а надо

  if ( number )

правда это ни на что не влияет, просто поменяются местами блоки.

Share this post


Link to post
Share on other sites

Вот такой кусок у меня работает:

 

INT8 FlashWriteBlock(UINT32 WriteAddr, UINT8 * pBuffer, UINT32 byteCnt)
{
....
  // Disable interrupts to prevent flash programming errors from firing
  __disable_interrupt();
  FLASH_Unlock();
  UINT32 FlashEnd = FlashGetEndAddr();
  for (UINT32 WriteCount = 0;(WriteCount < byteCnt) && (WriteAddr < FlashEnd); WriteCount += 4)
  {
    // Clear pending flags incase they were triggered
    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                    FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
    /* Program the data received into STM32F10x Flash */
    FLASH_ProgramWord(WriteAddr, *(UINT32*)pBuffer);
    if (*(uint32_t*)WriteAddr != *(uint32_t*)pBuffer)
    {
      FLASH_Lock();
      __enable_interrupt();
      return -2;
    }
    WriteAddr += 4;
    pBuffer += 4;
  }
  FLASH_Lock();
  __enable_interrupt();
  return 0;
}

Share this post


Link to post
Share on other sites
ProgramByte выпадает в hardfault на команде branch на FLASH_WaitForLastOperation()

 

Мда... Стоило опечататься в одном нолике в дефайне FLASH_BASE_ADDRESS, и ничего не работает...

Поменял на стандартный библиотечный FLASH_BASE - и всё стало гораздо приятнее.

 

За предоставленный код всем спасибо!

Share this post


Link to post
Share on other sites

Добрый день! Немного не в тему, ну может подскажите.Возможна ли работа с flash при включенной защите кода?У меня вопрос возник с stm32f405 - храню настройки в памяти контроллера, но при включении защиты кода все перестает работать...

Edited by Stirliz85

Share this post


Link to post
Share on other sites

защита кода влияет на внешний доступ, внутри программы все читается и пишется во flash. защита 2lvl.

после установки защиты перезагружал?

Edited by zatylok

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this