最近在使用BES2700进行TWS/OWS蓝牙耳机开发,理解SDK代码组织结构和系统初始化流程是高效开发的基石,本篇文章以BES2700-SDK为例,简单介绍了SDK目录结构以及SDK启动流程代码浅析。

SDK目录结构

SDK包解压后,打开SDK目录便可以看见SDK代码目录结构如下。
SDK目录结构
以下是SDK各个目录的简单介绍:
apps:主要存放上层应用相关的代码。
bthost:存放蓝牙相关代码,包括蓝牙应用层和蓝牙协议栈的代码。
config:存放配置相关文件,主要存放各个target的.mk文件,不同项目可以配置不同的target以达到项目差异化配置。
include:主要包含了系统的头文件。
lib:存放BES代码封装的库文件。
out:代码编译输出文件。
platform:该目录下主要存放一些底层驱动文件(硬件驱动,RF驱动等),正常情况下不需要修改。
rtos:存放操作系统代码, BES的SDK代码使用RTX嵌入式操作系统。
scripts:存放链接和编译相关脚本。
services:存放蓝牙协议相关代码。
tests:存放SDK测试相关代码,一般不用修改。
thirdparty:存放第三方代码文件。
utils:存放加密,校验等工具集。

SDK启动流程浅析

SDK代码中使用的是RTX5嵌入式系统,RTX5是一个嵌入式实时操作系统,基本功能就是开始和停止任务(进程),除此之外还支持进程通信,例如任务的同步、共享资源(外设或内存)的管理、任务之间消息的传递。可以解决众多的调度、维护、定时等问题。目前是CMSIS软件包的一部分,本身是免费且开源的,具有Apache2.0授权,几乎可以随意商用。其主要运用在ARM Cortex-M系列架构的微控制器上。

引导程序

BES的SDK中的启动引导程序在SDK\platform\main路径下的startup_main.S文件。startup_main.S是BES SDK的启动加载程序汇编代码,其主要功能有:
堆栈设置、特权模式配置等;数据段(.data)从只读存储器复制到 RAM;未初始化数据段(.bss)清零;跳转至C运行时环境或用户程序入口。
引导程序

系统启动

系统OS初始化于C语言内嵌汇编编写的函数,软件初始化钩子函数software_init_hook()开始,用于在进入main()函数之前执行一些系统的初始化工作,比如初始化更新系统核心时钟,以便后续库函数可以使用正确的时钟值,osKernelInitialize初始化内核,创建主线程(执行main函数),启动内核调度osKernelStart,如下图。
系统启动

硬件初始化

系统启动后进入main函数,main函数函数比较长,这其中主要会做一些硬件和软件的初始化动作。硬件相关的比如看门狗初始化app_wdt_open(),tgt_hardware_setup() 硬件IO初始化,硬件定时器hwtimer初始化,DEBUG串口初始化,音频硬件初始化,Norflash存储初始化,电源管理单元PMU等硬件相关的初始化。
硬件初始化

应用层软件初始化

主线程main函数中硬件相关初始化完成后,main线程调用app_init()对软件应用相关做相应的初始化动作。
app_init()函数位于apps\main\apps.cpp文件中,用于执行应用层软件相关的各种初始化任务,比如软件配置参数的初始化、软件应用层相关状态初始化、蓝牙相关功能初始化、用户自定义的功能代码初始化、用户自定义任务初始化等。
app初始化
这里需要注意的是app_init()函数的返回值,返回值为0代表着代码应用层初始化正常,main线程进入while(1)循环,一直等待关机或重启的信号量,此时系统便启动完成了,应用层代码正常处理其他线程的代码工作。
app初始化返回值
如果app_init返回值不为0或main线程收到了发送过来的信号量,则会退出main线程的while(1)循环,根据sys_case值进入系统关机或系统重启操作。
main线程退出

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐