本帖最后由 suxilong 于 2018-7-3 09:54 编辑
如图所示 这是一个STM32 内部地址映射表...
大家都说 stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小!!! 这听起来很有道理,但是细思又有些疑问:
1. 起始于0x0800 0000, 也许这是芯片设计时定下来的, 那我就疑问 0x0000 0000 到 0x0800 0000 这段区间用来干嘛了?放bootloader 吗???
2. 结束地址是0x0800 0000加上芯片实际的flash大小。 那是不是意味着 如果要操作 flash 的某个地址,比如A(A的值是在 小于 Flash 的size), 那么操作的地址是不是flash_wirte( 0x0800 0000+A, ...., ....) ? 还是flash_wirte( A, ...., ....) ?
以上 提及STM32 主要是用在下面MT2523 碰到的问题进行对比。因为他们都是cortex-M 的ARM核。
实际遇到的问题是在做mtk 2523 的蓝牙芯片OTA 碰到的的问题。
这个芯片 的memory map 设置如下:
其中 BL_BASE 存放 bootloader ,
CM4_BASE 存放 cortex-M4 运行的程序,
FOTA_RESERVED_BASE 存放 OTA接收到的 新的 cortex-M4 程序
....
#define BL_BASE 0x08000000
#define BL_LENGTH 0x00010000 /* 64kB */
#define CM4_BASE 0x08010000
#define CM4_LENGTH 0x00250000 /* 2368K */
#define FOTA_RESERVED_BASE 0x08260000
#define FOTA_RESERVED_LENGTH 0x00180000 /* 1536K */
#define ROM_NVDM_BASE 0x083E0000
#define ROM_NVDM_LENGTH 0x00010000 /* 64kB */
#define ROM_EPO_BASE 0x083F0000
#define ROM_EPO_LENGTH 0x00010000 /* 64kB */
然在它提供的 ota 例程中 接收到新程序 包时,开始写入flash 的起始地址是:s_fota_mem_info.start_address = FOTA_RESERVED_BASE - BL_BASE;
代码 如下:
<p>if (FOTA_UPDATE_FBIN == update_type) </p><p>{
s_fota_mem_info.start_address = FOTA_RESERVED_BASE - BL_BASE
s_fota_mem_info.end_address = FOTA_RESERVED_BASE + FOTA_RESERVED_LENGTH - BL_BASE
s_fota_mem_info.reserved_size = FOTA_RESERVED_LENGTH;
s_fota_mem_info.block_count = FOTA_RESERVED_LENGTH >> 12;
s_fota_mem_info.block_size = FLASH_BLOCK_SIZE;
s_fota_mem_info.block_type = HAL_FLASH_BLOCK_4K;
s_fota_mem_info.total_received = 0;
s_fota_mem_info.write_ptr = 0;
s_fota_mem_info.ubin_pack_count = 0;</p><p>}</p></p>
这就很奇怪了, 关于上面第2个问题就出现, 为什么操作地址不是0x08260000, 而是 0x08260000-0x08000000 ??? 难道0x08000000 是一个假的虚拟地址???
MTK 提供的SDK 中 flash 写操作的函数如下: (擦除和读操作基本一样就不一 一列举出来)
/**
* [url=home.php?mod=space&uid=247401]@brief[/url] flash write
* @param[in] address is starting address to write from.Before the address can be written to for the first time,
* the address located sector or block must first be erased.
* @param[in] length is data length
* @param[in] data is source data to be written
* @return
* #HAL_FLASH_STATUS_OK on success
*/
hal_flash_status_t hal_flash_write(uint32_t address, const uint8_t *data, uint32_t length);
我尝试 过 hal_flash_status_t hal_flash_write(FOTA_RESERVED_BASE , data,length); 但是函数返回值都提示 地址是无效的,
但是hal_flash_status_t hal_flash_write(FOTA_RESERVED_BASE - BL_BASE , data,length); 就是正常的!
那么第1 个问题 就来了, 既然flash 起始于0x0800 0000, 那么 0x0000 0000 到 0x0800 0000 这段区间用来干嘛了? 怎么它就可以操作了?
|