关于 单片机内部地址疑惑!!

[复制链接]
1326|13
手机看帖
扫描二维码
随时随地手机跟帖
suxilong|  楼主 | 2018-7-3 09:51 | 显示全部楼层 |阅读模式
本帖最后由 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  这段区间用来干嘛了? 怎么它就可以操作了?









  

用与类比

用与类比

相关帖子

xuyaqi| | 2018-7-3 10:20 | 显示全部楼层
1 flash.png


2 应该是flash_wirte( 0x0800 0000+A, ...., ....)

使用特权

评论回复
suxilong|  楼主 | 2018-7-3 13:39 | 显示全部楼层

谢谢!

答案1  中的截图 是? STM32 的吗?

答案2  适合 STM32  内部flash的 操作, 但是对于mt2523 内部flash 操作 则不适合 , mt2523 使用的是 去0x08000000  才可以。即flash_wirte( A, ...., ....)

使用特权

评论回复
xuyaqi| | 2018-7-3 14:24 | 显示全部楼层
suxilong 发表于 2018-7-3 13:39
谢谢!

答案1  中的截图 是? STM32 的吗?

1 是STM32f103 的
2 要看相关芯片的说明书,使用方法不通用。

使用特权

评论回复
一周一天班| | 2018-7-4 07:20 | 显示全部楼层
地址0放芯片内部boot管理程序,rom内置。和电脑一样,他把你程序加载到合适位置,arm是把flash程序读到ram中某位置并完成映射。

使用特权

评论回复
一周一天班| | 2018-7-4 07:23 | 显示全部楼层
看程序在flash运行还是ram运行,两种启动方式不一样,不能混着看。stm32简单,芯片boot启动后将指针交给flah即可。mdk要boot读flash到ram,在指针交给ram

使用特权

评论回复
一周一天班| | 2018-7-4 07:25 | 显示全部楼层
本帖最后由 一周一天班 于 2018-7-4 07:26 编辑

ram运行模式下,程序可以放nor,nand,spi,i2c,sd卡,,,,,

使用特权

评论回复
一周一天班| | 2018-7-4 07:29 | 显示全部楼层
0x0800,可以放用户自己boot,比如linux就是,程序放哪不重要。

使用特权

评论回复
suxilong|  楼主 | 2018-7-4 09:21 | 显示全部楼层
xuyaqi 发表于 2018-7-3 14:24
1 是STM32f103 的
2 要看相关芯片的说明书,使用方法不通用。

是啊,使用方法不是通用, 关键是 MTK的 API 说明文档太简略了~~~就简简单单一句:

// Start_address should be within flash size.

但是实际它又不是用0x08000000 以上的地址,而是 使用减去0x08000000 的地址

使用特权

评论回复
suxilong|  楼主 | 2018-7-4 09:23 | 显示全部楼层
一周一天班 发表于 2018-7-4 07:23
看程序在flash运行还是ram运行,两种启动方式不一样,不能混着看。stm32简单,芯片boot启动后将指针交给fla ...

谢谢你, 应该就是你说的这个原因, 要看程序是 在哪里运行~~~ 应该就是 将flash 读出来 然后映射到 RAM 上面进行 运行, 而操作flash 的时候 又得映射回来 ,使用实际物理的flash 地址~~~

使用特权

评论回复
一周一天班| | 2018-7-4 21:54 | 显示全部楼层
不是,你理解错了。

使用特权

评论回复
linqing171| | 2018-7-4 22:32 | 显示全部楼层
要一层层的把代码扒到flash控制器的寄存器操作那里。
flash控制器设计的时候,其寄存器里面填入的是没有偏移量的地址。而读写函数,是c语言写的,你可以写个flash_write(addr,xxx); addr带不带偏移是做软件的人说了算的,风格确实不一,一般传char*格式的地址应该是总线的,unsigned int类型的地址鬼知道带不带偏移。

一个flash可以挂总线的任意地址上,只要是片选信号结对应的译码就可以了。所以寄存器里面填上的都是内部地址。

使用特权

评论回复
suxilong|  楼主 | 2018-7-12 13:17 | 显示全部楼层
一周一天班 发表于 2018-7-4 21:54
不是,你理解错了。

不是 ???

使用特权

评论回复
suxilong|  楼主 | 2018-7-12 13:18 | 显示全部楼层
linqing171 发表于 2018-7-4 22:32
要一层层的把代码扒到flash控制器的寄存器操作那里。
flash控制器设计的时候,其寄存器里面填入的是没有偏 ...

SDK 里面 只提供到 flash_write(addr,xxx); ~~~~

在下去就看不到了~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:没有最差,只有最懒

55

主题

339

帖子

4

粉丝