5.14 Flash 使用说明
本章说明 N32H49x 标准外设库中 Flash 驱动的文件组成、55 个公开函数,以及 DualBankSwap、Flash_Program、Flash_Row_Program、OptionByte_Config、Run_In_CCM、SingleBankRemap 6 个示例。读等待周期、编程与擦除解锁、选项字节、写保护与双 Bank 等机制请配合用户手册的“存储器和总线架构”章节阅读。
5.14.1 相关文件
| 相对路径 | 作用 |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_flash.h |
定义 FLASH_STS 状态枚举、读保护与中断标志、选项字节、写保护页、行编程等宏,并声明 55 个公开函数 |
firmware/n32h49x_std_periph_driver/src/n32h49x_flash.c |
实现上述 55 个函数:等待周期与缓存控制、编程与擦除解锁序列、页与 Bank 擦除、双字与行编程、选项字节编程与读取、标志与中断管理、CCM SRAM 控制 |
projects/n32h49x_EVAL/examples/Flash/ |
Flash 示例根目录,含 DualBankSwap、Flash_Program、Flash_Row_Program、OptionByte_Config、Run_In_CCM、SingleBankRemap 6 个示例 |
projects/n32h49x_EVAL/examples/Flash/Flash_Program/ |
该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt |
projects/n32h49x_EVAL/bsp/ |
6 个示例共用的板级支持文件:评估板 LED 定义、串口日志初始化与毫秒延时函数 |
5.14.2 API 参考
以下 55 个公开函数按 n32h49x_flash.h 的声明顺序分为 9 组;每个条目给出功能摘要与 n32h49x_flash.c 中该函数正上方的注释原文。
取指延迟与缓存
FLASH_SetLatency、FLASH_GetLatency、FLASH_PrefetchBufSet、FLASH_iCacheRST、FLASH_iCacheCmd、FLASH_DCacheRST、FLASH_DCacheCmd
解锁与锁定
FLASH_Unlock、FLASH_Lock、Flash_GetLockStatus、Option_Bytes_Unlock、Option_Bytes_Lock、OB_GetLockStatus
擦除
FLASH_EraseOnePage、FLASH_MassErase、FLASH_BankErase
编程
FLASH_ProgramdoubleWord、FLASH_RowProgramSet、FLASH_RowProgramAreaSet、FLASH_RowProgram
选项字节编程
FLASH_EraseOB、FLASH_ProgramOB_RRDC、FLASH_ProgramOB_U1U2、FLASH_EnWriteProtection、FLASH_ProgramOB_Data、FLASH_ProgramOB_SRAMECC、FLASH_ReadOutProtectionL1、FLASH_ReadOutProtectionL2_ENABLE
选项字节读取
FLASH_GetUserOB、FLASH_GetUser2、FLASH_GetOptionBytes_Data0、FLASH_GetOptionBytes_Data1、FLASH_GetWriteProtectionSTS、FLASH_GetReadOutProtectionSTS、FLASH_GetReadOutProtectionL2STS、FLASH_GetPrefetchBufSTS
中断与标志
FLASH_INTConfig、FLASH_GetFlagSTS、FLASH_ClearFlag、FLASH_GetSTS、FLASH_WaitForLastOpt
CCM SRAM
CCM_EnWriteProtection、CCM_GetWriteProtectionSTS、CCM_Earse_Unlock、CCM_EarseEN、CCM_EarseSTS、CCM_ModeSet
解密与 UID
XSPI_DESRangeSet、FEMC_DESRangeSet、RTP_DESKeySet、GetRTP_DESKeyWnum、Jtag_SealSet、XSPI_FEMC_DESSet、Get_XFUID、Get_CCMUID
void FLASH_SetLatency(uint32_t FLASH_Latency)设置闪存读操作的等待周期数。
name FLASH_SetLatency
fun Sets the code latency value.
param FLASH_Latency :(The input parameters must be the following values)
- FLASH_LATENCY_0 FLASH Zero Latency cycle, 0 < SYSCLK <= 48MHz
- FLASH_LATENCY_1 FLASH One Latency cycle, 48MHz < SYSCLK<= 96MHz
- FLASH_LATENCY_2 FLASH Two Latency cycle, 96MHz < SYSCLK<= 144MHz
- FLASH_LATENCY_3 FLASH Three Latency cycle,144MHz < SYSCLK<= 192MHz
- FLASH_LATENCY_4 FLASH Four Latency cycle, 192MHz < SYSCLK<= 240MHz
return none
note The larger the latency, the longer the flash read operation will take.
If not necessary, it is recommended to use a smaller latency.
uint8_t FLASH_GetLatency(void)获取闪存读操作的当前等待周期数。
name FLASH_GetLatency
fun Get the code latency value.
param none
return FLASH_LATENCY :(The input parameters must be the following values)
- FLASH_LATENCY_0 FLASH Zero Latency cycle, 0 < SYSCLK <= 48MHz
- FLASH_LATENCY_1 FLASH One Latency cycle, 48MHz < SYSCLK<= 96MHz
- FLASH_LATENCY_2 FLASH Two Latency cycle, 96MHz < SYSCLK<= 144MHz
- FLASH_LATENCY_3 FLASH Three Latency cycle,144MHz < SYSCLK<= 192MHz
- FLASH_LATENCY_4 FLASH Four Latency cycle, 192MHz < SYSCLK<= 240MHz
void FLASH_PrefetchBufSet(uint32_t FLASH_PrefetchBuf)使能或禁止预取缓冲区。
name FLASH_PrefetchBufSet
fun Enables or disables the Prefetch Buffer.
param FLASH_PrefetchBuf:(The input parameters must be the following values)
- FLASH_PrefetchBuf_EN
- FLASH_PrefetchBuf_DIS
return none
note Prefetch feature must be disabled for this bit.
void FLASH_iCacheRST(uint32_t Bank)复位指令缓存(iCache)。
name FLASH_iCacheRST
fun ICache Reset.
param Bank:(The input parameters must be the following values)
- FLASH_BANK1
- FLASH_BANK2
return none
void FLASH_iCacheCmd(uint32_t Bank, uint32_t FLASH_iCache)使能或禁止指令缓存(iCache)。
name FLASH_iCacheCmd
fun Enables or disables the iCache.
param Bank:(The input parameters must be the following values)
- FLASH_BANK1
- FLASH_BANK2
param FLASH_iCache:(The input parameters must be the following values)
- FLASH_iCache_EN FLASH iCache Enable
- FLASH_iCache_DIS FLASH iCache Disable
return none
void FLASH_DCacheRST(void)复位数据缓存(DCache)。
name FLASH_DCacheRST
fun DCache Reset.
param none
return none
void FLASH_DCacheCmd(uint32_t FLASH_DCache)使能或禁止数据缓存(DCache)。
name FLASH_DCacheCmd
fun Enables or disables the DCache.
param FLASH_DCache:(The input parameters must be the following values)
- FLASH_DCache_EN FLASH DCache Enable
- FLASH_DCache_DIS FLASH DCache Disable
return none
note
void FLASH_Unlock(void)解锁 Flash 编程/擦除控制器。
name FLASH_Unlock
fun Unlocks the FLASH Program Erase Controller.
param none
return none
void FLASH_Lock(void)锁定 Flash 编程/擦除控制器。
name FLASH_Lock
fun Locks the FLASH Program Erase Controller.
param none
return none
FlagStatus Flash_GetLockStatus(void)获取 Flash 编程/擦除控制器的锁定状态。
name Flash_GetLockStatus
fun Get the Flash lock status.
param none
return FlagStatus :
- SET FLASH is in Lock state
- RESET FLASH is in Unlock state
void Option_Bytes_Unlock(void)解锁选项字节编程/擦除控制器。
name Option_Bytes_Unlock
fun Unlocks the Option_Bytes Program Erase Controller.
param none
return none
void Option_Bytes_Lock(void)锁定选项字节编程/擦除控制器。
name Option_Bytes_Lock
fun Locks the Option_Bytes Program Erase Controller.
param none
return none
FlagStatus OB_GetLockStatus(void)获取选项字节编程/擦除控制器的锁定状态。
name OB_GetLockStatus
fun Get the Option Bytes lock status.
param none
return FlagStatus :
- SET Option byte is in Lock state
- RESET Option byte is in Unlock state
FLASH_STS FLASH_EraseOnePage(uint32_t Page_Address)擦除指定的主存储区 Flash 页。
name FLASH_EraseOnePage
fun Erases a specified main FLASH page.
param Page_Address :(The input parameters must be the following values)
- it ranges from 0x08000000 to 0x080FFFFF
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_ADD FLASH address error
note If FLASH is in single bank mode,Page_Address must be a multiple of 0x4000;
If FLASH is in dual bank mode,Page_Address must be a multiple of 0x2000.
FLASH_STS FLASH_MassErase(void)擦除主存储区的全部页面(整片擦除)。
name FLASH_MassErase
fun Erases all main FLASH pages.
param none
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_BankErase(uint32_t Bank)擦除指定 Bank 主存储区的全部页面。
name FLASH_BankErase
fun Erases Bank's all main FLASH pages.
param Bank:(The input parameters must be the following values)
- FLASH_BANK1
- FLASH_BANK2
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ProgramdoubleWord(uint32_t address, uint32_t data0,uint32_t data1)在指定地址编程两个 32 位字(双字)。
name FLASH_ProgramdoubleWord
fun Programs two words at a specified address.
param address :(The input parameters must be the following values)
- main flash, it ranges from 0x08000000 to 0x080FFFFF, it must be a multiple of 0x08
param data0 :(The input parameters must be the following values)
- It ranges from 0x00000000 to 0xFFFFFFFF
param data1 :(The input parameters must be the following values)
- It ranges from 0x00000000 to 0xFFFFFFFF
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_ADD FLASH address error
- FLASH_ERR_RPADD FLASH Row programmer address error
- FLASH_TIMEOUT FLASH operation timeout
void FLASH_RowProgramSet(FunctionalState Cmd)使能或禁止行编程器。
name FLASH_RowProgramSet
fun Enables or disables row programmer.
param Cmd :(The input parameters must be the following values)
- ENABLE Enable Row programmer
- DISABLE Disable Row programmer
return none
void FLASH_RowProgramAreaSet(FunctionalState Cmd)配置行编程器的操作区域。
name FLASH_RowProgramAreaSet
fun Configure row programmer area.
param Cmd :(The input parameters must be the following values)
- ENABLE Row programmer in system memory
- DISABLE Row programmer in main flash
return none
FLASH_STS FLASH_RowProgram(uint32_t address, uint32_t row_num, uint32_t *data)在指定地址连续编程 x 个字。
name FLASH_RowProgram
fun Programs x words at a specified address.
param address :(The input parameters must be the following values)
- main flash, it ranges from 0x08000000 to 0x080FFFFF, it must be a multiple of 0x08
param row_num :(The input parameters must be the following values)
- It ranges from 0x02 to 0x10,it must be a multiple of 0x02
param data[] :(The input parameters must be the following values)
- It ranges from 0x00000000 to 0xFFFFFFFF
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_ADD FLASH address error
- FLASH_ERR_RPADD FLASH Row programmer address error
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
note Row programming cannot span 512 bytes.
FLASH_STS FLASH_EraseOB(void)擦除 Flash 选项字节。
name FLASH_EraseOB
fun Erases the FLASH option bytes.
param none
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ProgramOB_RRDC(uint32_t option_byte_rpd1, uint32_t option_byte_rpd2, \ uint32_t option_byte_DBANK,uint32_t option_byte_CCMSRAM)编程选项字节 RDP1、RDP2、DBANK 与 CCMSRAM_RST 位。
name FLASH_ProgramOB_RRDC
fun Programs the Option Byte: RDP1/RDP2/DBANK/CCMSRAM_RST.
param option_byte_rpd1 :(The input parameters must be the following values)
- FLASH_OB_RDP1_ENABLE Enable read protection L1
- FLASH_OB_RDP1_DISABLE Disable read protection L1
param option_byte_rpd2 :(The input parameters must be the following values)
- FLASH_OB_RDP2_ENABLE Enable read protection L2
- FLASH_OB_RDP2_DISABLE Disable read protection L2
param option_byte_DBANK :(The input parameters must be the following values)
- FLASH_SINGLE_BANK Single Bank Mode
- FLASH_DUAL_BANK Dual Bank Mode
param option_byte_CCMSRAM :(The input parameters must be the following values)
- CCMSRAM_RST_NERASE CCMSRAM reset not erase
- CCMSRAM_RST_ERASE CCMSRAM reset erase
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ProgramOB_U1U2(uint32_t option_byte_iwdg, uint32_t option_byte_stop,\ uint32_t option_byte_stdby, uint32_t option_byte_iwdg_stop, uint32_t option_byte_iwdg_stdby,\ uint32_t option_byte_iwdg_sleep,uint32_t option_byte2_nBOOT0, uint32_t option_byte2_nBOOT1,\ uint32_t option_byte2_nSWBOOT0, uint32_t option_byte2_FlashBoot,uint32_t option_byte2_DAC,\ uint32_t option_byte2_BOR)编程选项字节 USER 与 USER2 位。
name FLASH_ProgramOB_U1U2
fun Programs the Option Byte: USER/USER2.
param option_byte_iwdg :(The input parameters must be the following values)
- FLASH_OB_IWDG_SOFTWARE Software IWDG selected
- FLASH_OB_IWDG_HARDWARE Hardware IWDG selected
param option_byte_stop :(The input parameters must be the following values)
- FLASH_OB_STOP_NORST No reset generated when entering in STOP
- FLASH_OB_STOP_RST Reset generated when entering in STOP
param option_byte_stdby :(The input parameters must be the following values)
- FLASH_OB_STDBY_NORST No reset generated when entering in standby
- FLASH_OB_STDBY_RST Reset generated when entering in standby
param option_byte_iwdg_stop :(The input parameters must be the following values)
- FLASH_OB_IWDG_STOP_FRZ IWDG freeze in stop
- FLASH_OB_IWDG_STOP_NOFRZ Default no freeze
param option_byte_iwdg_stdby :(The input parameters must be the following values)
- FLASH_OB_IWDG_STDBY_FRZ IWDG freeze in standby
- FLASH_OB_IWDG_STDBY_NOFRZ Default no freeze
param option_byte_iwdg_sleep :(The input parameters must be the following values)
- FLASH_OB_IWDG_SLEEP_FRZ IWDG freeze in sleep
- FLASH_OB_IWDG_SLEEP_NOFRZ Default no freeze
param option_byte2_nBOOT0 :(The input parameters must be the following values)
- FLASH_OB2_NBOOT0_SET Set nBOOT0
- FLASH_OB2_NBOOT0_CLR Clear nBOOT0
param option_byte2_nBOOT1 :(The input parameters must be the following values)
- FLASH_OB2_NBOOT1_SET Set nBOOT1
- FLASH_OB2_NBOOT1_CLR Clear nBOOT1
param option_byte2_nSWBOOT0 :(The input parameters must be the following values)
- FLASH_OB2_NSWBOOT0_SET Set nSWBOOT0
- FLASH_OB2_NSWBOOT0_CLR Clear nSWBOOT0
param option_byte2_FlashBoot :(The input parameters must be the following values)
- FLASH_OB2_FLASHBOOT_SET Main flash forward section boot
- FLASH_OB2_FLASHBOOT_CLR Main flash back part boot
param option_byte2_DAC :(The input parameters must be the following values)
- FLASH_OB2_DAC_SET System reset, DAC voltage value maintained
- FLASH_OB2_DAC_CLR System reset, DAC voltage value not maintained
param option_byte2_BOR :(The input parameters must be the following values)
- BOR_LEVEL_1_6V Reset level threshold 1.6V (Up 1.66V / Down 1.62V)
- BOR_LEVEL_2_0V Reset level threshold 2.0V (Up 2.1V / Down 2.0V)
- BOR_LEVEL_2_2V Reset level threshold 2.2V (Up 2.3V / Down 2.2V)
- BOR_LEVEL_2_5V Reset level threshold 2.5V (Up 2.6V / Down 2.5V)
- BOR_LEVEL_2_8V Reset level threshold 2.8V (Up 2.9V / Down 2.8V)
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_EnWriteProtection(uint32_t FLASH_Pages)对指定的页使能写保护。
name FLASH_EnWriteProtection
fun Write protects the desired pages.
param FLASH_Pages :(The input parameters must be the following values)
- FLASH_WRP_NUM0 Single Bank: page 0 to 1 , Dual Banke: page 0 to 3
- FLASH_WRP_NUM1 Single Bank: page 2 to 3 , Dual Banke: page 4 to 7
- FLASH_WRP_NUM2 Single Bank: page 4 to 5 , Dual Banke: page 8 to 11
- FLASH_WRP_NUM3 Single Bank: page 6 to 7 , Dual Banke: page 12 to 15
- FLASH_WRP_NUM4 Single Bank: page 8 to 9 , Dual Banke: page 16 to 19
- FLASH_WRP_NUM5 Single Bank: page 10 to 11, Dual Banke: page 20 to 23
- FLASH_WRP_NUM6 Single Bank: page 12 to 13, Dual Banke: page 24 to 27
- FLASH_WRP_NUM7 Single Bank: page 14 to 15, Dual Banke: page 28 to 31
- FLASH_WRP_NUM8 Single Bank: page 16 to 17, Dual Banke: page 32 to 35
- FLASH_WRP_NUM9 Single Bank: page 18 to 19, Dual Banke: page 36 to 39
- FLASH_WRP_NUM10 Single Bank: page 20 to 21, Dual Banke: page 40 to 43
- FLASH_WRP_NUM11 Single Bank: page 22 to 23, Dual Banke: page 44 to 47
- FLASH_WRP_NUM12 Single Bank: page 24 to 25, Dual Banke: page 48 to 51
- FLASH_WRP_NUM13 Single Bank: page 26 to 27, Dual Banke: page 52 to 55
- FLASH_WRP_NUM14 Single Bank: page 28 to 29, Dual Banke: page 56 to 59
- FLASH_WRP_NUM15 Single Bank: page 30 to 31, Dual Banke: page 60 to 63
- FLASH_WRP_NUM16 Single Bank: page 32 to 33, Dual Banke: page 64 to 67
- FLASH_WRP_NUM17 Single Bank: page 34 to 35, Dual Banke: page 68 to 71
- FLASH_WRP_NUM18 Single Bank: page 36 to 37, Dual Banke: page 72 to 75
- FLASH_WRP_NUM19 Single Bank: page 38 to 39, Dual Banke: page 76 to 79
- FLASH_WRP_NUM20 Single Bank: page 40 to 41, Dual Banke: page 80 to 83
- FLASH_WRP_NUM21 Single Bank: page 42 to 43, Dual Banke: page 84 to 87
- FLASH_WRP_NUM22 Single Bank: page 44 to 45, Dual Banke: page 88 to 91
- FLASH_WRP_NUM23 Single Bank: page 46 to 47, Dual Banke: page 92 to 95
- FLASH_WRP_NUM24 Single Bank: page 48 to 49, Dual Banke: page 96 to 99
- FLASH_WRP_NUM25 Single Bank: page 50 to 51, Dual Banke: page 100 to 103
- FLASH_WRP_NUM26 Single Bank: page 52 to 53, Dual Banke: page 104 to 107
- FLASH_WRP_NUM27 Single Bank: page 54 to 55, Dual Banke: page 108 to 111
- FLASH_WRP_NUM28 Single Bank: page 56 to 57, Dual Banke: page 112 to 115
- FLASH_WRP_NUM29 Single Bank: page 58 to 59, Dual Banke: page 116 to 119
- FLASH_WRP_NUM30 Single Bank: page 60 to 61, Dual Banke: page 120 to 123
- FLASH_WRP_NUM31 Single Bank: page 62 to 63, Dual Banke: page 124 to 127
- FLASH_WRP_AllPages all Pages
- ~FLASH_WRP_AllPages Disable Write protection of all Pages
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ProgramOB_Data(uint32_t option_byte_data0, uint32_t option_byte_data1,\ uint32_t option_byte_data2, uint32_t option_byte_data3)编程选项字节 DATA0、DATA1、DATA2 与 DATA3。
name FLASH_ProgramOB_Data
fun Programs the Option Byte: DATA0/DATA1/DATA2/DATA3.
param option_byte_data0:(The input parameters must be the following values)
- 0x00 to 0xFF
param option_byte_data1:(The input parameters must be the following values)
- 0x00 to 0xFF
param option_byte_data2:(The input parameters must be the following values)
- 0x00 to 0xFF
param option_byte_data3:(The input parameters must be the following values)
- 0x00 to 0xFF
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ProgramOB_SRAMECC(uint32_t option_byte_SRAM2,uint32_t option_byte_SRAM3)编程选项字节中的 SRAM2、SRAM3 ECC 使能位。
name FLASH_ProgramOB_SRAMECC
fun Programs the Option Byte: SRAM2_ECC_ENABLE,SRAM3_ECC_ENABLE.
param option_byte_SRAM2 :(The input parameters must be the following values)
- SRAM2_ECC_ENABLE SRAM2 ECC ENABLE
- SRAM2_ECC_DISABLE SRAM2 ECC DISABLE
param option_byte_SRAM3 :(The input parameters must be the following values)
- SRAM3_ECC_ENABLE SRAM3 ECC ENABLE
- SRAM3_ECC_DISABLE SRAM3 ECC DISABLE
return FLASH_STS : (The input parameters must be the following values)
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_ReadOutProtectionL1(FunctionalState Cmd)使能或禁止读出保护 L1 等级。
name FLASH_ReadOutProtectionL1
fun Enables or disables the read out protection.
param Cmd:(The input parameters must be the following values)
- ENABLE Enable read protection L1
- DISABLE Disable read protection L1
return FLASH_STS : (The input parameters must be the following values)
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
note If the user has already programmed the other option bytes before calling
this function, he must re-program them since this function erases all option bytes.
FLASH_STS FLASH_ReadOutProtectionL2_ENABLE(void)使能读出保护 L2 等级。
name FLASH_ReadOutProtectionL2_ENABLE
fun Enables the read out protection L2.
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RDP2 FLASH is in read protection L2 status
- FLASH_TIMEOUT FLASH operation timeout
- FLASH_ERR_RPADD FLASH Row programmer address error
note If the user has already programmed the other option bytes before calling
this function, he must re-program them since this function erases all option bytes.
uint32_t FLASH_GetUserOB(void)读取 Flash USER 选项字节的值。
name FLASH_GetUserOB
fun Returns the FLASH User Option Bytes values.
param none
return The FLASH User Option Bytes values:IWDG_SW(Bit0), nRST_STOP(Bit1),
nRST_STDBY(Bit2), IWDGSTOPFRZ(Bit3), IWDGSTDBYFRZ(Bit5) and IWDGSLEEPFRZ(Bit6).
FlagStatus FLASH_GetUser2(uint32_t option_byte_bit)读取 Flash USER2 选项字节指定配置位的值。
name FLASH_GetUser2
fun Returns the FLASH User2 Option Bytes values.
param option_byte_bit: (The input parameters must be the following values)
- FLASH_OB2_NBOOT0_SET nBOOT0 configuration bit
- FLASH_OB2_NBOOT1_SET nBOOT1 configuration bit
- FLASH_OB2_NSWBOOT0_SET nSWBOOT0 configuration bit
return FlagStatus :
- SET Enter this mode without resetting
- RESET Enter this mode reset
uint32_t FLASH_GetOptionBytes_Data0(void)读取选项字节 DATA0 的值。
name FLASH_GetOptionBytes_Data0
fun Returns the FLASH User Option Bytes values.
param none
return data0:
- 0x00 to 0xFF.
uint32_t FLASH_GetOptionBytes_Data1(void)读取选项字节 DATA1 的值。
name FLASH_GetOptionBytes_Data1
fun Returns the FLASH User Option Bytes values.
param none
return data1:
- 0x00 to 0xFF.
uint32_t FLASH_GetWriteProtectionSTS(void)读取 Flash 写保护选项字节寄存器的值。
name FLASH_GetWriteProtectionSTS
fun Returns the FLASH Write Protection Option Bytes Register value.
param none
return The FLASH Write Protection Option Bytes Register value :
- Bit31 - Bit0 write-protects dual bank: pages (62~63) - page (0~1)
FlagStatus FLASH_GetReadOutProtectionSTS(void)查询 Flash 读出保护 L1 是否已使能。
name FLASH_GetReadOutProtectionSTS
fun Checks whether the FLASH Read Out Protection L1 status_value is set or not.
param none
return FlagStatus :
- SET Read protection L1 enable
- RESET Read protection L1 disable
FlagStatus FLASH_GetReadOutProtectionL2STS(void)查询 Flash 读出保护 L2 是否已使能。
name FLASH_GetReadOutProtectionL2STS
fun Checks whether the FLASH Read Out Protection L2 status_value is set or not.
param none
return FlagStatus :
- SET Read protection L2 enable
- RESET Read protection L2 disable
FlagStatus FLASH_GetPrefetchBufSTS(void)查询 Flash 预取缓冲区当前是否使能。
name FLASH_GetPrefetchBufSTS
fun Checks whether the FLASH Prefetch Buffer status_value is set or not.
param none
return FlagStatus :
- SET Flash prefetch buffer enable
- RESET Flash prefetch buffer disable
void FLASH_INTConfig(uint32_t FLASH_INT, FunctionalState Cmd)使能或禁止指定的 Flash 中断源。
name FLASH_INTConfig
fun Enables or disables the specified FLASH interrupts.
param Cmd:(The input parameters must be the following values)
- ENABLE
- DISABLE
param FLASH_INT :
- FLASH_INT_EOP FLASH end of operation Interrupt
- FLASH_INT_ERR PGERR WRPERR ERROR interrupt source
- FLASH_INT_FERR EVERR PVERR ERROR interrupt source
- FLASH_INT_ECC1 1 bit ECC error interrupt source
- FLASH_INT_JS jtag seal error interrupt source
- FLASH_INT_ECC2 2 bit ECC error interrupt source
- FLASH_INT_DECC XSPI/FEMC decryption misconfiguration interrupt source
- FLASH_INT_RPADD Row programmer address error interrupt source
- FLASH_INT_BANKEX BANK exchange error interrupt Enable
return none
FlagStatus FLASH_GetFlagSTS(uint32_t FLASH_FLAG)查询指定的 Flash 标志位是否置位。
name FLASH_GetFlagSTS
fun Checks whether the specified FLASH flag is set or not.
param FLASH_FLAG :(The input parameters must be the following values)
- FLASH_FLAG_EOP FLASH End of Operation flag
- FLASH_FLAG_BUSY FLASH Busy flag
- FLASH_FLAG_PGERR FLASH Program error flag
- FLASH_FLAG_WRPERR FLASH Write protected error flag
- FLASH_FLAG_PVERR FLASH Program Verify ERROR flag
- FLASH_FLAG_EVERR FLASH Erase Verify ERROR flag
- FLASH_FLAG_ECC1ERR FLASH 1 bit ECC ERROR flag
- FLASH_FLAG_RDKEYERR read key error flag
- FLASH_FLAG_RDXKEYERR xKEY match error flag
- FLASH_FLAG_NRDXKEYEN Not allowed to read RTPD_KEY enable flag
- FLASH_FLAG_JSERR JTAG/SRAM access JTAG_SEAL error flag
- FLASH_FLAG_RTPKEYERR read RTPD_KEY error flag
- FLASH_FLAG_ECC2ERR FLASH 2 bit ECC error flag
- FLASH_FLAG_DECCRDF XSPI/FEMC Decryption Configuration Completion Flag
- FLASH_FLAG_DECCERR XSPI/FEMC Decryption Configuration sequences error Flag
- FLASH_FLAG_FWORDF first word write completion flag
- FLASH_FLAG_RPADDERR row programmmer address error
- FLASH_FLAG_BANKEXERR BANK exchange error
- FLASH_FLAG_BANKMODE BANK mode
- FLASH_FLAG_OBERR FLASH Option Byte error flag
return bitstatus :
- SET
- RESET
void FLASH_ClearFlag(uint32_t FLASH_FLAG)清除 Flash 的待处理标志。
name FLASH_ClearFlag
fun Clears the FLASH's pending flags.
param FLASH_FLAG :(The input parameters must be the following values)
- FLASH_FLAG_EOP FLASH End of Operation flag
- FLASH_FLAG_PGERR FLASH Program error flag
- FLASH_FLAG_WRPERR FLASH Write protected error flag
- FLASH_FLAG_PVERR FLASH Program Verify ERROR flag
- FLASH_FLAG_EVERR FLASH Erase Verify ERROR flag
- FLASH_FLAG_ECC1ERR FLASH 1 bit ECC ERROR flag
- FLASH_FLAG_JSERR JTAG/SRAM access JTAG_SEAL error flag
- FLASH_FLAG_RTPKEYERR read RTPD_KEY error flag
- FLASH_FLAG_ECC2ERR FLASH 2 bit ECC error flag
- FLASH_FLAG_DECCRDF XSPI/FEMC Decryption Configuration Completion Flag
- FLASH_FLAG_DECCERR XSPI/FEMC Decryption Configuration sequences error Flag
- FLASH_FLAG_RPADDERR row programmmer address error
- FLASH_FLAG_BANKEXERR BANK exchange error
return none
FLASH_STS FLASH_GetSTS(void)返回 Flash 当前的操作状态。
name FLASH_GetSTS
fun Returns the FLASH Status.
param none
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RPADD FLASH Row programmer address error
FLASH_STS FLASH_WaitForLastOpt(uint32_t Timeout)等待 Flash 操作完成或发生超时。
name FLASH_WaitForLastOpt
fun Waits for a Flash operation to complete or a TIMEOUT to occur.
param Timeout:(The input parameters must be the following values)
- EraseTimeout
- ProgramTimeout
- RowProgramTimeout
return FLASH_STS :
- FLASH_BUSY FLASH is busy
- FLASH_ERR_PG FLASH programming error
- FLASH_ERR_WRP FLASH Write protected error
- FLASH_EOP FLASH End of Operation
- FLASH_ERR_PV Programmer Verification Error
- FLASH_ERR_EV Erase Verification Error
- FLASH_ERR_RPADD FLASH Row programmer address error
void CCM_EnWriteProtection(uint32_t CCM_Pages)对指定的 CCM SRAM 页使能写保护。
name CCM_EnWriteProtection
fun Enables write protection CCM x page.
param CCM_Pages:(The input parameters must be the following values)
- Bit31 - Bit0 write-protects pages (31) - page (0)
return none
uint32_t CCM_GetWriteProtectionSTS(void)读取 CCM SRAM 写保护选项字节寄存器的值。
name CCM_GetWriteProtectionSTS
fun Returns the CCM Write Protection Option Bytes Register value.
param none
return The CCM Write Protection Option Bytes Register value :
- Bit31 - Bit0 write-protects pages (31) - page (0)
void CCM_Earse_Unlock(void)解锁 CCM SRAM 擦除控制器。
name CCM_ERASE_Unlock
fun Unlocks the CCM Erase Controller.
param none
return none
使用提示: 头文件第 376 行的声明为 CCM_Earse_Unlock,而源码注释的 name 字段写作 CCM_ERASE_Unlock,二者不一致。
void CCM_EarseEN(void)使能 CCM SRAM 擦除。
name CCM_ERASE_EN
fun ENABLE CCM Erase.
param none
return none
使用提示: 头文件第 377 行的声明为 CCM_EarseEN,而源码注释的 name 字段写作 CCM_ERASE_EN,二者不一致。
FlagStatus CCM_EarseSTS(void)获取 CCM SRAM 擦除状态。
name CCM_EarseSTS
fun Get CCM Erase Status.
param none
return FlagStatus :
- SET CCM SRAM erase operation
- RESET No CCM SRAM erase operation
void CCM_ModeSet(FunctionalState Cmd)使能或禁止 CCM 模式。
name CCM_ModeSet
fun Enables or disables CCM mode.
param Cmd:(The input parameters must be the following values)
- ENABLE
- DISABLE
return none
void XSPI_DESRangeSet(uint32_t start_add,uint32_t end_add)设置 XSPI 解密地址范围。
name XSPI_DESRangeSet
fun XSPI Decryption address range setting.
param start_add:(The input parameters must be the following values)
- It ranges from 0x90000000 to 0x9FFFFFFF
param end_add:(The input parameters must be the following values)
- It ranges from 0x90000000 to 0x9FFFFFFF
return none
void FEMC_DESRangeSet(uint32_t start_add,uint32_t end_add)设置 FEMC 解密地址范围。
name FEMC_DESRangeSet
fun FEMC Decryption address range setting.
param start_add:(The input parameters must be the following values)
- It ranges from 0x60000000 to 0x8FFFFFFF
param end_add:(The input parameters must be the following values)
- It ranges from 0x60000000 to 0x8FFFFFFF
return none
void RTP_DESKeySet(uint32_t* DES_key)设置 128 位 RTPD 解密密钥。
name RTP_DESKeySet
fun 128bit RTPD decryption key setting.
param DES_key:(The input parameters must be the following values)
- A 128-bit key
return none
uint32_t GetRTP_DESKeyWnum(void)获取 RTPD_KEY 的写入次数。
name GetRTP_DESKeyWnum
fun get RTPD_KEY Write Count.
param none
return CNT:
- RTPD_KEY write cnt
void Jtag_SealSet(FunctionalState Cmd)使能或禁止 JTAG 密封(Jtag_Seal)。
name Jtag_SealSet
fun Enables or disables Jtag_Seal.
param Cmd:(The input parameters must be the following values)
- ENABLE
- DISABLE
return none
void XSPI_FEMC_DESSet(FunctionalState Cmd)使能或禁止 XSPI/FEMC 解密功能。
name XSPI_FEMC_DESSet
fun Enables or disables XSPI/FEMC decryption.
param Cmd:(The input parameters must be the following values)
- ENABLE
- DISABLE
return none
uint32_t Get_XFUID(void)获取 XSPI/FEMC 的配置 UID。
name Get_XFUID
fun get XSPI/FEMC configure UID.
param none
return UID:
- 0x01 BOOT user
- 0x02 FLASH user1
- 0x04 FLASH user2
- 0x08 FLASH user3
- 0x10 SRAM user
uint32_t Get_CCMUID(void)获取 CCM 的配置 UID。
name Get_CCMUID
fun get CCM configure UID.
param none
return UID:
- 0x01 BOOT user
- 0x02 FLASH user1
- 0x04 FLASH user2
- 0x08 FLASH user3
- 0x10 SRAM user
5.14.3 Demo 示例说明
本节说明 Flash 的 6 个示例:Flash_Program 演示页擦除与双字编程,Flash_Row_Program 演示行编程,OptionByte_Config 演示选项字节的擦除与编程,SingleBankRemap 演示单 Bank 模式下的启动重映射,DualBankSwap 演示双 Bank 的三种切换方式,Run_In_CCM 演示把函数代码放到 CCM SRAM 中执行。
5.14.3.1 DualBankSwap 双 Bank 切换
工程目录: projects/n32h49x_EVAL/examples/Flash/DualBankSwap/
初始化串口并打开 HSI 时钟→初始化板载 LED→检查当前 Bank 模式并要求为双 Bank→读取选项字节中的启动 Bank 与重映射 Bank→恢复上次运行的工作模式标记→主循环按串口指令以 Retry、Backup、Reload 三种方式切换 Bank→切换前点亮全部 LED 并复位或重映射
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示双 Bank 模式下的三种 Bank 切换:Retry 通过重映射切换,Backup 通过改写选项字节并复位切换,Reload 组合使用重映射与选项字节改写。 MCU 工作在 Bank1 时 LED1 闪烁,工作在 Bank2 时 LED2 闪烁; 发生重映射后,闪烁的 LED 对应的另一只 LED 常亮。 |
| 源码组成 | src/main.c:main、ConfigBootBank、SetModeMark、ClrModeMark、GetModeMark;inc/main.h:OB_BUF_ADDRESS、MODE_MARK_ADDR、三种模式标记宏、LED 操作宏与 ConfigBootBank 声明;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 示例要求双 Bank 模式(DBANK=1),单 Bank 模式下停在提示循环不执行。 选项字节缓冲区 OB_BUF_ADDRESS 为 0x40023000,工作模式标记 MODE_MARK_ADDR 为 0x40023080,均位于备份 SRAM。系统时钟 240 MHz,打印串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | main 先 log_init,打开 HSI 并等待稳定,初始化 LED;读取 FLASH_FLAG_BANKMODE 判断 Bank 模式,再读取选项字节的启动 Bank 与 RCC 的重映射 Bank,并用两个互补标记读出上次的工作模式;主循环轮询 USART1,收到 0x55 走 Retry、0x66 走 Backup、0x77 走 Reload; Retry 与 Reload 在 SetModeMark 后调用 RCC_ConfigRemapMode、RCC_EnableRemap,Backup 在 ConfigBootBank 成功后调用 NVIC_SystemReset。 |
| 主要 API | FLASH_GetFlagSTS、FLASH_Unlock、FLASH_EraseOB、Option_Bytes_Unlock、Option_Bytes_Lock、FLASH_ClearFlag、FLASH_WaitForLastOpt、FLASH_Lock |
| 验证方法 | 复位运行后串口打印当前 Bank 与启动地址 0x08000000; 下发 0x55 观察 Retry 重映射,下发 0x66 观察 Backup 复位后从另一 Bank 启动,下发 0x77 观察 Reload 组合切换; 每次切换成功时对应 LED 开始闪烁。 |
| 使用提示 | 启动地址始终是 0x08000000,切换的是代码实际存储位置。 Backup 与 Reload 会改写选项字节,属于 Flash 编程,运行前须保证 HSI 已打开。 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例通过重映射或改写选项字节在两只 Bank 之间切换启动代码,并用备份 SRAM 中的标记跨复位传递工作模式。
数据路径: 串口指令 → SetModeMark 写入 MODE_MARK_ADDR → RCC_ConfigRemapMode/RCC_EnableRemap 或 ConfigBootBank 改写选项字节 → NVIC_SystemReset 复位 → GetModeMark 恢复工作模式
1. 打开 HSI 并检查 Bank 模式。 Flash 编程或擦除要求 HSI 打开,示例在初始化后立即打开 HSI;随后检查 FLASH_FLAG_BANKMODE,单 Bank 模式下停在提示循环,不再执行后续切换逻辑。
/* When performing Flash programming operations(write or erase), HSI must be enable*/
RCC_EnableHsi(ENABLE);
RCC_WaitHsiStable();
/* User LED Init */
Hardware_Board_Led_Init();
/* Check current Bank mode, must be in dual Bank mode */
if(FLASH_GetFlagSTS(FLASH_FLAG_BANKMODE) == SET)
{
log_info("\r\nFLASH is dual Bank mode!\r\n");
}
else
{
log_info("\r\nFLASH is single Bank mode!\r\n");
log_info("This demo can not be used!\r\n");
while(1)
{
/* Dual Bank swap demo is only used for dual Bank mode */
}
}
2. Retry 方式通过重映射切换。 收到 0x55 后,示例按当前工作 Bank 选择重映射目标,先写入工作模式标记,再点亮全部 LED,最后配置并启动重映射,代码存储位置随之改变但启动地址不变。
if(UartCmd == 0x55U) /* Retry */
{
if(FLASH_BANK2 == WorkBankNum)
{
Value_temp = RCC_REMAP_BFLASH;
log_info("Remap to Bank1!\r\n");
}
else
{
Value_temp = RCC_REMAP_AFLASH;
log_info("Remap to Bank2!\r\n");
}
/* Set the mark of work mode */
SetModeMark(RETRY_MARK);
/* Turn on all LED before remap */
ALL_BANK_LED_ON;
systick_delay_ms(5);
/* Config remap bank and remap */
RCC_ConfigRemapMode(Value_temp);
RCC_EnableRemap();
}
3. 直接改写选项字节切换启动 Bank。 ConfigBootBank 先把当前选项字节读入备份 SRAM,修改 USER2 的启动 Bank 字段,再按双字为单位逐组编程;只有上一次编程返回 FLASH_EOP 才继续下一组。
/* Erase */
ConfigSts = FLASH_EraseOB();
/* Erase success, write the new value of option byte */
if(FLASH_EOP == ConfigSts)
{
/* Unlock option byte */
Option_Bytes_Unlock();
/* Clears the FLASH's pending flags */
FLASH_ClearFlag(FLASH_STS_CLRFLAG);
/* Enables the Option Bytes Programming operation */
FLASH->CTRL |= CTRL_Set_OPTPG;
/* Option byte must be programming in the unit of double-word */
/* Programming the 1st double word at 0x1FFF_E000 */
OBT->RDP2_RDP1 = pBuf[0];
OBT->CCMSRAM_RST_DBANK = pBuf[1];
/* Wait for the programming operation to complete */
ConfigSts = FLASH_WaitForLastOpt(ProgramTimeout);
/* Disable the Option Bytes Programming operation */
FLASH->CTRL &= CTRL_Reset_OPTPG;
}
4. 用互补标记跨复位传递工作模式。 工作模式写入 MODE_MARK_ADDR 所在备份 SRAM,写入原值与按位取反两个整数;读取时二者不互补即视为无效标记,复位后据此恢复上一次的切换方式。
static void SetModeMark(uint32_t mark)
{
uint32_t *pMark;
pMark = (uint32_t *)MODE_MARK_ADDR;
pMark[0] = mark;
pMark[1] = (~mark);
}
static uint32_t GetModeMark(void)
{
uint32_t *pMark;
uint32_t tMode;
pMark = (uint32_t *)MODE_MARK_ADDR;
tMode = pMark[0];
if(tMode != (~pMark[1]) )
{
tMode = 0xFFFFFFFFU;
}
return tMode;
}
对应源码: src/main.c、inc/main.h
5.14.3.2 Flash_Program 页擦除与双字编程
工程目录: projects/n32h49x_EVAL/examples/Flash/Flash_Program/
初始化串口→解锁 Flash 编程/擦除控制器→擦除起始地址所在页→按双字步进写入整页数据→锁定控制器→按字读回并逐字比对→打印测试结果
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示主存储区页的擦除与双字编程。 擦除 0x08008000 起始的一页后,以 8 字节为步长把固定数据写入整页,锁定控制器后逐字读回比对,并打印测试结果。 |
| 源码组成 | src/main.c:main,以及页大小与地址宏 FLASH_PAGE_SIZE、FLASH_WRITE_START_ADDR、FLASH_WRITE_END_ADDR;inc/main.h:公共头文件;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程,工程文件名为 Flash_Program_Proj。 |
| 关键配置 | 页大小 FLASH_PAGE_SIZE 为 0x2000(双 Bank 模式 8KB 一页);写入区间为 0x08008000~0x08010000; 写入数据固定为 0xCDEF89AB。 系统时钟 240 MHz,打印串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | main 先 log_init,调用 FLASH_Unlock;用 FLASH_EraseOnePage 擦除起始地址所在页,返回非 FLASH_EOP 时停在错误提示;以 8 字节为步长把同一双字写入整页,返回非 FLASH_EOP 同样停在错误提示;FLASH_Lock 后以 4 字节为步长读回比对,一致时打印测试结束。 |
| 主要 API | FLASH_Unlock、FLASH_EraseOnePage、FLASH_ProgramdoubleWord、FLASH_Lock |
| 验证方法 | 复位运行后串口打印 Flash Program Test Start; 擦除、编程与读回比对全部通过时打印 Flash Program Test End; 任一环节失败时停在对应错误提示。 |
| 使用提示 | 写入只支持双字,编程循环步长为 8 字节而读回步长为 4 字节。 写入前必须擦除,示例擦除的是 0x08008000 起始的一页。 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例把一整页擦除后按双字编程,再逐字读回验证数据一致性。
数据路径: FLASH_Unlock → FLASH_EraseOnePage(0x08008000) → FLASH_ProgramdoubleWord 按 8 字节步进写满一页 → FLASH_Lock → 逐字读回比对 → 串口打印结果
1. 解锁并擦除起始页。 示例先解锁编程/擦除控制器,再擦除写入区间起始地址所在页;擦除结果不等于 FLASH_EOP 时停在错误提示,不再执行编程。
/* Unlocks the FLASH Program Erase Controller */
FLASH_Unlock();
/* Erase */
if (FLASH_EOP != FLASH_EraseOnePage(FLASH_WRITE_START_ADDR))
{
while(1)
{
printf("Flash EraseOnePage Error. Please Deal With This Error Promptly\r\n");
}
}
2. 按双字步进写满整页。 循环以 8 字节为步长,每次把数据 0xCDEF89AB 作为两个 32 位字写入,步长与双字编程的对齐要求一致;返回非 FLASH_EOP 时停在错误提示。
/* Program */
for (Counter_Num = 0; Counter_Num < FLASH_PAGE_SIZE; Counter_Num += 8)
{
if (FLASH_EOP != FLASH_ProgramdoubleWord(FLASH_WRITE_START_ADDR + Counter_Num, Erase_Data,Erase_Data))
{
while(1)
{
log_info("Flash ProgramWord Error. Please Deal With This Error Promptly\r\n");
}
}
}
3. 锁定后逐字读回比对。 编程结束后锁定控制器,再以 4 字节为步长逐字读回,与写入数据不一致时打印测试失败;一致则继续打印测试结束。
/* Locks the FLASH Program Erase Controller */
FLASH_Lock();
/* Check */
for (Counter_Num = 0; Counter_Num < FLASH_PAGE_SIZE; Counter_Num += 4)
{
if (Erase_Data != (*(__IO uint32_t*)(FLASH_WRITE_START_ADDR + Counter_Num)))
{
printf("Flash Program Test Failed\r\n");
break;
}
}
对应源码: src/main.c
5.14.3.3 Flash_Row_Program 行编程
工程目录: projects/n32h49x_EVAL/examples/Flash/Flash_Row_Program/
初始化串口→解锁 Flash 编程/擦除控制器→擦除起始页→使能行编程器并选择主存储区→按 64 字节步长用 16 字连续编程→锁定控制器→逐字读回比对并打印结果
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示行编程器的连续写入能力。 擦除一页后使能行编程器,以 64 字节为步长一次写入 16 个字,锁定后逐字读回比对并打印结果。 |
| 源码组成 | src/main.c:main 与地址宏,以及 16 个元素的写入缓冲 Erase_Data;inc/main.h:公共头文件;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 写入缓冲区 Erase_Data[16] 全部为 0xCDEF89AB;FLASH_RowProgramSet(ENABLE) 使能行编程器,FLASH_RowProgramAreaSet(DISABLE) 选择在主存储区操作;行编程长度参数为 0x10,即 16 个字。 系统时钟 240 MHz,串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | 与 Flash_Program 相同的解锁与页擦除流程; 擦除后依次使能行编程器并指定主存储区; 以 64 字节为步长调用 FLASH_RowProgram,每次写入 16 个字;锁定后以 4 字节为步长读回比对缓冲首元素。 |
| 主要 API | FLASH_Unlock、FLASH_EraseOnePage、FLASH_RowProgramSet、FLASH_RowProgramAreaSet、FLASH_RowProgram、FLASH_Lock |
| 验证方法 | 复位运行后串口打印 Flash Row Program Test Start; 读回比对全部通过时打印 Flash Program Test End; 失败时打印 Flash Program Test Failed。 |
| 使用提示 | 行编程一次可写 2~16 个字且不能跨 512 字节,示例每次写 16 个字、步长 64 字节。 编程地址须为 8 字节对齐,字长度须为偶数。 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例用行编程器一次写入多个连续字,缩短整页写入的编程时间。
数据路径: FLASH_Unlock → FLASH_EraseOnePage → FLASH_RowProgramSet(ENABLE)/FLASH_RowProgramAreaSet(DISABLE) → FLASH_RowProgram 按 64 字节步进写 16 字 → FLASH_Lock
1. 使能行编程器并选择主存储区。 擦除完成后,示例先使能行编程器,再把操作区域设为主存储区;FLASH_RowProgramAreaSet(DISABLE) 对应在主存储区而非系统存储区编程。
/* Flash row programmer configure*/
FLASH_RowProgramSet(ENABLE);
FLASH_RowProgramAreaSet(DISABLE);
2. 按 64 字节步长连续编程。 循环以 64 字节为步长,每次调用 FLASH_RowProgram 写入 16 个字;单次写入不跨 512 字节,返回非 FLASH_EOP 时停在错误提示。
/*Row Program */
for (Counter_Num = 0; Counter_Num < FLASH_PAGE_SIZE; Counter_Num += 64)
{
if (FLASH_EOP != FLASH_RowProgram(FLASH_WRITE_START_ADDR + Counter_Num,0x10U, Erase_Data))
{
while(1)
{
log_info("Flash ProgramWord Error. Please Deal With This Error Promptly\r\n");
}
}
}
3. 锁定后读回比对。 锁定控制器后,示例以 4 字节为步长读回并与缓冲首个元素比对,不一致时打印测试失败,否则继续打印测试结束。
/* Locks the FLASH Program Erase Controller */
FLASH_Lock();
/* Check */
for (Counter_Num = 0; Counter_Num < FLASH_PAGE_SIZE; Counter_Num += 4)
{
if (Erase_Data[0] != (*(__IO uint32_t*)(FLASH_WRITE_START_ADDR + Counter_Num)))
{
printf("Flash Program Test Failed\r\n");
break;
}
}
对应源码: src/main.c
5.14.3.4 OptionByte_Config 选项字节配置
工程目录: projects/n32h49x_EVAL/examples/Flash/OptionByte_Config/
初始化串口→解锁 Flash 与选项字节控制器→擦除选项字节→依次编程读保护、写保护、数据字节与 SRAM ECC→锁定两个控制器→等待串口下发 0x55 恢复默认值
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示选项字节的擦除与编程。 复位后擦除选项字节并依次配置读保护、Bank 模式、USER/USER2、写保护、数据字节与 SRAM ECC,再等待串口下发 0x55 把选项字节恢复为默认值。 |
| 源码组成 | src/main.c:main,包含默认配置与 0x55 恢复两段流程;inc/main.h:公共头文件;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 默认配置为双 Bank 模式、CCM SRAM 复位不擦除、软件 IWDG、BOR 阈值 1.6V; 写保护配置为 FLASH_WRP_NUM16(单 Bank 第 32~33 页,双 Bank 第 64~67 页);选项字节数据写为 0x55、0x66、0x77、0xAA; SRAM2、SRAM3 ECC 使能。 系统时钟 240 MHz,串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | main 先 log_init,调用 FLASH_Unlock 与 Option_Bytes_Unlock;用 FLASH_EraseOB 擦除选项字节,返回 FLASH_EOP 后依次调用 FLASH_ProgramOB_RRDC、FLASH_ProgramOB_U1U2、FLASH_EnWriteProtection、FLASH_ProgramOB_Data、FLASH_ProgramOB_SRAMECC;每一步用 FLASH_EOP 判断是否继续,全部完成后锁定两个控制器;主循环等待 USART1 收到 0x55,再以默认参数重新编程一组选项字节。 |
| 主要 API | FLASH_Unlock、Option_Bytes_Unlock、FLASH_EraseOB、FLASH_ProgramOB_RRDC、FLASH_ProgramOB_U1U2、FLASH_EnWriteProtection、FLASH_ProgramOB_Data、FLASH_ProgramOB_SRAMECC、FLASH_Lock、Option_Bytes_Lock |
| 验证方法 | 复位运行后串口打印 Option Byte configure Test start; 五步编程全部成功时打印 Option Byte configure OK; 下发 0x55 后打印恢复默认值成功或失败。 |
| 使用提示 | 选项字节编程以双字为单位,先擦除再写,且需先解锁 Flash 与选项字节两个控制器。 读出保护 L2、Bank 模式切换等改动需重新刷写 Flash 才完全生效。 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例演示选项字节的整组擦除与逐项编程,以及如何把选项字节恢复为默认值。
数据路径: FLASH_Unlock/Option_Bytes_Unlock → FLASH_EraseOB → FLASH_ProgramOB_RRDC 等五个编程函数 → FLASH_Lock/Option_Bytes_Lock → 串口 0x55 触发默认值恢复
1. 擦除选项字节并逐项编程。 示例先解锁两个控制器并擦除选项字节;擦除成功后按顺序编程 USER/USER2,每一步都以返回状态判断是否继续。
/* Unlocks the FLASH Program Erase Controller */
FLASH_Unlock();
/* Unlocks the Option Byte Program Erase Controller */
Option_Bytes_Unlock();
/* Erase Option Byte page */
state_value = FLASH_EraseOB();
if(state_value == FLASH_EOP)
{
if(state_value == FLASH_EOP)
{
/* Configure option bytes RDP2, user2 and user3 */
state_value = FLASH_ProgramOB_U1U2(FLASH_OB_IWDG_SOFTWARE,FLASH_OB_STOP_NORST,FLASH_OB_STDBY_NORST,\
FLASH_OB_IWDG_STOP_NOFRZ,FLASH_OB_IWDG_STDBY_NOFRZ,FLASH_OB_IWDG_SLEEP_NOFRZ,\
FLASH_OB2_NBOOT0_SET,FLASH_OB2_NBOOT1_SET,FLASH_OB2_NSWBOOT0_SET,\
FLASH_OB2_FLASHBOOT_SET,FLASH_OB2_DAC_SET,BOR_LEVEL_1_6V);
}
2. 编程写保护、数据字节与 SRAM ECC。 同一层级的后续三步分别配置写保护页、选项字节数据与 SRAM2、SRAM3 的 ECC 使能位,写法与前一步一致,失败时进入空分支不处理。
if(state_value == FLASH_EOP)
{
/* Enable writing protection Single Bank: page 32 to 33, Dual Banke: page 64 to 67 */
state_value = FLASH_EnWriteProtection(FLASH_WRP_NUM16);
}
else
{
/* no process*/
}
if(state_value == FLASH_EOP)
{
/* Configure option byte datax */
state_value = FLASH_ProgramOB_Data(0x55,0x66,0x77,0xAA);
if(state_value == FLASH_EOP)
{
/* Configure option byte CCMSRAM reset without erasing */
state_value = FLASH_ProgramOB_SRAMECC(SRAM2_ECC_ENABLE,SRAM3_ECC_ENABLE);
}
else
{
/* no process*/
}
3. 用串口 0x55 恢复默认值。 主循环收到 0x55 后重复解锁与擦除流程,再以默认参数重新写读保护与 Bank 模式,从而把之前改动的选项字节恢复为默认值。
UartCmd = USART_ReceiveData(USART1);
if(UartCmd == 0x55)
{
/* Unlocks the FLASH Program Erase Controller */
FLASH_Unlock();
/* Unlocks the Option Byte Program Erase Controller */
Option_Bytes_Unlock();
/* Erase Option Byte page */
state_value = FLASH_EraseOB();
对应源码: src/main.c
5.14.3.5 Run_In_CCM 在 CCM SRAM 中运行代码
工程目录: projects/n32h49x_EVAL/examples/Flash/Run_In_CCM/
初始化串口→把启动代码已拷贝到 CCM SRAM 的函数字节镜像到普通 SRAM 备份→用 RCC 一键初始化把 CCM SRAM 填零并建立 ECC 位→把备份字节写回 CCM SRAM→打印三个函数执行地址并确认落在 CCM SRAM 范围→执行三级嵌套调用链并校验返回值
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示把函数代码存放于 Flash、运行时复制到 CCM SRAM 并在其中执行的方法。 示例用三级嵌套调用链,打印三个函数的执行地址确认位于 CCM SRAM,并校验调用链返回值为 448。 |
| 源码组成 | src/main.c:main、CCM_SRAM_Init、CCM_SRAM_SaveCode、CCM_SRAM_RestoreCode 与三个被标记的 CCM 函数;inc/main.h:公共头文件;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/(含自定义分散加载文件 Run_In_CCM.sct)、EWARM/(含自定义 ICF 文件 Run_In_CCM.icf):Keil 与 IAR 工程。 |
| 关键配置 | CCM SRAM 范围为 0x20070000~0x2007FFFF,大小 64KB; 备份缓冲 ccm_backup 为 256 个字;__CCM_FUNC 宏按工具链把函数放到 CCM 段(Keil ccmram、IAR CCM_CODE),由自定义链接脚本指定函数的加载地址在 Flash、执行地址在 CCM SRAM。系统时钟 240 MHz,串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | main 先 log_init;调用 CCM_SRAM_SaveCode 把 CCM SRAM 现有内容镜像到 ccm_backup;调用 CCM_SRAM_Init,依次写起始地址、配置初始化范围与值、启动一键初始化并等待完成,再调用 CCM_ModeSet;CCM_SRAM_RestoreCode 把备份写回;取三个函数地址判断是否落在 CCM SRAM 范围内,最后调用 CCM_WeightedSumOfSquares(5) 并校验返回 448。 |
| 主要 API | CCM_ModeSet(CCM SRAM 一键初始化由 RCC->SRAMCFG1~SRAMCFG4 直接配置) |
| 验证方法 | 串口依次打印 CCM Function Code Saved、CCM SRAM Initialized、CCM Function Code Restored; 三个函数执行地址均落在 CCM SRAM 范围时打印 [PASS]; 调用链返回 448 时打印 Run_In_CCM Test Passed。 |
| 使用提示 | CCM SRAM 默认使能 ECC,读取前须保证 ECC 位有效; 一键初始化会清零整个 CCM SRAM,包含启动代码已拷贝的函数代码,因此须在初始化后重新写回。 Keil 工程须使用 Run_In_CCM.sct,IAR 工程须使用 Run_In_CCM.icf。开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例说明如何把函数放到 CCM SRAM 执行,并用备份缓冲避免一键初始化清零代码。
数据路径: CCM_SRAM_SaveCode 镜像 CCM SRAM → CCM_SRAM_Init 一键初始化并 CCM_ModeSet → CCM_SRAM_RestoreCode 写回 → 校验函数地址在 CCM SRAM → CCM_WeightedSumOfSquares 返回 448
1. 用宏把函数放进 CCM 段。 示例按工具链定义 __CCM_FUNC,Keil 使用 ccmram 段、IAR 使用自定义的 CCM_CODE 段;标记后的函数加载地址仍在 Flash,由链接脚本决定执行地址在 CCM SRAM。
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
#define __CCM_FUNC __attribute__((section("ccmram")))
#elif defined(__ICCARM__)
#define __CCM_FUNC _Pragma("location=\"CCM_CODE\"")
#elif defined(__GNUC__)
#define __CCM_FUNC __attribute__((section(".ccmram")))
#else
#define __CCM_FUNC
#endif
2. 一键初始化 CCM SRAM。 CCM_SRAM_Init 先向起始地址写一个初始化值,再配置初始化范围与值,启动一键初始化并等待完成标志,最后清使能位并打开 CCM 模式。
*(__IO uint32_t *)CCM_SRAM_BASE = 0x00000000U;
/* Step 1: Configure initialization range
End address must differ from start address */
RCC->SRAMCFG3 = (uint32_t)CCM_SRAM_BASE;
RCC->SRAMCFG4 = (uint32_t)(CCM_SRAM_BASE + CCM_SRAM_SIZE - 4U);
/* Step 2: Configure initialization value */
RCC->SRAMCFG2 = 0x00000000U;
/* Step 3: Start one-key initialization */
RCC->SRAMCFG1 |= RCC_SRAMCFG1_SRINIEN;
/* Step 4: Wait for initialization complete */
while (!(RCC->SRAMCFG1 & RCC_SRAMCFG1_SRINIF))
{
}
/* Clear initialization enable */
RCC->SRAMCFG1 &= ~RCC_SRAMCFG1_SRINIEN;
/* Enable CCM mode */
CCM_ModeSet(ENABLE);
3. 备份代码、写回并校验执行地址。 一键初始化会覆盖启动代码已拷贝到 CCM SRAM 的函数字节,示例先把这些字镜像到普通 SRAM,初始化后再写回;随后取三个函数地址判断是否落在 CCM SRAM 范围内。
volatile uint32_t *src = (volatile uint32_t *)CCM_SRAM_BASE;
uint32_t i;
for (i = 0U; i < CCM_BACKUP_WORDS; i++)
{
ccm_backup[i] = src[i];
}
addr_square = (uint32_t)CCM_Square & ~1U;
addr_sum = (uint32_t)CCM_SumOfSquares & ~1U;
addr_weighted = (uint32_t)CCM_WeightedSumOfSquares & ~1U;
printf("CCM_Square Address : 0x%08X\r\n", (unsigned int)addr_square);
printf("CCM_SumOfSquares Address : 0x%08X\r\n", (unsigned int)addr_sum);
printf("CCM_WeightedSumOfSquares Address: 0x%08X\r\n", (unsigned int)addr_weighted);
printf("CCM SRAM Range: 0x%08X ~ 0x%08X\r\n",
(unsigned int)CCM_SRAM_BASE, (unsigned int)CCM_SRAM_END);
if ((addr_square >= CCM_SRAM_BASE) && (addr_square <= CCM_SRAM_END) &&
(addr_sum >= CCM_SRAM_BASE) && (addr_sum <= CCM_SRAM_END) &&
(addr_weighted >= CCM_SRAM_BASE) && (addr_weighted <= CCM_SRAM_END))
{
printf("All Functions In CCM SRAM [PASS]\r\n");
}
else
{
printf("Function NOT In CCM SRAM [FAIL]\r\n");
while (1)
{
}
}
对应源码: src/main.c
5.14.3.6 SingleBankRemap 单 Bank 启动重映射
工程目录: projects/n32h49x_EVAL/examples/Flash/SingleBankRemap/
初始化串口→读取并打印当前 Bank 模式→读取启动重映射状态→等待串口指令→改写启动区选项字节并复位或直接重映射→从主存储区前/后半段启动
| 项目 | 源码解读 |
|---|---|
| 功能 | 演示单 Bank 模式(DBANK=0)下的启动重映射。 示例读取当前 Bank 模式与启动重映射状态,通过串口指令改写启动区选项字节或直接重映射,使系统从主存储区前/后半段启动。 |
| 源码组成 | src/main.c:main 与启动使能位宏 FLASH_BOOTENABLE;inc/main.h:公共头文件;src/n32h49x_it.c、inc/n32h49x_it.h:中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 启动使能标志位 FLASH_BOOTENABLE 为 0x00080000,通过系统存储区地址 0x1FFFE010 判断启动区;启动区由选项字节 USER2 的 FLASH_OB2_FLASHBOOT 位决定;重映射状态通过 RCC->BOOTREMAP 的 RCC_BOOTREMAP_REMAPSEL 域读取。系统时钟 240 MHz,串口 USART1 TX PA9、RX PA10,波特率 115200。 |
| 程序与数据路径 | main 先 log_init;用 FLASH_GetFlagSTS(FLASH_FLAG_BANKMODE) 打印当前 Bank 模式,再读 RCC->BOOTREMAP 与 0x1FFFE010 判断当前启动区;主循环轮询 USART1:0x55 配置前半段为启动区、0x66 配置后半段为启动区,二者改写选项字节后复位; 0x77 与 0x88 只做前后半段重映射。 |
| 主要 API | FLASH_GetFlagSTS、FLASH_Unlock、FLASH_EraseOB、FLASH_ProgramOB_RRDC、FLASH_ProgramOB_U1U2 |
| 验证方法 | 复位运行后串口打印当前 Bank 模式和启动区; 下发 0x55 或 0x66 后系统复位并从对应半段启动; 下发 0x77 或 0x88 后直接重映射并从对应半段启动。 |
| 使用提示 | 单 Bank 模式下主存储区分前后两半段,启动地址始终是 0x08000000。 改写启动区选项字节后需要系统复位,示例用 NVIC_SystemReset 完成。开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1。 |
核心代码解读与移植
示例读取启动区来源,并通过选项字节或 RCC 重映射把启动区切换到主存储区的另一半。
数据路径: 读 FLASH_FLAG_BANKMODE 与 RCC->BOOTREMAP/0x1FFFE010 → 串口指令 → FLASH_ProgramOB_U1U2 改启动位并复位,或 RCC_ConfigRemapMode/RCC_EnableRemap 重映射
1. 读取 Bank 模式与启动区。 示例先打印 Bank 模式,再读重映射寄存器;未使能重映射时改读系统存储区的启动使能位,据此判断系统从主存储区的前半段还是后半段启动。
/* Show bank mode */
if(FLASH_GetFlagSTS(FLASH_FLAG_BANKMODE) == SET)
{
log_info("FLASH is dual bank mode!\r\n");
}
else
{
log_info("FLASH is single bank mode!\r\n");
}
Value_temp = RCC->BOOTREMAP & RCC_BOOTREMAP_REMAPSEL;
if(Value_temp == RCC_REMAP_BFLASH)
{
FlashRemap = RCC_REMAP_BFLASH;
log_info("Flash starts from the forward half, with startup address 0x08000000!\r\n");
}
else if(Value_temp == RCC_REMAP_AFLASH)
{
FlashRemap = RCC_REMAP_AFLASH;
log_info("Flash starts from the back half, with startup address 0x08000000!\r\n");
}
else
{
log_info("No boot remap!\r\n");
if(((*(uint32_t*)(0x1FFFE010)) & FLASH_BOOTENABLE) == FLASH_BOOTENABLE)
{
FlashRemap = RCC_REMAP_BFLASH;
printf("System start from the forward half,with startup address 0x08000000!\r\n");
}
else
{
FlashRemap = RCC_REMAP_AFLASH;
printf("System start from the back half,with startup address 0x08000000!\r\n");
}
}
2. 改写启动区选项字节并复位。 需要持久改变启动区时,示例解锁并擦除选项字节,先配置为单 Bank 模式,再用 USER2 的启动位写入目标半段,最后调用 NVIC_SystemReset 复位。
if(UartCmd == 0xDD) /* Modify OB */
{
FLASH_Unlock();
FLASH_EraseOB();
/* Configure FLASH to Single BANK mode */
FLASH_ProgramOB_RRDC(FLASH_OB_RDP1_DISABLE,FLASH_OB_RDP2_DISABLE,FLASH_SINGLE_BANK,CCMSRAM_RST_NERASE);
/* Configure FLASH BANK1 startup */
FLASH_ProgramOB_U1U2(FLASH_OB_IWDG_SOFTWARE,FLASH_OB_STOP_NORST,FLASH_OB_STDBY_NORST,FLASH_OB_IWDG_STOP_NOFRZ,\
FLASH_OB_IWDG_STDBY_NOFRZ,FLASH_OB_IWDG_SLEEP_NOFRZ,FLASH_OB2_NBOOT0_SET,FLASH_OB2_NBOOT1_SET,\
FLASH_OB2_NSWBOOT0_SET,Value_temp,FLASH_OB2_DAC_SET, BOR_LEVEL_1_6V);
log_info("System reset !\r\n");
NVIC_SystemReset();
}
3. 直接重映射启动区。 不需要改写选项字节时,示例只调用 RCC_ConfigRemapMode 与 RCC_EnableRemap 立即切换启动映射,不触发复位。
else if(UartCmd == 0xEE) /* Remap */
{
RCC_ConfigRemapMode(Value_temp);
RCC_EnableRemap();
}
对应源码: src/main.c
5.14.4 注意与排障
| 场景 | 检查与建议 | 来源 |
|---|---|---|
| 编程/擦除的时钟条件 | 进行 Flash 编程(写入或擦除)时必须打开内部 RC 振荡器(HSI); 低功耗模式下所有 Flash 操作都被中止。 |
用户手册 |
| 写操作与擦除粒度 | Flash 写入只支持 64 位双字; 编程阶段写入半字会产生总线错误; 写入前须先擦除,双 BANK 模式最小擦除单位为 8KB 一页,单 BANK 模式为 16KB 一页。 |
用户手册 |
| BUSY 期间的访问限制 | FLASH_STS.BUSY 为 1 时不能对任何 Flash 寄存器执行写操作,也不能对同一片 Flash 同时读写。 |
用户手册 |
| 页擦除地址对齐 | 单 BANK 模式下 Page_Address 须为 0x4000 的整数倍(每页 16KB);双 BANK 模式下须为 0x2000 的整数倍(每页 8KB)。 |
用户手册 |
| 整片擦除的 BANK 选择 | DBANK=0(单 BANK)时,只置位 MER1 或 MER2 不会执行整片擦除。 | 用户手册 |
| 行编程的地址跨度 | 行编程不能跨 512 字节; 编程地址要与行编程的开始地址及字长度一致。 |
用户手册 |
| 双 BANK 读写并发 | 双 BANK 模式(DBANK=1)允许一个 Bank 擦除或编程的同时从另一个 Bank 读取; 不允许同时进行两次写操作; 选项字节与 BANK1 位于同一片 Flash,不能同时操作。 |
用户手册 |
| 选项字节解锁 | 对选项字节编程或擦除前须先解锁 Flash 与选项字节(FLASH_OPTKEY 写入 KEY1 0x45670123、KEY2 0xCDEF89AB);OPTWE=0 时选项字节被锁定。 |
用户手册 |
| BANK 模式切换后重刷 | 通过选项字节切换 BANK 模式后,主存储区结构发生变化,需要重新刷写 Flash。 | 用户手册 |
| 写保护生效条件 | 通过 WRP 配置写保护后,需进行一次系统复位才能生效; 对受保护的页编程或擦除会返回保护错误标志。 |
用户手册 |
| 读出保护 L1 | 使能读出保护 L1 后,除整片擦除外,全部主存储区页不允许在调试模式下或从内部 SRAM 启动后执行写或擦除。 | 用户手册 |
| 等待周期与预取 | 读等待周期须随 AHB 时钟提高而增大(48 MHz 内为 0、96 MHz 内为 1、144 MHz 内为 2、192 MHz 内为 3、240 MHz 内为 4); 等待周期不为零时启用预取缓冲可提高效率。 |
用户手册 |