CC2540 Large OAD实现程序无线升级
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实现程序无线升级相关推荐
- 【BLE】CC2541之Large OAD
本篇博文最后修改时间:2017年05月19日,03:33. 一.简介 本篇以SimpleBLEPeripheral工程为例,介绍如何进行Large OAD升级. 二.实验平台 协议栈版本:BLE-CC ...
- 实现NRF52832蓝牙DFU无线升级
实现NRF52832蓝牙DFU无线升级 需要使用到的工具 选用相关工程 工具安装 BootLoader固件生成及DFU升级操作 需要使用到的工具 nrfutil(生成私有秘钥) make工具(Wind ...
- 安信可PB-01/02蓝牙模组实现远程OTA无线升级功能介绍,剖析整个实现原理和代码介绍。
文章目录 一.安信可PB-01/02蓝牙模组 OTA简介 二.安信可PB-01/02蓝牙模组 FOTA实现流程 三.通过手机APP 完成安信可PB-01/02蓝牙模组的OTA演示 联系我们 一.安信可 ...
- ASP网站程序自动升级实现的方法
现在流行虚拟主机建站,我也有个网站,也算是个站长咯.当了近一年的站长,感到网站程序每次升级的时候颇为麻烦:先去官方看公告,然后下载升级包到本地,解压,FTP上传到虚拟主机.这些都是累人的体力活,加之本 ...
- ARM-Linux应用程序自动升级以及自动回滚的实现
1. 研究背景 现今,许多基于arm-linux平台开发的应用程序开发都具备了物理的网卡这样的外围设备,这也是为通过网络升级应用程序提供了诸多便利,网络的便捷,快速,稳定等诸多特点.今天,我们约定应用 ...
- 使用T卡无线升级的方法
离线更新的文件:config_extra.h中 #define UPD_FILENAME "fw5000.upd" func_update.c中,更新的函数,所以我们需要将升级的文 ...
- 基于串口通信的DSP应用程序在线升级方法
摘 要:为解决特殊场合DSP程序升级困难的问题,以TMS320F28035为例,介绍了一种基于串口通信的适合于TMS320C2000系列DSP实现程序更新的在线升级方法.描述了该在线升级方法的基本思 ...
- 苹果交付iOS 6系统 可无线升级
北京时间9月20日凌晨消息,苹果周三开始向iPod.iPhone和iPad交付iOS 6操作系统,符合此前预期. 用户可启动iTunes软件来进行更新,iOS 5用户还可在设置菜单中进行无线升级.苹果 ...
- 现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现
现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现 闲来无事,总结一下前段时间做过的U盘升级项目.一个新手的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作 ...
最新文章
- java url 拦截_Spring mvc设置某些url不被interceptor拦截器拦截的方法
- c2064 项不会计算为接受0个参数的函数_【JS必知必会】高阶函数详解与实战
- CentOS 6.4下安装中文输入法
- boost::range模块strided相关的测试程序
- python基本程序结构有几种_python基础梳理(一)(推荐)
- LeetCode 900. RLE 迭代器(模拟/二分查找)
- 2013.3.9学习日记
- 大一计算机考试题库知识点,大一 计算机基础 期末考试题库
- (59)Verilog HDL测试激励:时钟激励1
- 关于使用runtimeStyle属性问题讨论
- UnityShader9:光照基础回顾
- [转]日常交际技巧经验总结100句
- Android 文件系统路径
- Netty源码分析第1章(Netty启动流程)----第3节: 服务端channel初始化
- 复制pdf里的文字,去掉多余换行符的最简单方法(不用word不用python)
- 翻翻git之---实用工具类Lazy(绝对的好东西,走过路过别错过)
- jasper ireport
- android手机管理器在哪里打开,小米手机任务管理器在哪?怎么打开?
- workman php 视频,利用workerman实现webrtc实时音视频通话
- 全网首发游戏陪玩系统 语音聊天系统11月商业版源码 附教程