Hi,
I would like to store few kB (application settings) in internal flash region of STM32F4 chip it self. I know I can access flash address space via base address 0x08000000, problem is to find some reserved space that is safe to be used for this purpose.
I was diggin in source NETMF_for_STM32, file STM32F4_BlConfig.cpp and found out this configuration of blockstorage:
const BlockRange g_STM32F4_BlockRange3[] =
{
{ BlockRange::BLOCKTYPE_CODE , 0, 2 }, // 08020000 CLR 384k
{ BlockRange::BLOCKTYPE_DEPLOYMENT, 3, 6 }, // 08080000 deployment 512k
//{ BlockRange::BLOCKTYPE_STORAGE_A , 5, 5 }, // 080C0000 storage A 128k
//{ BlockRange::BLOCKTYPE_STORAGE_B , 6, 6 }, // 080E0000 storage B 128k
};
What are regions storage A, and B for ?
Thanks for any reply.
Jan
Both of these areas are used by ExtendedWeakReference storage subsystem.
@ Architect - I tought that ExtendedWeakReference storage doesn’t work on Cerberus familly ? Or I’m wrong ? And if this place is dedicated to EWR that If i’m not using it I can use storage B without any trouble ? Or not ?
Yes and that is why they are commented out
It is commented out - not used.
Then expect InternalStorage class from me on Codeshare
Thanks guys a lot!
vqp
August 21, 2012, 5:06pm
#8
Hi all,
Johny have you made any progress on the InternalStorage class? If not , can you share whatever code you have so we can start from there? Is it possible to implement it in managed code?
Regards.
vqp
August 21, 2012, 6:49pm
#10
Ok, is clear that EWR would be overkill for the cerberus architecture, but I just need 1kb or so to store configuration parameters, and I wonder if I can use the unused flash segments in the chip and it seems that Johny has a point there.
Well currenty have trouble unlocking flash for write operation. My current code is:
using System;
using Microsoft.SPOT;
using GHI.OSHW.Hardware;
using GHI.OSHW.Hardware.LowLevel;
namespace STM32F4.IO
{
public static class InternalStorage
{
private const uint StorageAddressBase = 0x080C0000;
private const uint StorageSize = 0x40000;
private const uint StorageAddressMax = StorageAddressBase + StorageSize - 1;
//definitions taken from http://www.keil.com/dd/docs/arm/st/stm32f4xx/stm32f4xx.h
//#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
//#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
//#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000)
//#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00)
//#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
//typedef struct
//{
// __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */
// __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */
// __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */
// __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */
// __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */
// __IO uint32_t OPTCR; /*!< FLASH option control register, Address offset: 0x14 */
//} FLASH_TypeDef;
private const UInt32 Flash_ACR = 0x8023C00;
private const UInt32 Flash_KEYR = 0x8023C04;
private const UInt32 Flash_OPTKEYR = 0x8023C08;
private const UInt32 Flash_SR = 0x8023C0C;
private const UInt32 Flash_CR = 0x8023C10;
private const UInt32 Flash_OPTCR = 0x8023C14;
/******************* Bits definition for FLASH_SR register ******************/
private const UInt32 FLASH_SR_EOP = 0x00000001;
private const UInt32 FLASH_SR_SOP = 0x00000002;
private const UInt32 FLASH_SR_WRPERR = 0x00000010;
private const UInt32 FLASH_SR_PGAERR = 0x00000020;
private const UInt32 FLASH_SR_PGPERR = 0x00000040;
private const UInt32 FLASH_SR_PGSERR = 0x00000080;
private const UInt32 FLASH_SR_BSY = 0x00010000;
/******************* Bits definition for FLASH_CR register ******************/
private const UInt32 FLASH_CR_PG = 0x00000001;
private const UInt32 FLASH_CR_SER = 0x00000002;
private const UInt32 FLASH_CR_MER = 0x00000004;
private const UInt32 FLASH_CR_SNB_0 = 0x00000008;
private const UInt32 FLASH_CR_SNB_1 = 0x00000010;
private const UInt32 FLASH_CR_SNB_2 = 0x00000020;
private const UInt32 FLASH_CR_SNB_3 = 0x00000040;
private const UInt32 FLASH_CR_PSIZE_0 = 0x00000100;
private const UInt32 FLASH_CR_PSIZE_1 = 0x00000200;
private const UInt32 FLASH_CR_STRT = 0x00010000;
private const UInt32 FLASH_CR_EOPIE = 0x01000000;
private const UInt32 FLASH_CR_LOCK = 0x80000000;
private const UInt32 FLASH_KEY1 = 0x45670123;
private const UInt32 FLASH_KEY2 = 0xCDEF89AB;
private const UInt32 FLASH_OPT_KEY1 = 0x08192A3B;
private const UInt32 FLASH_OPT_KEY2 = 0x4C5D6E7F;
private const UInt32 FLASH_PSIZE_BYTE = 0x00000000;
private const UInt32 FLASH_PSIZE_HALF_WORD = 0x00000100;
private const UInt32 FLASH_PSIZE_WORD = 0x00000200;
private const UInt32 FLASH_PSIZE_DOUBLE_WORD = 0x00000300;
private const UInt32 CR_PSIZE_MASK = 0xFFFFFCFF;
private static Register ACR, KEYR, OPTKEYR, SR, CR, OPTCR;
/// <summary>
/// Static construtor to check right platform
/// </summary>
static InternalStorage()
{
CheckPlatform();
ACR = new Register(Flash_ACR);
KEYR = new Register(Flash_KEYR);
OPTKEYR = new Register(Flash_OPTKEYR);
SR = new Register(Flash_SR);
CR = new Register(Flash_CR);
OPTCR = new Register(Flash_OPTCR);
}
/// <summary>
/// Check if code is running on CERB
/// </summary>
private static void CheckPlatform()
{
if (DeviceInfo.GetDeviceID() != DeviceID.FEZ_CERB)
{
throw new NotSupportedException();
}
}
/// <summary>
/// An internal flash size bytes for storage.
/// </summary>
public static uint Length
{
get
{
return StorageSize;
}
}
//void FLASH_Unlock(void)
//{
// if((FLASH->CR & FLASH_CR_LOCK) != RESET)
// {
// /* Authorize the FLASH Registers access */
// FLASH->KEYR = FLASH_KEY1;
// FLASH->KEYR = FLASH_KEY2;
// }
//}
private static void UnlockFlash()
{
if((CR.Read() & FLASH_CR_LOCK) != 0)
{
KEYR.Write(FLASH_KEY1);
KEYR.Write(FLASH_KEY2);
}
}
//void FLASH_Lock(void)
//{
// /* Set the LOCK Bit to lock the FLASH Registers access */
// FLASH->CR |= FLASH_CR_LOCK;
//}
private static void LockFlash()
{
CR.Write(CR.Read() | FLASH_CR_LOCK);
}
/// <summary>
/// Reading bytes from internal storage
/// </summary>
/// <param name="buffer">An initialized byte buffer, where data will be stored from flash.</param>
/// <param name="storageAddress">An address of storage</param>
/// <param name="bufferIndex"></param>
/// <param name="lenght"></param>
public static void Read(byte[] buffer, uint storageAddress, int bufferIndex, int lenght)
{
uint address = storageAddress + StorageAddressBase;
uint addressEnd = storageAddress + StorageAddressBase + (uint)lenght;
if (address > StorageAddressMax)
{
throw new IndexOutOfRangeException();
}
AddressSpace.Read(address, buffer, bufferIndex, lenght);
}
public static void Write(byte[] buffer, uint storageAddress, int bufferIndex, int lenght)
{
uint address = storageAddress + StorageAddressBase;
if (address > StorageAddressMax)
{
throw new IndexOutOfRangeException();
}
try
{
UnlockFlash();
/*
* FLASH->CR &= CR_PSIZE_MASK;
FLASH->CR |= FLASH_PSIZE_BYTE;
FLASH->CR |= FLASH_CR_PG;
* */
CR.Write(CR.Read() & CR_PSIZE_MASK);
CR.Write(CR.Read() | FLASH_PSIZE_BYTE);
CR.Write(CR.Read() | FLASH_CR_PG);
AddressSpace.Write(address, buffer, bufferIndex, lenght);
CR.Write(CR.Read() & (~FLASH_CR_PG));
}
finally
{
LockFlash();
}
}
}
}
vqp
August 23, 2012, 6:24pm
#12
We posted a version of this in Codeshare : see http://www.tinyclr.com/forum/topic?id=8477
1 Like
Hi vqp,
glad you finished it, you save me few hours of diggin in.
Thanks
Jan