18

STM32F4 で EEPROM をエミュレートするには、次の 2 つの方法があります。

  1. オンチップ 4K バイトのバックアップ SRAM
  2. 特定のソフトウェア アルゴリズムを備えたオンチップ フラッシュ

2 番目のオプションについては、AN3969 で説明しています。

しかし、残念ながら、Google は最初のオプション (4Kb のバックアップ SRAM を EEPROM として使用する) の使用方法に関する情報を提供できませんでした。..

誰でもこのトピックについて助けてもらえますか?

4

7 に答える 7

16

stm32f4 のリファレンス マニュアルと stm32f405xx/stm32f407xx データシートを読んだ後、バックアップ sram を実際に使用する方法 (またはその場所) が明確ではないことに同意します。これが私が見つけたものです。RTC レジスタとバックアップ SRAM の両方に、バッテリ電源がある限り維持されるある程度のストレージが含まれています。RTC には 20 個のレジスタ (80 バイト) が含まれており、バックアップ SRAM (AHB1 上の独自のペリフェラルであり、レジスタ アドレス領域内にある) には 0x1000 (4096 バイト) が含まれています。どちらもデフォルトでは有効になっていません。

DM00037051 (stm32f405xx/stm32f407xx データシート、p29):

The 4-Kbyte backup SRAM is an EEPROM-like memory area. It can be used to store
data which need to be retained in VBAT and standby mode. This memory area is 
disabled by default to minimize power consumption (see Section 2.2.19: 
Low-power modes). It can be enabled by software.

The backup registers are 32-bit registers used to store 80 bytes of user 
application data when VDD power is not present. Backup registers are not reset
by a system, a power reset, or when the device wakes up from the Standby mode 
(see Section 2.2.19: Low-power modes).

データシートの71ページとリファレンスマニュアルの65ページ

AHB1   |   0x4002 4000 - 0x4002 4FFF   |   BKPSRAM

データシートの73ページとリファレンスマニュアルの67ページ

APB1   |   0x4000 2800 - 0x4000 2BFF   |   RTC & BKP Registers

リファレンス マニュアルの 118 ~ 119 ページには、バックアップ SRAM および RTC レジスタの有効化に関する情報が含まれています。

注: バックアップ ドメインで RTC を既に使用していて、80 バイト以下しか保存する必要がない場合は、RTC バックアップ レジスタを使用することをお勧めします。これは、バックアップ SRAM を有効にすると、基本的に消費電流が 2 倍になるためです ( stm32f405/7 データシート)。

ここに、バックアップ SRAM とバックアップ RTC レジスタの両方に対する書き込みおよび読み取り関数を示します。

int8_t write_to_backup_sram( uint8_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 0x1000;
  uint8_t* base_addr = (uint8_t *) BKPSRAM_BASE;
  uint16_t i;
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  }
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
  /* disable backup domain write protection */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   // set RCC->APB1ENR.pwren
  PWR_BackupAccessCmd(ENABLE);                          // set PWR->CR.dbp = 1;
  /** enable the backup regulator (used to maintain the backup SRAM content in
    * standby and Vbat modes).  NOTE : this bit is not reset when the device
    * wakes up from standby, system reset or power reset. You can check that
    * the backup regulator is ready on PWR->CSR.brr, see rm p144 */
  PWR_BackupRegulatorCmd(ENABLE);     // set PWR->CSR.bre = 1;
  for( i = 0; i < bytes; i++ ) {
    *(base_addr + offset + i) = *(data + i);
  }
  PWR_BackupAccessCmd(DISABLE);                     // reset PWR->CR.dbp = 0;
  return 0;
}

int8_t read_from_backup_sram( uint8_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 0x1000;
  uint8_t* base_addr = (uint8_t *) BKPSRAM_BASE;
  uint16_t i;
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  }
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);
  for( i = 0; i < bytes; i++ ) {
    *(data + i) = *(base_addr + offset + i);
  }
  return 0;
}

int8_t write_to_backup_rtc( uint32_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 80;
  volatile uint32_t* base_addr = &(RTC->BKP0R);
  uint16_t i;
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  } else if( offset % 4 || bytes % 4 ) {
    /* ERROR: data start or num bytes are not word aligned */
    return -2;
  } else {
    bytes >>= 2;      /* divide by 4 because writing words */
  }
  /* disable backup domain write protection */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   // set RCC->APB1ENR.pwren
  PWR_BackupAccessCmd(ENABLE);                          // set PWR->CR.dbp = 1;
  for( i = 0; i < bytes; i++ ) {
    *(base_addr + offset + i) = *(data + i);
  }
  PWR_BackupAccessCmd(DISABLE);                     // reset PWR->CR.dbp = 0;
  // consider also disabling the power peripherial?
  return 0;
}

int8_t read_from_backup_rtc( uint32_t *data, uint16_t bytes, uint16_t offset ) {
  const uint16_t backup_size = 80;
  volatile uint32_t* base_addr = &(RTC->BKP0R);
  uint16_t i;
  if( bytes + offset >= backup_size ) {
    /* ERROR : the last byte is outside the backup SRAM region */
    return -1;
  } else if( offset % 4 || bytes % 4 ) {
    /* ERROR: data start or num bytes are not word aligned */
    return -2;
  } else {
    bytes >>= 2;      /* divide by 4 because writing words */
  }
  /* read should be 32 bit aligned */
  for( i = 0; i < bytes; i++ ) {
    *(data + i) = *(base_addr + offset + i);
  }
  return 0;
}
于 2014-01-10T19:09:09.910 に答える
5

ユーザーの要求に応じて、メイン プログラムからブートローダーにジャンプする必要がありました。そこで、メイン プログラムの BKPSRAM に「マジック ナンバー」を入れて、CPU ソフト リセットを行います。ブートローダーは常に最初に起動します。「マジックナンバー」が存在する場合はチェックし、実行し、存在しない場合はメインプログラムを開始します

HAL を使用する場合、ブートローダーにジャンプする方法は次のとおりです。

__HAL_RCC_PWR_CLK_ENABLE();

HAL_PWR_EnableBkUpAccess();

__BKPSRAM_CLK_ENABLE();

*(__IO uint8_t *)0x40024000 = 42;//magic number

HAL_NVIC_SystemReset();

ブートローダ内でマジック ナンバーを読み取るには、バックアップ SRAM クロックのみを有効にするだけで十分です (ブートローダは StdPeriphDriver を使用します)。

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);

extRequest = *(__IO uint8_t *)0x40024000;

if(extRequest == 42)
    //run bootloader

CPUはstm32f407

于 2015-11-17T22:04:37.270 に答える
1

現在、STM32F2xx マイクロコントローラを使用しています。データシートによると:

4K バイトのバックアップ SRAM は、EEPROM のような領域です。

RTC バックアップ レジスタの内容を保持するには、VDD がオフのとき、VBAT ピンをバッテリまたは別の電源から供給されるオプションのスタンバイ電圧に接続できます。

たとえば、マイクロコントローラの電源がオフのときにバックアップ レジスタの内容を維持するには、スーパーキャパシタが必要です。

また、ドキュメントによると:

リセット後、バックアップ ドメイン (… バックアップ SRAM) は不要な書き込みアクセスから保護されます。バックアップ ドメインへのアクセスを有効にするには、次の手順に従います。</p>

特定のペリフェラル レジスタに直接書き込むことによって、バックアップ ドメインにアクセスする方法を説明します。STM32F4xx ライブラリにアクセスできる場合は、次のように呼び出すことができます (注: STM32F2xx ライブラリを使用しています)。

PWR_BackupAccessCmd(ENABLE);

注: バックアップ SRAM インターフェイス クロックを有効にするなど、単に上記の関数を呼び出すだけではありません。STM32F4 シリーズのドキュメントを参照してください。

ライブラリ ソースには非常に貴重な多くのドキュメントが埋め込まれており、利用可能な場合は読む必要があります。

STM32F2 シリーズ マイクロコントローラでは、SRAM は次のメモリ アドレス範囲にあります。

0x40024000 - 0x40024FFF

たとえば、次のように、場所のどこかに書き込むことができます。

#define VAR_LOC ((volatile uint8_t *)(0x40024000))
volatile uint8_t *pVar = VAR_LOC;
*pVar = 5;
于 2013-12-20T21:52:10.743 に答える
0

バックアップ SRAM にアクセスするための STM32H7 の HAL 設定:

#define BKP_RAM (*(__IO uint32_t *) (D3_BKPSRAM_BASE)) //Start address: 0x38800000

Main() {

__HAL_RCC_BKPRAM_CLK_ENABLE();

HAL_PWREx_EnableBkUpReg();

BKP_RAM = 0xA5AA5A55;

}

それに加えて、systemInit() に以下の行を追加して、バックアップ SRAM へのライトスルー アクセスを有効にする必要があります。

SCB->CACR |= 1<<2;
于 2019-01-07T07:22:21.463 に答える