简谈 BlueNRG-LP 和-LPS 的代码空间优化

news2025/1/16 16:18:12

1.引言

客户在使用 BlueNRG-LP/LPS 芯片时,增加 OTA 服务后常常反馈说,编译代码区域超空间了,需要帮忙优化一下。后文主要通过下列步骤进行分析和优化 BlueNRG-LP/LPS 的代码空间:

  1. a. 通过分析 BlueNRG-LP/LPS 的 OTA 方式,让客户可以选择合适的方式;
  2. b. 通过整体分析 BlueNRG-LP/LPS 的链接文件(.icf/.sct/*.ld)了解默认工程的存储分布;
  3. c. 通过裁剪协议栈,选择合适的协议栈功能,优化 BlueNRG-LP/LPS 的代码空间;
  4. d. 通过使用静态协议栈,进一步优化 BlueNRG-LP/LPS 的代码空间;
  5. e. 其他方案;

总的来说通过两个维度来节省空间:

一个是协议栈的裁剪维度:主要是通过修改宏配置实现编译对应应用需要的协议栈。

另一个是 OTA 和静态协议栈的维度:OTA 和静态协议栈的选择流程图如下图所示。
在这里插入图片描述

2.BlueNRG-LP/BlueNRG-LPS 的 OTA

2.1 OTA 的框架

手机或者电脑做 GATT Client,给带 OTA 服务的设备升级。
在这里插入图片描述

2.2 官方提供的 OTA 方式

默认提供的 OTA 应用和协议栈编译在一个固件上。

  1. a. 不带备份的(右图中的右半部分)
    升级服务程序在 Boot 端(OTA Service manager)。
    省空间(存放了 2 份协议栈,1 份应用)
    管理简单(只需管理一份应用)

  2. b. 带备份的(右图中的左半部分)
    升级服务程序在应用端
    更消耗空间(存放了 2 份协议栈,2 份应用)
    管理稍微麻烦(需要管理两份应用,Lower 区域应用
    不能放置 Higher 区域运行)
    更安全

  3. a. 不带备份的方式由以下组件构成:
    BLE_OTA_ServiceManager+ application

  4. b. 带备份的由以下组件构成:
    BLE_OTA_ResetManager +Lower Application (with BLE OTA service) or
    BLE_OTA_ResetManager + Higher Application (with BLE OTA service)

对应在 SDK 中工程和配置如下图所示:
a. BLE_OTA_ServiceManager 配合 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager
b. BLE_OTA_ResetManger 配合 BLE_SerialPort 中的 Service_LowerApp_OTA 或者Service_LowerApp_OTA 使用
在这里插入图片描述
在这里插入图片描述

2.3 使用带备份类型 OTA 升级错误变砖头问题

编译器编译的 Higher Application 如果放置在 Lower Application 的位置,程序无法运行。

APP 程序可以知晓当前运行的固件是 Lower 还是 Higher APP。可以在编译固件 Higher Application 和 Lower Application 中加入一些标记,用于给升级工具识别,当前需要下载的是Higher Application 还是 Lower Application 或者是否混用。建议每次发布时两个应用程序都编译生成,不要人为来管理固件,否则容易造成混乱,应该让升级 app 自动选择对应的来升级。
在这里插入图片描述

3.BlueNRG-LP/LPS 的存储分析

3.1 linker 中宏定义作用范围

Linker 中可定义一些宏、用于指定链接脚本文件所需的配置。这些宏定义不作用于.c文件或者.h文件,只作用于链接文件(.icf 或者.sct 或者 *.ld)。

3.2 链接脚本文件分析(代码区域)

不同的 IDE 所使用的链接脚本文件的格式不同。比如,Keil 使用“.sct”文件,IAR 使用“.icf”文件,而 TrueStudio 使用 “*.ld”文件。

下面分析BlueNRG-LP最新SDK中BLE_SerialPort项目IAR工程目录下的BlueNRG_LP.icf文件, 其他IDE一样,可以进行类比。由于Flash的擦除必须是整页操作的,写Flash之前必须将对应的页擦除,所以Flash的划分需要2KB对齐。就算只使用到0.9KB,也需要划分2KB区域。

默认SDK中提供了4种程序的链接配置:

  1. CONFIG_OTA_HIGHER
  2. CONFIG_OTA_LOWER
  3. .CONFIG_OTA_USE_SERVICE_MANAGER
  4. 其他
    在这里插入图片描述
    对于这四种链接配置编译后,代码区域放置在如下地址。BLE_OTA_ServiceManager 工程使用的是非 OTA 程序,而 BLE_SerialPort 中的 Sever_Use_OTA_serviceManager 工程使用的是CONFIG_OTA_USE_SERVICE_MANAGER。
    在这里插入图片描述
    上述4种程序的链接配置由以下宏定义来指定:

MEMORY_FLASH_APP_SIZE: 定义程序使用Flash的大小。以工程BLE_OTA_ServiceManager为例子,在linker中定义了MEMORY_FLASH_APP_SIZE = 0x3000, 则表明LE_OTA_ServiceManager的大小不能超过0x3000(12*1024) 字节。

BLE_OTA_ServiceManager是一个带OTA服务的启动程序,宏定义MEMORY_FLASH_APP_SIZE限制这个工程编译的程序空间大小不能超过这个范围。

如果在linker中没有定义MEMORY_FLASH_APP_SIZE,则对应的4种配置分别是:

• CONFIG_OTA_HIGHER ---> (((_MEMORY_FLASH_SIZE_ - RESET_MANAGER_SIZE -
FLASH_NVM_DATASIZE)/2)/2048)*2048
• CONFIG_OTA_LOWER ---> (((_MEMORY_FLASH_SIZE_ - RESET_MANAGER_SIZE -
FLASH_NVM_DATASIZE)/2)/2048)*2048
• CONFIG_OTA_USE_SERVICE_MANAGER ---> (_MEMORY_FLASH_SIZE_ -
SERVICE_MANAGER_SIZE - FLASH_NVM_DATASIZE)
• 其他 ---> (_MEMORY_FLASH_SIZE_ - FLASH_NVM_DATASIZE -

MEMORY_FLASH_APP_OFFSET)
MEMORY_FLASH_APP_OFFSET: 定义程序编译链接地址的偏移(非OTA程序)。

如果在linker中没有定义MEMORY_FLASH_APP_OFFSET,则对应的4种配置分别是:

• CONFIG_OTA_HIGHER ---> (RESET_MANAGER_SIZE + MEMORY_FLASH_APP_SIZE)
• CONFIG_OTA_LOWER ---> (RESET_MANAGER_SIZE)
• CONFIG_OTA_USE_SERVICE_MANAGER ---> (SERVICE_MANAGER_SIZE)
• 其他 ---> MEMORY_FLASH_APP_OFFSET (0)

前面提到默认SDK中提供了4种程序的链接配置,本质上只是计算MEMORY_FLASH_APP_OFFSET和MEMORY_FLASH_APP_SIZE的方式不同而已,如果应用需要,也可以改动这个链接脚本文件。

4.通过协议栈的初步裁剪与自定义优化空间

SDK 中默认提供了 4 种默认配置的协议栈加一种自定义的协议栈配置(BLE_STACK_CUSTOM_CONF),如下图所示。
在这里插入图片描述
上述 5 种不同协议栈的配置,本质上就是通过使用宏控制不同的特性功能是否打开。只是前面 4种提供了默认便捷的设置,而最后一种可以进行细粒度更细的自定义的协议栈。

可以在 Preprocesor Symbols 中定义相关的宏来配置使用哪种协议栈配置。
在这里插入图片描述
如果选用细粒度更细的 BLE_STACK_CUSTOM_CONF 协议栈配置,则在 其中在头文件“custom_ble_stack_config.h”中开关不同功能特性,大致占用的代码如下图所示。
在这里插入图片描述

5.协议栈的进一步裁剪:使用静态协议栈

5.1 静态协议栈工程的 4 种默认的配置

ST 官方 SDK 中已经提供了静态协议栈的 Demo,分为协议栈工程和应用工程两部分,路径
为:
C:\Users\user name\ST\BlueNRG-LP DK 1.x.x\Projects\BLE_Examples\BLE_StaticStack
静态协议栈工程默认提供了 4 种配置:

  • • Release
  • • Basic
  • • OTA_BTL_ResetManager
  • • OTA_BTL_ResetManager_Basic
    C:\Users\user name\ST\BlueNRG-LP DK 1.x.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack
  • • Release
  • • LowerApp_OTA
  • • HigherApp_OTA
    在这里插入图片描述
    那它们有什么区别呢?它们可以分为两组。

Release 和 Basic 是一组: 它们运行时都是由协议栈程序直接跳转到一个固定的应用上;

Release 和 Basic 的区别: Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而 Release的协议栈配置是 BLE_STACK_FULL_CONF。

不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。

  • • 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
  • • 占用的 Flash 空间可以通过编译的 Map 文件查看
  • • 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
  • • Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
  • OTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 是另外一组:它们都是由协议栈程序跳转到 Lower 应用程序或者 Higher 应用程序;
  • • OTA_BTL_ResetManager 和 OTA_BTL_ResetManager_Basic 的区别:
    OTA_BTL_ResetManager_Basic 的协议栈配置是 BLE_STACK_BASIC_CONF, 而
    OTA_BTL_ResetManager 的协议栈配置是 BLE_STACK_FULL_CONF
  • • 不同的协议栈配置,包含的功能和占用的 Flash 空间也不一致。
    o 不同的协议栈配置包含的功能请查看 stack_user_cfg.h
    o 占用的 Flash 空间可以通过编译的 Map 文件查看
    o 宏 RESET_MANAGER_SIZE 用于协议栈程序的跳转偏移,即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。
    o Linker 中宏 MEMORY_FLASH_APP_SIZE 用于定义程序可用的大小。即预留多少空间给协议栈,因此这个宏的大小也会因为协议栈占用的空间不同而不同。

其中,一个工程负责生成协议栈,另一个工程负责应用,那么这里 BLE_StaticStack 中的Release or Basic 与 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic 怎么和Release,LowerApp_OTA 和 HigherApp_OTA 组合呢?

  • • BLE_StaticStack 中的 Release or Basic + BLE_SensorDemo_StaticStack 中的Release //不带备份 OTA 的使用固定协议栈的方
  • • BLE_StaticStack 中的 OTA_BTL_ResetManager or OTA_BTL_ResetManager_Basic + BLE_SensorDemo_StaticStack 中的 LowerApp_OTA or HigherApp_OTA //带备份OTA 的使用固定协议栈的方法

5.2 将工程实例化为静态协议栈工程

将工程实例化为静态协议栈涉及比较多的步骤,可以参考官方的文档 :
BlueNRG-LP_LPS DK 1.2.0\Projects\BLE_Examples\BLE_SensorDemo_StaticStack\README.txt

以及 SDK 安装目录的 index.html 中的静态协议栈的介绍如下图所示。
在这里插入图片描述
如果在实例化 OTA 程序时,可能需要修改链接脚本和 Preprocesor Symbols 中下面几个宏(具体不同应用,不同 OTA 类型,具体需要定义的宏和宏的数值也不同):
RESET_MANAGER_SIZE
SERVICE_MANAGER_OFFSET
SERVICE_MANAGER_SIZE
MEMORY_FLASH_APP_SIZE
MEMORY_RAM_APP_OFFSET

5.3 使用默认配置的协议栈

如果使用了 OTA,发现空间不够,可以考虑将应用协议栈和 OTA 协议栈合并使用如下图所示。
在这里插入图片描述
OTA 在应用程序服务中(带备份)---------------------OTA 功能和 boot 单独一个程序(不带备份)

上图列举的是基于 BlueNRG-LP 的默认提供的工程的大致数值(BlueNRG-LPS 类似,这里不再举例)。如果遇到不同的应用,可以实际裁剪协议栈适配不同的应用需求。

5.4 使用自定义配置的协议栈

使用静态协议栈可以实现更为精确的函数级别的裁剪:

通过注释协议栈工程中的 bluenrg_lp_cmd_if.c 中的 cmd_call_table 中对应的函数,编译时可以将不使用的协议栈函数裁减出协议栈。
在这里插入图片描述

5.5 使用静态协议栈这种模式如何支持升级协议栈

当使用静态协议栈,默认协议栈就无法升级。为了能够支持协议栈也升级。需要增加一段 boot代码,当升级协议栈时,先放置在 APP 区域,当升级完协议栈后,将 APP 区域的协议栈拷贝到协议栈区域。接着继续升级被擦除的应用程序。Boot 代码决定搬运协议栈和跳转到下一级。
在这里插入图片描述

6.优化后空间仍不足的其他方法

如果使用静态协议栈和空间仍然不足,可以考虑将一些常用而不需修改的通用模块编译进协议栈的工程。如果空间仍然差距比较远则考虑用片外 Falsh 或者选用 STM32WB 系列,再或者使用 STM32+协处理器模式。

参考文献

在这里插入图片描述


本文档参考ST官方的《【应用笔记】LAT1239+简谈BlueNRG-LP和-LPS的代码空间优化》文档。
参考下载地址:https://download.csdn.net/download/u014319604/89170582

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1608659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Canvas与数学】动态生成圆形中运动的包络线

【题设】 F为圆内任一一点,A为圆周上一点,AF连线的中垂线交圆周与CD两点,求CD围成的图形形状。 【关键点】 使用解析几何方法求出FA中垂线与圆的交点,应用中学数学知识就可做到。 注意中间变量及时求出来比较好,在…

【C++程序员的自我修炼】友元

心之所向 素履以往 目录 友元函数 cout 如何输出自定义类型 cin 如何输入自定义类型 总结 友元类 日期类Date 如何访问 时间类Time 内部类 概念: 总结: 契子✨ 我们之前已经把类与对象的基础知识已经学完了,这些是只针对一个类的操作 那么…

endnote21从安装到使用!文献引用!Mac版

视频学习和资源获取 新建库 选择上方导航栏处的File下的New 软件 软件界面可以分成四个部分 2是个人图书馆 3是对某一分类中文献的展示 最右侧是对具体一篇文献的摘要、编辑以及PDF 有回形针标志意味着这篇有全文,也就是有pdf 如果没有回形针代表它只有引文信…

【电力工程】电力大数据和云架构智能AI服务平台研发建设项目可行性研究报告范例

1、项目概况 本项目拟进行基于电力大数据和云架构的智能 AI 服务平台的研究,具体包括电力多元大数据中心、技术中台、数据中台和智能 AI 中台,基于电力大数据云平台基础构建 BI 可视化开发平台和智能 AI 服务平台。 该项目的实施旨在引领公司在大数据领域发展的新趋势,从功…

【第三版 系统集成项目管理工程师】 十五至尊图

持续更新。。。。。。。。。。。。。。。 【第三版】十五至尊图 十五至尊图【必会】1.整合(7)2.范围 (6)3.进度 (6)4.成本 (4)5.质量(3)6.资源(6&…

el-table使用show-summary合计,但只需要合并某一列

el-table使用show-summary合计,但只需要合并某一列 这里有两种方法,一种是网上的,我会引用他的链接给你们看。 一种是我自己看源码发现的 方法一 这个就是方法一的链接 点击我跳转方法一 方法二 不需要计算的列 去掉prop 然后用插槽显示即可…

利用动态规划在有向图上实现高效语音识别算法

在现代语音识别系统中,动态规划是一种非常关键的技术。它能够帮助我们将复杂的语音信号转换为可理解的文字信息。在本文中,我们将探讨如何使用动态规划方法在有向图上实现语音识别。我们将首先介绍问题的背景和基本概念,然后提供一个高效的算…

【路径规划】局部路径规划算法——DWA算法(动态窗口法)|(含python实现 | c++实现)

文章目录 参考资料1. DWA算法原理1.1 简介1.2 算法原理1. 速度采样2. 轨迹预测(轨迹推算)3. 轨迹评价 2. Python实现2.1 参数配置2.2 机器人运动学模型2.3 DWA算法类实现2.4 画图2.5 主函数 3. c实现4. 总结 参考资料 The Dynamic Window Approach to C…

如何在Windows 10中启用和使用上帝模式,这里有详细步骤

序言 上帝模式(God Mode)是一个特殊的文件夹,只在一个窗口中显示所有可用的操作设置。它可以节省搜索命令的时间,而无需知道通过“开始”菜单或“控制面板”查找命令的步骤。上帝模式默认情况下是隐藏的,所以我们需要…

ROS 2边学边练(29)-- 使用替换机制

前言 启动文件用于启动节点、服务和执行流程。这组操作可能有影响其行为的参数。替换机制可以在参数中使用,以便在描述可重复使用的启动文件时提供更大的灵活性。替换是仅在执行启动描述期间评估的变量,可用于获取特定信息,如启动配置、环境变…

链表带环问题——leetcode环形链表1 2

证明链表带环 链表的带环问题指的是本该指向NULL的最后一个节点指向了之前的节点,导致链表成环,找不到尾结点的情况,那么我们该如何证明链表带环呢? 我们可以类比物理中的追及问题,让快慢指针同时走,两者相…

在wsl下安装QT

文章目录 一、前言二、安装QT1、安装依赖 2、安装qt1、先下载到window中,复制到wsl上2、执行命令 三、命令行打开QT1、打开~/.bashrc,在里面添加命令2、测试 四、mysql驱动 一、前言 本方案可以在wsl下正常安装QT,但是QT菜单栏的字体大小调整不了&#…

【开源】使用Python+Flask+Mysql快速开发一个用户增删改查系统

项目演示 项目本身很简单,增删改查是几乎所有系统的骨架。正所谓万丈高楼平地起,学会了增删改查,航母就指日可待了:),光速入门,直接看演示图: 项目地址 https://github.com/mudf…

[C++][算法基础]欧拉函数(常规求质数)

给定 n 个正整数 ,请你求出每个数的欧拉函数。 欧拉函数的定义 1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。 若在算数基本定理中,N…,则: ϕ(N) N… 输入格式 第一行包含整数 n。 接下来 n 行&#xf…

雨云:让你的服务器体验不再“阴霾”

引言 在当今数字化的时代,服务器已经成为了我们生活中不可或缺的一部分。无论是个人网站、企业应用还是游戏服务器,都需要一个稳定可靠的平台来运行。然而,在选择服务器提供商时,很多人常常陷入选择困难,不知道哪家更适…

IO进程(线程Thread)

线程Thread 1.什么是线程 1.1 概念 线程是一个轻量级的进程,为了提高系统的性能引入线程。 线程和进程都参与统一的调度。 在同一个进程中可以创建的多个线程, 共享进程资源。 (Linux里同样用task_struct来描述一个线程) 1.2 进程和线程的区别…

精益思维驱动人工智能革新:理论到实践的跃迁之旅

随着科技的飞速发展,人工智能(AI)已成为引领未来的关键力量。在这个变革的时代,如何将精益思维与人工智能相结合,推动AI从理论走向实践,成为行业内外关注的焦点。本文,天行健精益生产顾问将分享…

拷贝构造函数与运算符重载

目录 一、拷贝构造函数 1.概念 2.特性 二、运算符重载 1.运算符重载 2.运算符重载实现的形式 3.赋值运算符重载 一、拷贝构造函数 1.概念 拷贝构造函数是一种特殊的构造函数,它在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象…

Vitis HLS 学习笔记--scal 函数-探究

目录 1. Vitis HLS重器-Vitis_Libraries 2. 初识scal() 3. 函数具体实现 3.1 变量命名规则 3.2 t_ParEntries解释 3.3 流类型详解 3.4 双重循环 4. 总结 1. Vitis HLS重器-Vitis_Libraries 在深入探索Vitis HLS(High-Level Synthesis)的旅程中&…

【单调栈】力扣85.最大矩形

好久没更新了 ~ 我又回来啦! 两个好消息: 我考上研了,收到拟录取通知啦!开放 留言功能 了,小伙伴对于内容有什么疑问可以在文章底部评论,看到之后会及时回复大家的! 前面更新过的算法&#x…