前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CC1310空中升级笔记04 WSN OAD Example

CC1310空中升级笔记04 WSN OAD Example

作者头像
twowinter
发布2020-04-17 14:41:31
6360
发布2020-04-17 14:41:31
举报
文章被收录于专栏:twowintertwowinter

1. 前言

关于CC1310的空中升级,让我折腾了特别久,我几乎绝望了。仅有的两个参考资料都遇到了困难: 1.CC2640 OAD,其中的BIM部分,TI只提供了IAR的版本,这导致关键性的存储映射无从参考,缺少了最关键的资料。 2.CC1350 BLE OAD Project 0,只有一个开发文档。

但是,身负物联网世界振兴重任的我又怎么能说不行呢!IoT小能手的字典中从来就没有‘不行’这两个字,因为我连字典都没有。

你看,山重水复疑无路,柳暗花明又一村。TI给了我一个CC1310的内部例程WSN OAD Example。别问我怎么得到的。

本文作者twowinter,转载请注明作者:http://blog.csdn.net/iotisan/

2. 例程研究

这个工程包含了 rfWsnConcentratorOadServer_CC1350_LAUNCHXL_TI_CC1350F128 和 rfWsnNodeOadClient_CC1310_LAUNCHXL_TI_CC1310F128 projects,以及用来将hex转化成OAD bin,下载镜像的脚本。 例程中,集中器存储节点的OAD镜像,通过OAD方式发送给子节点,子节点将镜像存储到外部flash中,子节点BIM程序把固件拷贝到内部flash,之后运行新程序。

2.1 产生要求的二进制镜像

需要如下工具: - CCSv7 - simplelink_cc13x0_sdk_1_00_00_13 - Python 2.7 - Python intelhex-2.1 - Python crcmod-1.7

只有rfWsnNodeOadClient_CC1310_LAUNCHXL_TI_CC1310F128需要BIM。

2.2 如何使用OAD例程

为了第一次使用时正常工作,集中器和子节点的外部flash需要清空。给两个LP boards烧写bin和CC1350LaunchPad_ExtFlashErase.hex。当擦写时LED会闪烁,烧写完成时LED就停止闪烁。除非外部flash擦除,LED停止闪烁。

集中器的OAD Server和子节点的固件通过SmartRF Flash Programmer来下载。

集中器将在串口显示如下信息: *Available FW: None

代码语言:javascript
复制
Nodes   FwVer   SW   RSSI

0xfe    0850    0    -025

Press BTN-2 to update available node FW

The "Available FW", or node selection is indicated by the '*'

子节点要用的OAD镜像可以使用oad_wrtie_bin.py 通过集中器的串口写入到外部flash。可用固件必须先按BTN-1来选中。

当”Available FW”被选中,BTN-2按下,则终端会显示:

代码语言:javascript
复制
Waiting for Node FW update...

串口terminal立即关掉,然后运行脚本将bin写入。 升级完后,绿色LED会闪烁,之后就可以重新打开串口terminal。

现在使用BTN-1来选择节点,显示屏会显示节点来运行的程序: Available FW: rfWsnNode v02.00.00

代码语言:javascript
复制
Nodes   Value   SW   RSSI

*0x7d    0850    0    -027

FW: rfWsnNode v01.00.00

Press BTN-2 to OAD node FW 

如果新上电一个节点,过几秒会显示出它的固件版本。

当选中节点后再按下BTN-2,则会开始向那个节点下发OAD。当节点接下来发送一个传感器读取,OAD就会启动,可以按下它自身的 BTN-1 来唤醒节点(它可能进入了50s的慢速上报)。节点固件会显示总包数和当前升级的包数:

代码语言:javascript
复制
 Available FW: rfWsnNode v02.00.00

Nodes   Value   SW   RSSI

*0x7d    0850    0    -028

FW: Block 03f6/0ed8

Press BTN-2 to OAD node FW

一旦OAD完成,节点会自动重启。 集中器会显示一个新的节点,该新节点会显示更新的固件版本。

2.3 编译一个OAD固件

  1. Update the nodeFwVersion string in NodeTask.c
  2. Exclude the ccfg.c file from the project.
  3. Enable hex file conversion in Project->Properties Arm Hex Utility
  4. Set memory width to 8 in General options
  5. Set outut format to intel hex.
  6. build
  7. copy hex from the projects Debug dir to the bin folder
  8. convert to OAD bin:

python tools/oad_image_tool.py -v 0x[version] -i remoteapp bin/rfWsnNodeOadClient_CC1310_LAUNCHXL_tirtos_ccs.hex -ob bin/rfWsnNodeOadClient_CC1310_LAUNCHXL_TI_CC1310F128_app-[version].bin -m 0x1000

3. OAD 源码解析

3.1 关于OAD的空中交互部分

空中交互大致有6条,源码最主要体现在 \source\common\wsnprotocol.h 底下

代码语言:javascript
复制
WSNProtocol_sendFwVersionReq
WSNProtocol_sendFwVersionRsp
WSNProtocol_sendImgIdentifyReq
WSNProtocol_sendOadIdentifyImgRsp
WSNProtocol_sendOadImgBlockReq
WSNProtocol_sendOadImgBlockRsp

整体OAD的交互流程梳理如下:

Concentrator — fwVersionReq –> Node Concentrator <– fwVersionRsp — Node Concentrator — oadImgIdentifyReq –> Node Concentrator <– oadImgIdentifyRsp — Node Concentrator <– oadBlockReq — Node Concentrator — oadBlockRsp –> Node

3.2 关于镜像下载部分

空中交互之后就到了镜像下载部分,也是特别关键的一部分,每次下载16字节。每次在oadBlockRspCb()中收到镜像分包,然后进行写入,边下载边写入FLASH。下载完镜像之后,再做下CRC校验:

代码语言:javascript
复制
/*********************************************************************
 * @fn      OAD_imgBlockWrite
 *
 * @brief   Process the Image Block Write.
 *
 * @param   pValue - pointer to data to be written
 *
 * @return  none
 */
void OAD_imgBlockWrite(uint8_t *pValue)
{
  // N.B. This must be left volatile.
  volatile uint16_t blkNum = BUILD_UINT16(pValue[0], pValue[1]);

  // Check that this is the expected block number.
  if (oadBlkNum == blkNum)
  {
    // Calculate address to write as (start of OAD range) + (offset into range)
    uint32_t addr = imageAddress + (oadBlkNum * OAD_BLOCK_SIZE);

    // If address starts a new page, erase that page first.
    if ((addr % flashPageSize) == 0)
    {
      OADTarget_eraseFlash(addr / flashPageSize);
    }

    // Write a 16 byte block to Flash.
    OADTarget_writeFlash(imagePage, (blkNum * OAD_BLOCK_SIZE), pValue+2,
                         OAD_BLOCK_SIZE);

    // Increment received block count.
    oadBlkNum++;
  }
  else
  {
    // Overflow, abort OAD
    oadBlkNum = 0;
#ifndef FEATURE_OAD_ONCHIP
    flagRecord = 0;
#endif
    // Close the target device
    OADTarget_close();

    // Send status
    OAD_sendStatusCb(OAD_BUFFER_OFL);

    return;
  }

  // Check if the OAD Image is complete.
  if (oadBlkNum == oadBlkTot)
  {
#if FEATURE_OAD_ONCHIP
    // Handle CRC verification in BIM.
    OADTarget_systemReset();
#else // !FEATURE_OAD_ONCHIP
    // Run CRC check on new image.
    if (checkDL())
    {
      // Store the flag of the downloaded image.
      flagRecord |= getImageFlag();

      // Store the image information.
      saveImageInfo();

      // Indicate a successful download and CRC
      OAD_sendStatusCb(OAD_SUCCESS);
    }
    else
    {
      // CRC error
      OAD_sendStatusCb(OAD_CRC_ERR);
    }
    flagRecord = 0;
#endif //FEATURE_OAD_ONCHIP

    OADTarget_close();
    oadBlkNum = 0;
  }
  else
  {
    // Request the next OAD Image block.
    OAD_getNextBlockReqCb(oadBlkNum);
  }
}

4. End


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. 例程研究
    • 2.1 产生要求的二进制镜像
      • 2.2 如何使用OAD例程
        • 2.3 编译一个OAD固件
        • 3. OAD 源码解析
          • 3.1 关于OAD的空中交互部分
            • 3.2 关于镜像下载部分
            • 4. End
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档