前言

概述

本文档介绍BS2X系列芯片SDK开发环境(包括:SDK编译、应用程序的开发等),用于帮助用户在快速了解开发环境后编译出可执行文件进行二次开发。

产品版本

与本文档相对应的产品版本如下。

产品名称

产品版本

BS2X

V100

读者对象

本文档主要适用于以下工程师:

  • 技术支持工程师

  • 软件开发工程师

符号约定

在本文中可能出现下列标志,它们所代表的含义如下。

符号

说明

表示如不避免则将会导致死亡或严重伤害的具有高等级风险的危害。

表示如不避免则可能导致死亡或严重伤害的具有中等级风险的危害。

表示如不避免则可能导致轻微或中度伤害的具有低等级风险的危害。

用于传递设备或环境安全警示信息。如不避免则可能会导致设备损坏、数据丢失、设备性能降低或其它不可预知的结果。

“须知”不涉及人身伤害。

对正文中重点信息的补充说明。

“说明”不是安全警示信息,不涉及人身、设备及环境伤害信息。

修改记录

文档版本

发布日期

修改说明

04

2025-08-07

更新“打包添加其他bin文件”小节内容。

03

2025-05-30

更新“flash分区表配置”小节内容。

02

2025-01-24

  • 调整文档内容结构。
  • 新增“搭建Windows开发环境”小节内容。
  • 新增“编译SDK(Cmake)”小节内容。

01

2024-05-15

第一次正式版本发布。

00B03

2024-02-29

更新“版本编译”小节内容。

00B02

00B01

2023-12-04

2023-10-27

更新“启动编译”小节内容。

第一次临时版本发布。

开发环境搭建

SDK开发环境简介

典型的SDK开发环境主要包括:

  • Linux服务器

    Linux服务器主要用于建立交叉编译环境,实现在Linux服务器上编译出可以在目标板上运行的可执行代码。

  • 工作台

    工作台主要用于目标板烧录和调试,通过串口与目标板连接,开发人员可以在工作台中烧录目标板的镜像、调试程序。工作台通常需要安装终端工具,用于登录Linux服务器和目标板,查看目标板的打印输出信息。工作台一般为Windows或Linux操作系统,在Windows或Linux工作台运行的终端工具通常有SecureCRT、Putty、miniCom等,这些软件需要从其官网下载。

  • 目标板

    本文的目标板以DEMO板为例,DEMO板与工作台通过USB转串口连接。工作台将交叉编译出来的DEMO板镜像通过串口烧录到DEMO板。如图1所示。

    图 1 SDK 开发环境

搭建Windows开发环境

BS2X解决方案提供了Windows下IDE开发工具,支持一键构建版本,基于IDE的编译环境搭建,请参考《BS2XV100 IDE工具使用指南》,本文档不再赘述。

搭建Linux开发环境

Linux系统推荐使用Ubuntu 20.04及以上版本,Shell使用bash ,SDK使用Cmake编译(3.14.1以上),编译工具还包括Python(3.8.0以上)等。

配置Shell

配置默认使用 bash。打开Linux终端,执行命令“sudo dpkg-reconfigure dash”,选择 no。

安装Cmake

打开Linux终端,执行命令“sudo apt install cmake”,完成Cmake的安装。

安装Python环境

  1. 打开Linux终端,输入命令“python3 -V”,查看Python版本号,推荐python3.8.0以上版本。

  2. 如果Python版本太低,请使用命令“sudo apt-get update”更新系统到最新,或通过命令“sudo apt-get install python3 -y”安装Python3(需root/sudo权限安装),安装后再次确认Python版本。

    如果仍不能满足版本要求,请从“https://www.python.org/downloads/source/ ”下载对应版本源码包,下载与安装方法请阅读 https://wiki.python.org/moin/BeginnersGuide/Download 和源码包内README内容。

  3. 安装Python包管理工具,运行命令“sudo apt-get install python3-setuptools python3-pip -y”(需root/sudo权限安装)。

  4. 安装Kconfiglib 14.1.0+,使用命令“sudo pip3 install kconfiglib”(需root/sudo权限安装),或从“https://pypi.org/project/kconfiglib”下载.whl文件(例如:kconfiglib-14.1.0-py2.py3-none-any.whl)后,使用“pip3 install kconfiglib-xxx.whl”进行安装(需root/sudo权限安装),或者下载源码包到本地并解压,使用“python setup.py install”进行安装(需root/sudo权限安装)。安装完成界面如图1所示。

    图 1 安装Kconfiglib组件包完成示例

  5. 安装升级文件签名依赖的Python组件包。

    安装pycparser:

    从“https://pypi.org/project/pycparser/”下载.whl文件(例如:pycparser-2.21-py2.py3-none-any.whl)后,使用“pip3 install pycparser-xxx.whl”进行安装(需root/sudo权限安装),或者下载源码包到本地并解压,使用“python setup.py install”进行安装(需root/sudo权限安装)。安装完成后界面会提示“Successfully intalled pycparser-2.21”。

说明: 如果构建环境中包含多个python,特别是多个同版本的python,而用户无法辨认正在使用的是其中的哪个版本,此情况下,在安装python组件包时,推荐使用组件包源码进行安装。

编译SDK

SDK目录结构介绍

SDK根目录结构如表1所示。

表 1 SDK根目录

目录

说明

application

应用层代码(其中包含demo程序为参考示例)。

build

SDK构建所需的脚本、配置文件。

build.py

编译入口脚本。

CMakeLists.txt

Cmake工程顶层“CMakeLists.txt”文件。

config.in

Kconfig配置文件。

drivers

驱动代码。

include

API头文件存放目录。

interim_binary

库存放目录。

kernel

内核代码和OS接口适配层代码。

middleware

中间件代码。

open_source

开源代码。

protocol

BLE、SLE等协议栈。

test

testsuite代码。

tools

包含编译工具链(包括linux和windows)、镜像打包脚本、NV制作工具和签名脚本等。

output

编译时生成的目标文件与中间文件(包括库文件、打印log、生成的二进制文件等)。

注:上表所述的output目录是编译后生成的。解压缩SDK后的根目录,如图1所示。

图 1 解压缩SDK示例

编译SDK(Cmake)

编译方法

根目录下执行“python3 build.py”指令运行脚本编译,即可编译出对应的SDK程序。编译命令列表如表1所示。此处以standard-bs21-n1100为例说明,根据BS2X项目不同编译目标可能不一致。

表 1 build.sh参数列表

参数

示例

说明

python3 build.py standard-bs21-n1100

启动standard-bs21-n1100目标的增量编译。

-c

python3 build.py -c standard-bs21-n1100

启动standard-bs21-n1100目标的全量编译。

menuconfig

python3 build.py standard-bs21-n1100 menuconfig

启动standard-bs21-n1100目标的menuconfig图形配置界面。

表 2 编译目标介绍

编译目标

说明

python3 build.py -c standard-bs21-n1100

app版本编译目标(flashboot将被打包至编译产物)。

python3 build.py -c flashboot-bs21-n1100

flashboot镜像编译目标。

编译得到的烧录镜像在“output/bs21/fwpkg/standard-bs21-n1100”目录下(如表3所示)。

表 3 烧录镜像

文件名

说明

bs21_all_in_one.fwpkg

空片烧录时,需要烧录此文件。包含了所有的需要烧录的内容。包含:loaderboot_sign.bin、flashboot_sign_a.bin、flashboot_sign_b.bin、bs21_all_nv.bin、application_sign.bin。

各文件介绍如下:

loaderboot_sign.bin:loaderboot的镜像文件。升级开始时,芯片中固化的romboot会接收此镜像文件,加载到内存并运行,loadboot负责接收后续的镜像文件。注:此镜像只在升级阶段放在RAM中运行,并不存放在flash中。

flashboot_sign_a.bin:flashboot的镜像文件,烧录完成执行后,首要执行的flashboot镜像,启动时会校验flashboot的完整性。

flashboot_sign_b.bin:flashboot的备份镜像文件,当首要flashboot镜像被检查为不合法或已损坏时,将加载本镜像。

bs21_all_nv.bin:参数区的镜像文件。

application_sign.bin:应用版本镜像文件。

bs21_loadapp_only.fwpkg

版本升级打包文件,包含:loaderboot_sign.bin、application_sign.bin。不包含flashboot相关内容。

当芯片烧录过“bs21_all_in_one.fwpkg”镜像后,如果后续修改不涉及flashboot、nv的修改,则可以用此文件升级。

bs21_flashboot_only.fwpkg

boot升级打包文件,包含:loaderboot_sign.bin、flashboot_sign_a.bin、flashboot_sign_b.bin。不包含application相关内容。

当芯片烧录过“bs21_all_in_one.fwpkg”镜像后,有升级flashboot的需求,可用此文件升级。

bs21_nv_only.fwpkg

nv升级打包文件,包含loaderboot_sign.bin、bs21_all_nv.bin。不包含application和flashboot相关内容。

当芯片烧录过“bs21_all_in_one.fwpkg”镜像后,有升级nv参数的需求,可用此文件升级。

注:编译得到的中间文件在“output/bs21/acore/standard-bs21-n1100”目录下。

编译参数详解

编译命令接收参数及解释如表1所示。

表 1 编译参数信息表

参数

参数信息

-c

clean后编译。

-j

-j<num>,以num线程数执行编译,如-j16、-j8。

默认最大线程。

-def=

-def=XXX,YYY,ZZZ=x,... 向本次编译target中添加XXX、YYY、ZZZ=x编译宏。

可使用-def=-:XXX屏蔽XXX宏;

可使用-def=-:ZZZ=x添加或者修改ZZZ宏。

-component=

-component=XXX,YYY,... 仅编译XXX,YYY组件。

-ninja

使用ninja生成中间文件,默认使用Unix makefile。

-[release / debug]

release: 在生成反汇编文件时节省时间;

debug: 在生成反汇编文件时信息更加全面但也更耗时。

默认为debug。

-dump

编译时在终端输出target的所有参数列表(包括编译宏、组件、编译选项等)。

-nhso

不更新HSO数据库。

-out_libs

-out_libs=file_path,不再链接成elf,转而将所有.a打包成一个大的.a。

others

作为匹配编译target_names的关键字。

编译选项详解

bs2x在不同目录下的.py文件下配置编译选项,如表1所示。

表 1 BS2X通用组件编译选项

编译选项类型

说明

内容

对应文件控制路径

common_ccflags

基础编译选项

-std=gnu99 -Wall -Werror -Wextra -Winit-self -Wpointer-arith -Wstrict-prototypes -Wno-type-limits -fno-strict-aliasing -Os -fno-unwind-tables

\sdk\build\config\target_config\common_config.py

riscv31

芯片类型编译选项

-ffreestanding -fdata-sections -Wno-implicit-fallthrough -ffunction-sections -nostdlib -pipe -fno-tree-scev-cprop -fno-common -mpush-pop -msmall-data-limit=0 -fno-ipa-ra -Wtrampolines -Wlogical-op -Wjump-misses-init -Wa,-enable-c-lbu-sb -Wa,-enable-c-lhu-sh -fimm-compare -femit-muliadd -fmerge-immshf -femit-uxtb-uxth -femit-lli -femit-clz -fldm-stm-optimize -g

\sdk\build\config\target_config\common_config.py

fp_flags

硬浮点编译选项

-march=rv32imfc -mabi=ilp32f

\sdk\build\config\target_config\bs21\target_config.py

codesize_flags

codesize优化选项

--short-enums -madjust-regorder -madjust-const-cost -freorder-commu-args -fimm-compare-expand -frmv-str-zero -mfp-const-opt -frtl-sequence-abstract -frtl-hoist-sink -fsafe-alias-multipointer -finline-optimize-size -fmuliadd-expand -mlli-expand -Wa,-mcjal-expand -foptimize-reg-alloc -fsplit-multi-zero-assignments -floop-optimize-size -Wa,-mlli-relax -mpattern-abstract -foptimize-pro-and-epilogue

\sdk\build\config\target_config\bs21\target_config.py

其中,编译选项的详细说明如表2所示。

表 2 编译选项详细说明

选项

说明

-std=gnu99

使用 ISO C99 标准再加上GNU的扩展。

-Wall

选项意思是编译后显示所有警告。

-Werror

用于将所有警告升级成错误。

-Wextra

用于开启额外的警告信息(-Wall的补充)。

-Winit-self

警告使用自己初始化的未初始化变量。

-Wpointer-arith

警告任何取决于“功能类型”或“功能类型”的大小void。

-Wstrict-prototypes

警告如果一个函数被声明或定义而没有指定参数类型。

-Wno-type-limits

屏蔽由于数据类型范围有限而导致比较始终为真或始终为false的告警。

-fno-strict-aliasing

禁用strict-aliasing优化规则:不同类型的指针绝对不会指向同一块内存区域。

-Os

专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项,同时-Os还会执行更加优化程序的选项。

-fno-unwind-tables

删除unwind调试信息。

-ffreestanding

断言编译发生在独立环境中。

-fdata-sections

将每个数据放入自己的部分(仅限ELF)。

-Wno-implicit-fallthrough

可忽略编译时switch-case中缺少break的错误。

-ffunction-sections

将每个函数放在自己的节中(仅限ELF)。

-nostdlib

关闭默认头文件与库文件搜索目录。

-pipe

编译过程中使用管道,借助GCC的管道功能来提高编译速度。

-fno-tree-scev-cprop

禁用标量演化信息进行复写传递,代码空间优化相关。

-fno-common

可以把静态库中的没有初始化的全局变量从弱符号变成强符号,当所有静态库链接成可执行文件,如果同时有两个以上“重名强符号”,链接器会报错。

-mpush-pop

CodeSize优化,改编译选项需要CPU版本支持push/pop/popret/lwm/swm等指令。

-msmall-data-limit=0

CodeSize优化,改编译选项需要CPU版本支持push/pop/popret/lwm/swm等指令。

-fno-ipa-ra

禁用编译器针对叶子函数的编译优化(编译选项中添加了-O2优化选项时-fipa-ra参数导致)。

-Wtrampolines

该选项用于检查代码中是否包含内嵌函数,gcc对内嵌函数有个专门的称呼:trampoline。

-Wlogical-op

当逻辑操作结果似乎总为真或假时给出警告。

-Wjump-misses-init

switch或者goto语句后声明并且初始化变量,进行告警。

-Wa,-enable-c-lbu-sb

汇编器优化,默认禁用。如果启用此优化,汇编器将使用压缩的lbu & sb替换 lbu & sb。

-Wa,-enable-c-lhu-sh

汇编器优化,默认禁用。如果启用此优化,汇编器将使用压缩的lhu & sh替换 lhu & sh。

-fimm-compare

代码大小的优化,可以将非零立即比较的两条指令(li,bxx)合并到一条指令(bxxi)。

-femit-muliadd

CodeSize优化,可以将多条加树指令合并为一条指令。

-fmerge-immshf

CodeSize优化,可以将立即移位合并为一条指令。组合仅在-O1以上的选项中生效。

-femit-uxtb-uxth

CodeSize优化,将无符号扩展字节和无符号扩展半字优化为uxtb、uxth(16字节)。组合仅在-O1以上的选项中。

-femit-lli

使用48位l.li指令代替64位指令lui + addi进行32位长立即加载。此优化与insn组合结合使用。

-femit-clz

支持CLZ指令,所有__builtin_clz函数的调用都会优化为CLZ指令。

-fldm-stm-optimize

启用用 ldmia/stmia 替换连续WORD加载/存储的优化,默认禁用。

-g

调试编译选项,对于可执行二进制文件可通过以下方法确定是否包含调试信息。

-mabi=ilp32f

支持硬浮点(指定整数和浮点调用约定)。

-march=rv32imfc

支持硬浮点(为给定的RISC-V ISA生成代码)。

--short-enums

CodeSize优化,enum类型等于大小足够的最小整数类型。

-madjust-regorder

寄存器分配优化-寄存器分配顺序调整优化。

-madjust-const-cost

立即数重复加载优化。

-freorder-commu-args

浮点运算可交换操作数优化。

-fimm-compare-expand

扩展指令常量比较指令优化。

-frmv-str-zero

rodata段常量字符串对齐优化。

-mfp-const-opt

浮点常量加载优化。

-mswitch-jump-table

switch case跳转表优化。

-frtl-sequence-abstract

函数内过程优化。

-frtl-hoist-sink

代码移动优化。

-fsafe-alias-multipointer

多级指针重复加载优化。

-finline-optimize-size

inline内联代价模型优化。

-fmuliadd-expand

扩展指令乘加指令优化(muliadd优化)。

-mlli-expand

扩展指令l.li指令优化。

-Wa,-mcjal-expand

汇编器上jal压缩指令优化。

-foptimize-reg-alloc

寄存器分配优化-寄存器分配优先级调整优化。

-fsplit-multi-zero-assignments

连续赋零值优化。

-floop-optimize-size

循环结构优化。

-Wa,-mlli-relax

高频立即数加载优化(汇编器和链接器协同优化)。

-mpattern-abstract

过程间抽象优化(根据已知pattern抽象优化)。

-foptimize-pro-and-epilogue

函数prologue和epilogue优化。

打包添加其他bin文件

当前bs21编译bs21_all_in_one.fwpkg时,默认会编译bs21_all_nv.bin、application_sign.bin文件,在打包时则会添加loaderboot_sign.bin、flashboot_sign_a.bin、flashboot_sign_b.bin文件,文件介绍如表3所示。

如果需要打包其他bin文件,可按如下步骤添加:

  1. 在根路径下打开/tools/pkg/chip_packet/bs2x/packet.py文件。

  2. 在make_all_in_one_packet函数中添加代码,如图1所示。

    图 1 文件路径和待添加函数

  3. 在函数中添加bin文件路径,以partition.bin为例。

    其中每个拼接字符串代表一层目录(文件夹名和文件名)

    最终拼接完成的partition.bin实际路径:sdk\interim_binary\bs21\bin\boot_bin\loaderboot_sign.bin。

    图 2 bin文件路径图

  4. 设置打包参数,参数之间用"|"分割,如图3所示。

    图 3 bin文件编译参数

    1. 烧录位置,单板剩余地址可在sdk\build\config\target_config\bs2x\flash_sector_config\bs2x-xxx.json文件中查看。

    2. 占用空间大小。

    3. 文件类型。

    • 0:loader。

    • 1:代表普通烧写文件,烧写到flash。

    • 3:eFuse。

    • 4:OTP。

  5. 在函数末尾,将设置好编译参数和路径的变量添加到编译列表,如图3所示。

    图 4 添加路径到编译列表

  6. 编译结果展示如图5所示。

    图 5 编译结果

说明: 如果新增的bin文件有通过OTA升级的需求,请参见《BS2XV100 升级方案 使用指南》中对应内容,适配新增bin文件的OTA升级支持。

flash分区表配置

分区表配置文件路径“sdk\build\config\target_config\bs21\flash_sector_config\xxx.json”。

表 1 分区表说明

分区表Id

起始地址

分区长度

描述

0x00

0x00001000

0x0000A000

flashboot a:二级boot主区(size根据使用使用大小配置)。

0x01

0x0000B000

0x00000000

flashboot b:二级boot备份区(size根据使用使用大小配置)。

0x23

0x0000B000

0x00073000

acpu image:应用程序分区。

0x25

0x00000000

0x00000080

nv data:nv数据区域。

0x26

0x00000080

0x00000700

fota dat:fota备份区。

0x27

0x00000000

0x00000000

rsv1:预留分区1。

0x28

0x00000000

0x00000000

rsv1:预留分区2。

0x29

0x00000000

0x00000000

rsv1:预留分区3。

0x30

0x00000000

0x00000000

rsv1:预留分区4。

0x31

0x00000000

0x00000000

rsv1:预留分区5。

0x32

0x00000000

0x00000000

rsv1:预留分区6。

0x33

0x00000000

0x00000000

rsv1:预留分区7。

说明: 分区表Id[0x0, 0x26]为镜像加载启动、OTA升级使用的分区信息,请谨慎修改,分区表信息可通过uapi_partition_get_info接口传入分区Id获取对应地址和长度。 Partition_defines为分区表宏定义传参,当使能Use_defines时,会将对应ID的分区表偏移以及大小按照指定的宏定义传入到后续构建阶段,在代码中可以直接引用。

注意事项

  • 如果执行“./build.py”提示无权限,可执行命令“chmod +x build.py”添加执行权限或执行“python3./build.py”。

  • 编译过程中,报错找不到某个包,请检查环境中的python是否已经安装了相应组件。如果构建环境中包含多个python,特别是多个同版本的python,而用户无法辨认正在使用的是其中的哪个版本,此情况下,在安装python组件包时,推荐使用组件包源码进行安装。

  • 系统优先使用用户通过Menuconfig所做的配置,如果用户未配置,系统将使用默认配置进行编译。

新建APP

建立源码目录

说明: 用户可在“application/bs21”同级目录下参考“standard-bs21-n1100”目录建立app,以下均以建立“my_demo”为例。

步骤如下:

  1. 新建“application/bs21/my_demo”目录,用来存放“my_demo”的源文件。

  2. 复制“application/bs21/standard/CMakeLists.txt”到“application/bs21/my_demo/CmakeLists.txt”,并将源文件放在“application/bs21/my_demo”目录下。

  3. 修改“application/bs21/my_demo/CmakeLists.txt”文件。其中各个变量的含义如表1所示。

    表 1 组件的CmakeLists.txt中的变量含义

    变量名称

    变量含义

    COMPONENT_NAME

    当前组件名称,如“my_demo”。

    SOURCES

    当前组件的C文件列表,其中CMAKE_CURRENT_SOURCE_DIR变量标识当前CMakeLists.txt所在的路径。

    PUBLIC_HEADER

    当前组件需要对外提供的头文件的路径。

    PRIVATE_HEADER

    当前组件内部的头文件搜索路径。

    PRIVATE_DEFINES

    当前组件内部生效的宏定义。

    PUBLIC_DEFINES

    当前组件需要对外提供的宏定义。

    COMPONENT_PUBLIC_CCFLAGS

    当前组件需要对外提供的编译选项。

    COMPONENT_CCFLAGS

    当前组件内部生效的编译选项。

  4. 修改“application/bs21/CMakeLists.txt”,将my_demo目录加入编译。

  5. 修改“build/config/target_config/bs21/config.py”,在ram_component字段中加入‘my_demo’,向编译系统中注册my_demo组件。

开发代码

目录结构建立完成后开始启动开发代码(用户可参考“application/samples”进行移植),代码开发完成后即可使用“python3 build.py -c standard-bs21-n1100”编译my_demo进行代码编译调试。

镜像烧录

镜像烧录方法,请参见《BS2XV100 BurnTool工具 使用指南》中“操作指南”章节。