CC254x代码量小于128K的可以使用ImageA和ImageB互切的方案,这个是TI比较标准的方案,但是有两个缺点:一是代码量限制的太小了,仅例程编译下来都要110K了,给用户可以扩展的空间太小;二是两个Image要分成不同的版本,每次升级要关注版本号,比较麻烦,也不符合常规升级习惯。

对此TI又给出了CC2541的Large OAD方案,它把ImageA变成了只有BLE通讯的最小系统,用于无线对接升级ImageB,ImageA编译后只有96K,因此给用户留下150K的程序空间,这对于一般应用来讲还是差不多了,无线对接后每次只升级ImageB也就是用户程序,需要升级时在ImageB应用中写一个升级密码就会跳到ImageA中重新启动升级,这个比较符合常规升级习惯。

这两种方案不是本文要讲内容,可以百度一下,按照例程一步步来就可以实现了。
    本文要讲的是,然而TI比较坑的在于,只给了CC2541的Large OAD例程(http://processors.wiki.ti.com/index.php/BLE_Large_Image_OAD)
    但是没有CC2540的例程,所以要实现CC2540必须自己改例程。而因为CC2540的协议栈编译出来比CC2541要大几个KB导致程序放不下,所以如果直接把协议栈换掉,link的时候会出现以下错误:

Error[e104]: Failed to fit all segments into specified ranges. Problem discovered in segment BANKED_CODE. Unable to place 61 block(s)
(0x14ba9 byte(s) total) in 0x14638 byte(s) of memory. The problem occurred while processing the segment placement command
"-P(CODE)BANKED_CODE=_CODE_BEG-_CODE_END,_BANK5_BEG-_BANK5_END,_BANK6_BEG-_BANK6_END,_BANK7_BEG-_BANK7_END", where at the moment of
placement the available memory ranges were "CODE:2a24-3fff,CODE:5b7a4-5ffff,CODE:68000-6ffff,CODE:78000-7e7ff"
Error while running Linker

所以必须对代码进行裁剪。接下来详述怎样裁剪例程代码以实现CC2540的ImagA。

一、前提是CC2541的Large OAD已经实现并可以跑起来了,请参考香瓜的
http://blog.csdn.net/feilusia/article/details/52236140

二、接下来要Project->edit configurations,基于CC2541_OAD_ImgA新建一个CC2540_OAD_ImgA


三、工程上点右键,找到option打开工程选项,在C/C++ Complier标签的Preprocessor选项卡下的Defined symbols:下添加以下一行:
LIMIT_2540


在Extra options选项卡下修改配置文件名:
-f $PROJ_DIR$\buildConfig_2540.cfg


四、在工程的Lib组下右键Add上CC2540的协议栈,要注意的是这里要选用1.4.1协议栈,1.4.2的可能会出问题。然后在原来CC2541协议栈上点右键,勾选上从工程中排除的勾。


五、在电脑的工程所在目录中复制一下build_config.cfg文件,重命名为buildConfig_2540.cfg,打开将里面的-DCC2540改为-DCC2540


然后在IAR的工程下面TOOLS组中添加该文件,并将原文件右键从当前工程中排除。

六、修改代码,注意修改本工程内的文件,也就是APP组下的文件,不要修改库中涉及的其他文件:

1. SimpleBLEPeripheral_Main.c 文件

第一处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
// Initialize board I/O
InitBoard( OB_COLD );
#endif
说明:增加宏编译语句#if !(defined LIMIT_2540),裁剪掉InitBoard( OB_COLD );语句。可以搜索该语句然后添加宏编译语句。后面裁剪手段与此相同,不再解释。

第二处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
// Final board initialization
InitBoard( OB_READY );
#endif

2. peripheral_small.c 文件

第一处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static void gapRole_HandleParamUpdateNoSuccess( void );
#endif
第二处:

#if !(defined LIMIT_2540) //尽量压缩2540代码
case GAPROLE_IRK:
if ( len == KEYLEN )
{
......
break;
case GAPROLE_SRK:
if ( len == KEYLEN )
{
......
break;
case GAPROLE_SIGNCOUNTER:
......
break;
#endif
第三处:

#if !(defined LIMIT_2540) //尽量压缩2540代码
case GAPROLE_ADV_EVENT_TYPE:
......
case GAPROLE_ADV_DIRECT_TYPE:
......
case GAPROLE_ADV_DIRECT_ADDR:
if ( len == B_ADDR_LEN )
{
......
break;
case GAPROLE_ADV_CHANNEL_MAP:
if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= 0x07) )
{
......
break;
case GAPROLE_ADV_FILTER_POLICY:
if ( (len == sizeof ( uint8 )) && (*((uint8*)pValue) <= GAP_FILTER_POLICY_WHITE) )
......
break;
case GAPROLE_RSSI_READ_RATE:
......
break;
#endif

第四处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
case GAPROLE_PARAM_UPDATE_REQ:
{
uint8 req = *((uint8*)pValue);
if ( len == sizeof ( uint8 ) && (req == TRUE) )
{
......
break;
#endif

第五处:
if ( events & RSSI_READ_EVT )
{
#if !(defined LIMIT_2540) //尽量压缩2540代码
// Only get RSSI when in a connection
if ( gapRole_state == GAPROLE_CONNECTED )
{
// Ask for RSSI
VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle );

// Setup next event
if ( gapRole_RSSIReadRate )
{
VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
}
}
#endif

第六处:
if ( events & CONN_PARAM_TIMEOUT_EVT )
{
#if !(defined LIMIT_2540) //尽量压缩2540代码
// Unsuccessful in updating connection parameters
gapRole_HandleParamUpdateNoSuccess();
#endif

第七处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static void gapRole_HandleParamUpdateNoSuccess( void )
{
......
}
#endif

3. simpleBLEPeripheral.c 文件

第一处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static uint8 simpleBLEPeripheral_TaskID; // Task ID for internal task/event processing
#endif

第二处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg );
static void performPeriodicTask( void );
#endif

第三处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
simpleBLEPeripheral_TaskID = task_id;
#endif

第四处:
将原程序启动OSAL的代码修改成以下内容:
#if !(defined LIMIT_2540) //尽量压缩2540代码
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
#else //直接启动
// Start the Device
VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
#endif

第五处:
注释掉函数内容:
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
#if !(defined LIMIT_2540) //尽量压缩2540代码
VOID task_id; // OSAL required parameter that isn't used in this function
......
#endif //LIMIT_2540
// Discard unknown events
return 0;
}

第六处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
......
}
#endif

第七处:
static void peripheralStateNotificationCB( gaprole_States_t newState )
{
#if !(defined LIMIT_2540) //尽量压缩2540代码
switch ( newState )
{
......
}
}
#endif
gapProfileState = newState;
......

第八处:
#if !(defined LIMIT_2540) //尽量压缩2540代码
static void performPeriodicTask( void )
{
......
}
#endif

七、修改完成后编译代码,即可生成裁剪版的CC2540的ImagA程序,大小:

95 963 bytes of CODE memory (+ 293 range fill )
50 bytes of DATA memory (+ 75 absolute )
5 590 bytes of XDATA memory
178 bytes of IDATA memory
8 bits of BIT memory
4 000 bytes of CONST memory
Errors: none
Warnings: none

八、对应的Large B文件也按前面步骤一至五完成即可,不需要第六步添加裁剪的代码。使用BLE Device Monitor即可完成升级(on-chip OAD)。

CC2540 Large OAD实现程序无线升级相关推荐

  1. 【BLE】CC2541之Large OAD

    本篇博文最后修改时间:2017年05月19日,03:33. 一.简介 本篇以SimpleBLEPeripheral工程为例,介绍如何进行Large OAD升级. 二.实验平台 协议栈版本:BLE-CC ...

  2. 实现NRF52832蓝牙DFU无线升级

    实现NRF52832蓝牙DFU无线升级 需要使用到的工具 选用相关工程 工具安装 BootLoader固件生成及DFU升级操作 需要使用到的工具 nrfutil(生成私有秘钥) make工具(Wind ...

  3. 安信可PB-01/02蓝牙模组实现远程OTA无线升级功能介绍,剖析整个实现原理和代码介绍。

    文章目录 一.安信可PB-01/02蓝牙模组 OTA简介 二.安信可PB-01/02蓝牙模组 FOTA实现流程 三.通过手机APP 完成安信可PB-01/02蓝牙模组的OTA演示 联系我们 一.安信可 ...

  4. ASP网站程序自动升级实现的方法

    现在流行虚拟主机建站,我也有个网站,也算是个站长咯.当了近一年的站长,感到网站程序每次升级的时候颇为麻烦:先去官方看公告,然后下载升级包到本地,解压,FTP上传到虚拟主机.这些都是累人的体力活,加之本 ...

  5. ARM-Linux应用程序自动升级以及自动回滚的实现

    1. 研究背景 现今,许多基于arm-linux平台开发的应用程序开发都具备了物理的网卡这样的外围设备,这也是为通过网络升级应用程序提供了诸多便利,网络的便捷,快速,稳定等诸多特点.今天,我们约定应用 ...

  6. 使用T卡无线升级的方法

    离线更新的文件:config_extra.h中 #define UPD_FILENAME "fw5000.upd" func_update.c中,更新的函数,所以我们需要将升级的文 ...

  7. 基于串口通信的DSP应用程序在线升级方法

    摘  要:为解决特殊场合DSP程序升级困难的问题,以TMS320F28035为例,介绍了一种基于串口通信的适合于TMS320C2000系列DSP实现程序更新的在线升级方法.描述了该在线升级方法的基本思 ...

  8. 苹果交付iOS 6系统 可无线升级

    北京时间9月20日凌晨消息,苹果周三开始向iPod.iPhone和iPad交付iOS 6操作系统,符合此前预期. 用户可启动iTunes软件来进行更新,iOS 5用户还可在设置菜单中进行无线升级.苹果 ...

  9. 现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现

    现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现 闲来无事,总结一下前段时间做过的U盘升级项目.一个新手的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作 ...

最新文章

  1. java url 拦截_Spring mvc设置某些url不被interceptor拦截器拦截的方法
  2. c2064 项不会计算为接受0个参数的函数_【JS必知必会】高阶函数详解与实战
  3. CentOS 6.4下安装中文输入法
  4. boost::range模块strided相关的测试程序
  5. python基本程序结构有几种_python基础梳理(一)(推荐)
  6. LeetCode 900. RLE 迭代器(模拟/二分查找)
  7. 2013.3.9学习日记
  8. 大一计算机考试题库知识点,大一 计算机基础 期末考试题库
  9. (59)Verilog HDL测试激励:时钟激励1
  10. 关于使用runtimeStyle属性问题讨论
  11. UnityShader9:光照基础回顾
  12. [转]日常交际技巧经验总结100句
  13. Android 文件系统路径
  14. Netty源码分析第1章(Netty启动流程)----第3节: 服务端channel初始化
  15. 复制pdf里的文字,去掉多余换行符的最简单方法(不用word不用python)
  16. 翻翻git之---实用工具类Lazy(绝对的好东西,走过路过别错过)
  17. jasper ireport
  18. android手机管理器在哪里打开,小米手机任务管理器在哪?怎么打开?
  19. workman php 视频,利用workerman实现webrtc实时音视频通话
  20. 全网首发游戏陪玩系统 语音聊天系统11月商业版源码 附教程

热门文章

  1. elasticsearch算法之推荐系统的相似度算法(一)
  2. 基于深度学习的轴承故障识别-构建基础的CNN模型
  3. bugku 奇怪的密码
  4. HAProxy快速入门(七)—— 常见负载均衡策略
  5. 一份完整的ACSII码表
  6. typora中实心圆和空心圆
  7. 云知梦php资源下载,云知梦php全站工程师含有每节课源码及php手册
  8. Function中的apply函数的应用
  9. 3分钟火速手写一个二叉查找树,搞快点。
  10. 阿里、中兴、中国联通打造物联网区块链框架