CC2640 片外OAD 内部FLASH结构与OAD过程

1 内部FLASH内存地址定义图

CC2640 片外OAD 内部FLASH结构与OAD过程_第1张图片

 

 

 

 

 

片外OAD同时拥有片上flash memory和片外flash memory device。

 

内部FLASH包含如下组件

1 interrupt vectors(0x00000-0x01000) 共1页

2 application(0x01000 - 0x0f000) 共14页 最多56Kb

3 stack (0x0f000 - 0x1d000) 共14页 最多56KB

4 NV Storage Area(0x1d000-0x1f000)共2页,最多8KB

5 BIM+CCFG(0x1f000 - 0x1ffff)共1页,最多4KB

 

各个组件的作用和特点

1 interrupt vectors:存放中断向量,例如重要的重启中断向量

 

笔者认为系统复位之后,想要执行bootloader,就必须把reset vectors指向bootloader入口,其他的中断向量表与reset一样,只不过指向了其他程序段。笔者认为,interrupt vectors是函数指针,指向函数入口。

 

2 application:存放APP代码

 

CC2640严格区分了APP和蓝牙STACK,蓝牙STACK运行在M0核心上,APP运行在M3核心,用户仅需编程APP,不需要编程STACK。

APP与STACK有一个边界,这个边界叫做BAUNDARY TOOL。此工具可以自动帮你划分边界,根据你的APP大小。参考《SWRU393_CC2640_BLE_Software_Developer's_Guide page39》。

笔者认为BAUNDARY TOOL太灵活了,不适合严谨的OAD升级过程,于是取消了这个自动工具,改为手动设置边界 为0X0F0000,这样实际观察生成的STACK,发现仅用到了(0XF000-0X1CAD0)代码段,还空余出了一部分空间。

 

3 STACK:存放协议栈代码

 

笔者手动设置边界,0x0f000-0x1d000,实际发现生成的STACK文件占用了(0XF000-0X1CAD0)刚好在预先配置的flash段之间,可见TI工程师的先见之明,0x1d000这个值不是随意写出来的。STACK是用户不用改变的代码段,不用动他,OAD升级也不会升级他。

 

4 NV Storage Area(0x1d000-0x1f000)

 

笔者认为此段FLASH是给用户用来存放关键信息的段,默认是2页。

参考《SWRU393_CC2640_BLE_Software_Developer's_Guide page35》

 

笔者要构建的应用不需要那么大的空间来存放我的信息,所以配置成1页即可。

于是增加预定义 OSAL_SNV=1

CC2640 片外OAD 内部FLASH结构与OAD过程_第2张图片

 

5 BIM和CCFG(0x1f000 - 0x1ffff)

5.1 BIM

BIM是独立于APP工程的新工程,会产生一个独立的代码段,这个代码段先于APP执行。

也就是说,程序最开始会执行BIM,也就是BOOTLOAD,此时需要保证一些基本的外设是可以运行的,例如硬件SPI,但是不必运行RTOS系统,因为要保证BIM的代码size小,以此来节约FLASH。

 

BIM运行之后,会检查外部FLASH(通过SPI通讯)里的数据内容,判断是否有更新请求,其实说白了查一个标志位是否是1等等。如果发现有升级请求,那么就从外部FLASH搬运数据到内部FLASH,搬运结束之后,跳转到APP程序继续运行。

 

至于远程主机通过蓝牙发送升级数据包给到CC2640因为需要协议栈支持,所以这一个步骤是运行在APP代码里的,必须在APP中建立一个OAD_TASK,用来侦听远程主机的程序升级请求。

 

于是,OAD的升级过程应该是这样的

 

在APP代码中通过蓝牙得到升级数据包--> 存放到外部FLASH中,并且置位需要更新标志位-->调用系统重启函数,重启系统-->系统进入bim,检查更新标志位-->发现更新标志位,检查外部flash里的升级包是否损坏,用传统CRC校验法(分段CRC,分段校验)-->搬运数据,从外部搬运到内部-->跳转到APP程序,升级结束。

 

这里分享写入内部FLASH的方法和过程

 

FlashProtectionSet(addr_offset,FLASH_NO_PROTECT);//解锁扇区

FlashSectorErase(addr_offset); //擦除扇区

status = FlashProgram(page_buf,addr_offset,4096);

 

注释1 addr_offset 是页地址,只支持0x1000 0x2000这样对齐的页地址

注释2 page_buf 是需要写入FLASH的数据,长度必须是4096

注释3 写入flash的过程就是与0 AND的过程 也就是 0->0 1->0 没有能力 0->1 所以,必须先erase,再写。

注释4 status 需要判断 返回0说明写入成功。

 

BIM要尽可能的大

这里笔者配置为8K的大小,方法很简单,缩小SNV的大小,把BIM的起始地址从0x1f000移到0x1E00,于是SNV的FLASH区间缩小到了(0x1d000-0x1e000)。

因为CRC算法等等代码段,使得BIM变大了,4K容纳不下所有代码,所以放大BIM。

 

5.2 CCFG(占用最后的86byte)

存放用户配置数据,也就是类似SNV的功能。

这个暂时不考虑了,在配置BIM的时候,预留86BYTE 给到CCFG。

也就是BIM的实际可用范围是(0x1e000 - 0x1ffa9)

 

于是笔者工程的FLASH内存分配为

CC2640 片外OAD 内部FLASH结构与OAD过程_第3张图片

你可能感兴趣的:(CC2640 片外OAD 内部FLASH结构与OAD过程)