这里会显示出您选择的修订版和当前版本之间的差别。
jaysnote:cc2530_mem_arch [2018/11/22 20:47] jaylee |
jaysnote:cc2530_mem_arch [2021/06/22 23:14] |
||
---|---|---|---|
行 1: | 行 1: | ||
- | < | ||
- | |||
- | # CC2530 存储架构 | ||
- | |||
- | 在理解CC2530的51内核存储结构上面吃力了。先提出疑问,在`swru191f-CC253xSystem-on-ChipSolutionfor2.4-GHz IEEE 802.15.4andZigBee® Application .pdf`上面介绍如下的存储空间,但是确找不到对应的sram和256kb的flash 映射空间。 | ||
- | |||
- | ## 8051 CPU 架构 | ||
- | |||
- | 在CC2530的Dtasheet上面详细介绍了8051 CPU的存储架构 | ||
- | |||
- | > `swru191f-CC253xSystem-on-ChipSolutionfor2.4-GHz IEEE 802.15.4andZigBee® Application .pdf`-> | ||
- | |||
- | 对于8051的CPU存储空间,区分以下4类; | ||
- | |||
- | * **CODE** 只读存储空间,应用存储,64KB; | ||
- | |||
- | * **DATA** 读写存储空间,单CPU指令周期读写,256个字节,低128字节支持直接或者间接访问,高128字节支持间接访问; | ||
- | |||
- | * **XDATA**读写存储空间,访问周期在4-5个CPU指令周期,64KB,访问速度慢于 **DATA**空间,同时**CODE** 和**XDATA**共享一部分的公用总线,因为,**CODE**预取指和**XDATA**的访问不能并行。 | ||
- | |||
- | * **SFR** 可读写的特殊功能寄存器存储空间,支持单CPU指令周期直接访问,128字节,对于寄存器,划分为字节单位,直接位直接访问。 | ||
- | |||
- | 对于以上CODE和DATA存储空间需要特别注意 | ||
- | |||
- | ### XDATA | ||
- | |||
- | ![](http:// | ||
- | |||
- | * 方便DMA的获取,如上的 `SRAM`、`8051 DATA SPACE`、 `XREG`、`8051 SFR SPACE`被映射在`XDATA`的低30KB; | ||
- | |||
- | * 2KB的`INFORMATION | ||
- | |||
- | * 高32KB用以映射需要读写的Flash区域; | ||
- | |||
- | > **提示**:在程序执行阶段的Flash读写操作,比如Falsh作为NV; | ||
- | |||
- | ### CODE | ||
- | |||
- | ![](http:// | ||
- | |||
- | * 可选的直接SRAM直接映射到`CODE` 存储空间,也就是直接可以从SRAM启动并且执行代码; | ||
- | |||
- | |||
- | |||
- | ## 疑问 | ||
- | |||
- | 看到这里,如果说8kb的sram可以同时支持映射在如上图的`CODE`中间区域和`XDATA起始`区域。256kb的flash又映射到哪里了? | ||
- | |||
- | 原来这里还需要回头看看系统架构。 | ||
- | |||
- | ![](http:// | ||
- | |||
- | 在`8051 CPU CORE`和物理存储器之间还有一个`MEMMORY ARBITER`存储仲裁者。而该控制器会通过寄存器控制选型将256kb的flash再以32kb为单位做选择性映射。 | ||
- | |||
- | ![](http:// | ||
- | |||
- | 如上的`MEMCTR`和`FMAP`其实支持把Flash映射到 `XDATA`和`CODE`,理顺是改区域的用途,例如存储代码和常量只需要映射到`CODE`。做Nv就需要到`XDATA`区域。 | ||
- | |||
- | 我们快速验证hal_flash.c 作为nv中的实际pg 和偏移地址到 xbank的映射的配置。 | ||
- | |||
- | ```c | ||
- | // | ||
- | void HalFlashRead(uint8 pg, uint16 offset, uint8 *buf, uint16 cnt) { | ||
- | // Calculate the offset into the containing flash bank as it gets mapped into XDATA. | ||
- | uint8 *pData = (uint8 *)(offset + HAL_FLASH_PAGE_MAP) + | ||
- | ((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE); | ||
- | uint8 memctr = MEMCTR; | ||
- | // Calculate and map the containing flash bank into XDATA. | ||
- | MEMCTR = (MEMCTR & 0xF8) | pg; | ||
- | while (cnt--) | ||
- | *buf++ = *pData++; | ||
- | } | ||
- | MEMCTR = memctr; | ||
- | } | ||
- | ``` | ||
- | |||
- | * `HAL_FLASH_PAGE_MAP`表示flash映射到`XDATA`区域的高32kb(0x8000) | ||
- | * `pg /= HAL_FLASH_PAGE_PER_BANK` | ||
- | * `(pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE)` 就表示XBANK32kb的区域的内部偏移; | ||
- | |||
- | |||
- | |||
- | ## 从Hex文件找出变量的NV值 | ||
- | |||
- | 对于如下的`registered` 变量我们如何找出他对应hex的存储位置。 | ||
- | |||
- | ``` | ||
- | osal_nv_item_init(MXJ_NV, | ||
- | if(osal_nv_read(MXJ_NV, | ||
- | ``` | ||
- | |||
- | 在线Debug,找到如上`osal_nv_read`-> | ||
- | |||
- | ``` | ||
- | address=121*2048+848; | ||
- | |||
- | ``` | ||
- | </ | ||