# 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`->2 8051 CPU->2.2 Memory。 对于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://www.leconiot.com/md_res/jaysnote/cc2530_mem_arch/images/xdata.png) * 方便DMA的获取,如上的 `SRAM`、`8051 DATA SPACE`、 `XREG`、`8051 SFR SPACE`被映射在`XDATA`的低30KB; * 2KB的`INFORMATION PAGE `用以存储IEEE地址的信息; * 高32KB用以映射需要读写的Flash区域; > **提示**:在程序执行阶段的Flash读写操作,比如Falsh作为NV; ### CODE ![](http://www.leconiot.com/md_res/jaysnote/cc2530_mem_arch/images/code.png) * 可选的直接SRAM直接映射到`CODE` 存储空间,也就是直接可以从SRAM启动并且执行代码; ## 疑问 看到这里,如果说8kb的sram可以同时支持映射在如上图的`CODE`中间区域和`XDATA起始`区域。256kb的flash又映射到哪里了? 原来这里还需要回头看看系统架构。 ![](http://www.leconiot.com/md_res/jaysnote/cc2530_mem_arch/images/cpu_arch.png) 在`8051 CPU CORE`和物理存储器之间还有一个`MEMMORY ARBITER`存储仲裁者。而该控制器会通过寄存器控制选型将256kb的flash再以32kb为单位做选择性映射。 ![](http://www.leconiot.com/md_res/jaysnote/cc2530_mem_arch/images/memctr.png) 如上的`MEMCTR`和`FMAP`其实支持把Flash映射到 `XDATA`和`CODE`,理顺是改区域的用途,例如存储代码和常量只需要映射到`CODE`。做Nv就需要到`XDATA`区域。 我们快速验证hal_flash.c 作为nv中的实际pg 和偏移地址到 xbank的映射的配置。 ```c //hal_falsh.c HalFlashRead Line.70 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; // Save to restore. // 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` 表示如上32kb(16page)为单位的`XBANK[0:2]`配置值; * `(pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE)` 就表示XBANK32kb的区域的内部偏移; ## 从Hex文件找出变量的NV值 对于如下的`registered` 变量我们如何找出他对应hex的存储位置。 ``` osal_nv_item_init(MXJ_NV,1,NULL); //初始化NV条目 if(osal_nv_read(MXJ_NV,0,1,®istered)!=SUCCESS) ``` 在线Debug,找到如上`osal_nv_read`->`HalFlashRead` pg=121 offset= 848; ``` address=121*2048+848; ```