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的例程,地址是:
没有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已经实现并可以跑起来了,可以参考
二、接下来要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)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值