CC2530之Flash笔记

最近在看CC2530的Flash部分,翻阅一些文章,将记录下来,做为笔记以免遗忘,如有错误之处请指出。

参考文章:
http://www.cfanz.cn/?c=article&a=read&id=173767
http://www.xuebuyuan.com/1035130.html
http://blog.csdn.net/crystal736/article/details/8727111
https://wenku.baidu.com/view/b640309043323968001c925d.html
http://www.xuexila.com/diannao/rumen/607222.html
http://www.cnblogs.com/felixfang/p/3420462.html

一、基础知识
我使用的TI的芯片型号为CC2530-F256,拥有256K的 Flash,8K SRAM,内核为8051,只支持64K访问空间,以下为一些基本概念。
1.CODE. A read-only memory space for program memory. This memory
space addresses 64 KB.
2.DATA. A read/write data memory space that can be directly or indirectly accessed by a single-cycle CPU instruction. This memory space addresses 256 bytes. The lower 128 bytes of the DATA memory space can be addressed either directly or indirectly, the upper 128 bytes only indirectly.
3.XDATA. A read/write data memory space, access to which usually requires 4–5 CPU instruction cycles.This memory space addresses 64 KB. Access to XDATA memory is also slower than DATA access, as the CODE and XDATA memory spaces share a common bus on the CPU core, and instruction
prefetch from CODE can thus not be performed in parallel with XDATA
accesses.
4.SFR. A read/write register memory space which can be directly accessed by a single CPU instruction.This memory space consists of 128 bytes. For SFR registers whose address is divisible by eight, each bit is also individually addressable.
在此处我们只需要记住 DATAXDATA 存在 SRAM 上,而 CODE存在 Flash上即可。

二、CC2530中的 Flash 结构
由于CC2530只支持64K寻址,因此,采用 Bank映射的方式寻址,其中,32K作为 ROOT,用于存放启动代码等,地址空间为 0x0000~0x7FFF;剩余32K用于映射不同的 Bank(0~7),地址为0x8000~0xFFFF.在查询某个 Bank 的数据或代码时,将该 Bank映射到地址空间 0x8000 ~ 0xFFFF即可。

通过ZigBee协议栈中的定义

#define HAL_FLASH_PAGE_SIZE       2048

我们可以知道每页page的大小为2K,定义每16个page为1个Bank,下图为Bank与page的关系

Bank地址:
Bank0: 0x00000 ~ 0x07FFFF
Bank1: 0x18000 ~ 0x1FFFFF
Bank2: 0x28000 ~ 0x2FFFFF
Bank3: 0x38000 ~ 0x3FFFFF
Bank4: 0x48000 ~ 0x4FFFFF
Bank5: 0x58000 ~ 0x5FFFFF
Bank6: 0x68000 ~ 0x6FFFFF
Bank7: 0x78000 ~ 0x7FFFFF

三、计算Bank的数据或代码的地址
在计算地址前,首先了解物理地址与逻辑地址的概念,及两者之间的转换公式。
1、物理地址与逻辑地址
物理地址:加载到内存地址寄存器中的地址,内存单元的真正地址。在前端总线上传输的内存地址都是物理内存地址,编号从0开始一直到可用物理内存的最高端。这些数字被北桥(Nortbridge chip)映射到实际的内存条上。物理地址是明确的、最终用在总线上的编号,不必转换,不必分页,也没有特权级检查(no translation, no paging, no privilege checks)。
  逻辑地址:CPU所生成的地址。逻辑地址是内部和编程使用的、并不唯一。例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址(偏移地址),不和绝对物理地址相干。
2、物理地址与逻辑地址的转换
(1)确定虚拟地址(物理地址)的有效位
  例如:假设页面大小1KB,共32页。(页面:逻辑地址 页框:物理地址)
  由32(KB)=32×1024(B) 即等于32×1024 字节
  二进制用多少位能有效表示这么多字节呢?
答案是:15位 因为32×102 4=2^5×2^10=2^15
(2)再次确定逻辑地址页面位数 你应该知道:逻辑地址=页号+页面
  还是以上假设,那么页面大小为1KB=1024字节 同样的方法计算出表示位数:10位
  如果给你逻辑地址:0000 1111 1000 0000
  那么由:011+11100000000(相当于 页号+页面(10位))推得出页号011=3
  (3)根据页号找出对应的页框号
  由 物理地址=页框号×页块大小(页块大小是等于页面大小的)+页内位移(即页面逻辑地址)//物理地址=块的大小(即页的大小L)*块号f+页内地址d
  根据上面 物理地址=页框号×1024B + 1110000000 ( 这里的相加是指位置上而言)
  例如:110+110=110110(即高地址+低地址)
有了以上的知识,我们来看一看CC2530的Flash的读写是怎样通过逻辑地址找到物理地址的

    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 ptr = (uint8 )(offset + HAL_FLASH_PAGE_MAP) +
               ((pg % HAL_FLASH_PAGE_PER_BANK) * HAL_FLASH_PAGE_SIZE);
        .............
    }
ptr为物理地址,offset为偏移量, pg为页数
#define HAL_FLASH_PAGE_MAP                         0x8000
#define HAL_FLASH_PAGE_PER_BANK            16
#define HAL_FLASH_PAGE_SIZE                          2048

  假如我们要读某一page中的数据,那么我们必须先把这个page所在的

bank映射到XDATA的0x8000~0xFFFF中,我们读取page值为100,偏移量为20的数据时,这个地址通过上面的表达式就很容易计算出来为20+0x8000+(100%16)2024 = 0x9FB4,注意这个地址转换成了(uint8 ),即为XDATA空间的地址。
pg /= HAL_FLASH_PAGE_PER_BANK;
计算page所在的bank,如果pg为100,则其所在bank值为100/16= 6
MEMCTR = (MEMCTR & 0xF8) | pg;
这句是将刚才计算所得的bank映射到XDATA的0x8000~0xFFFF中去,
MEMCTR的低三位为XDATA的bank选择位

四、其他地址
1、IEEE
-D_IEEE_ADDRESS_SPACE_START=(((_NR_OF_BANKS+1)*_FIRST_BANK_ADDR)-0x18)
-D_IEEE_ADDRESS_SPACE_END=(_IEEE_ADDRESS_SPACE_START+7)
-Z(CODE)IEEE_ADDRESS_SPACE=_IEEE_ADDRESS_SPACE_START-_IEEE_ADDRESS_SPACE_END
注:0x18 = 24 = 16 +8;
_IEEE_ADDRESS_SPACE_START容易算出来,_NR_OF_BANKS值为0x07,_FIRST_BANK_ADDR值为0x8000,这些值是在options...里面设置的。所以_IEEE_ADDRESS_SPACE_START的值为0x40000 - 0x18 = 0x3FFE8,_IEEE_ADDRESS_SPACE_END值就为0x3FFE8+7 = 0x3FFEF。
(备注:每2kb(1page)的flash有1bit的lock位)
2、NV
Z-STACK将flash的最末处的12KB(6page)用来作为Nv存储的,具体看:
-D_ZIGNV_ADDRESS_SPACE_START=(((_NR_OF_BANKS+1)*_FIRST_BANK_ADDR)-0x3800)
-D_ZIGNV_ADDRESS_SPACE_END=(_ZIGNV_ADDRESS_SPACE_START+0x2FFF)
-Z(CODE)ZIGNV_ADDRESS_SPACE=_ZIGNV_ADDRESS_SPACE_START-_ZIGNV_ADDRESS_SPACE_END

时间: 2024-10-30 22:10:25

CC2530之Flash笔记的相关文章

Flash笔记-Alpha通道遮罩的三个要素

笔记 好些日子没有玩flash了,今天拾起来作了几个练习,发现之前在吕聪贤网页上看到的alpha通道遮罩居然不会做,出错了N久,最后在帮助中找到了一句话,特此面壁思过一下. 在flash8版本之前,要想做朦胧效果的遮罩,就必须在遮罩块的上面同时做一个羽化或者渐变的元件,使之能够于遮罩块同步,这样效果差,而且麻烦. 现在flash8里可以完全不用搞第三个元件,就做出朦胧的遮罩效果,但是需要谨记三个因素: 1.遮罩与被遮罩元件都必须是影片剪辑(MovieClip).因为alpha通道的遮罩效果必须是

FLASH笔记:AS在计算方面的8个常见问题

笔记|问题 AS在计算方面会有小小的偏差,而这份偏差可能会导致很多问题.那么通常出现的问题有哪几种呢?这里我把本身遇到和其他以前看过的凑起来 第一种var a=(1/3); trace(a); // 输出 0.333333333333333 trace(a*3); // 输出 1 到这里为止的计算没有问题,那么接下来看看所出现的问题 var b=a.toString(); //把a转换为文字 var c=Number(b); //再把文字转换为数字 trace(c); // 输出 0.33333

Flash AS3学习笔记

笔记 首先 say hello 一下,在输出面板 trace 出 "Hello World!".复习一下AS2的类代码: class net.eidiot.learnAS3.HelloAs2{    public function HelloAs2(){        trace("Hello World!");    }} 为了让这段代码工作,需要在Flash IDE里场景的第一帧输入代码: import net.eidiot.learnAS3.HelloAs2;

Flash/Flex学习笔记(5):捕获摄像头(续)--在线抓屏并保存到客户端本地

必须有摄像头上面的演示才能正常播放. 思路 使用摄像头以及在线抓屏在上一节Flash/Flex学习笔记(2)捕获摄像头 里已经讲过了就不重复粘贴了至于在客户端保存文件Flash里用起来也很简单:直接调用 FileReference 即可另外为了减少图片大小还可能借助AS3.0的扩展库项目地址http://code.google.com/p/as3corelib/把bmp格式的位置转换成jpeg再保存   扩展 结合本文的方法再配合Flash/Flex学习笔记(4)如何打开网页及Get/Post数

Flash/Flex学习笔记(52):使用TweenLite

TweenLite是第三方出品的专用于各种缓动动画的类库,其性能据说已经超过了Adobe官方的Tween. 从网上找到了一篇中文的说明文档:http://files.cnblogs.com/yjmyzz/tweenLite%e4%b8%ad%e6%96%87%e6%89%8b%e5%86%8c%e4%b8%8e%e5%8f%82%e6%95%b0%e8%af%b4%e6%98%8e.pdf 这是官方的测试示例: AS3类库下载: http://files.cnblogs.com/yjmyzz/g

Flash/Flex学习笔记(37):不用系统组件(纯AS3)的视频播放器--只有8.82K

以前为了赶项目,利用系统组件制作过一款视频播放器(见Flash/Flex学习笔记(6):制作基于xml数据源的flv视频播放器),但是系统组件实在是太大了,最终生成的swf居然有103K,随着AS3的深入学习,昨天又弄了一个只用AS3的播放器,最终只有8.82K,呵呵,这肥减得那是相当厉害. 用到了上一篇(Flash/Flex学习笔记(35):自己动手实现一个滑块控件(JimmySilder))里自己写的的滑块控件,主要代码如下(关键是NetConnection与NetStream对象的使用):

Flash/Flex学习笔记(57):实用技巧

布朗运动: varnumDots:uint=50; varfriction:Number=0.9; vardots:Array; varlife:uint=0; functioninit(){ graphics.lineStyle(0,0xffffff,.5); dots=newArray(); for(vari:uint=0;i<numDots;i++){ vardot:Ball=newBall(2,0x00ff00); dot.x=Math.random()*stage.stageWidth

Flash/Flex学习笔记(46):正向运动学

所谓"正向运动学"通俗点讲就是把几个连接部件的一端固定起来,另一个端可以自由(向前/向外)运动.比如人的行走,单个下肢可以理解为脚连接小腿,小腿连接大腿,大腿连接腰.行走的过程,相当于二条腿相对固定于腰部,大腿运动驱动小腿,小腿又驱动脚,从而带动整个连接系统的一系列运动. 先来一个基本的关节类Segment:(就是一个圆角矩形+二个小圆圈) package { import flash.display.Sprite; import flash.geom.Point; public cl

Flash/Flex学习笔记(24):粒子效果

粒子爆炸: 仍然要用到以前的小球类,不过稍加改造 package { import flash.display.Sprite; //小球 类 public class Ball extends Sprite { public var radius:uint;//半径 public var color:uint;//颜色 public var vx:Number=0;//x轴速度 public var vy:Number=0;//y轴速度 public function Ball(r:Number