Hello ,大家好!上次写了基于恒玄模块的 单线串口通讯模块,本文在这里对恒玄蓝牙SDK 做简单的介绍。

一 .软件系统构架

1.BES采用的是RXT RTOS(嵌入式实时操作系统),并且用了ARM的CMSIS_RTOS API接口

2. 我们知道程序运行开始的地方是RTX_CM_LIB.H里面的_main_init(),主要是进行内核初始化、堆栈的设置、main线程的创建和开启内核等。

3.第一个线程os_thread_def_main就是main,接着看,在main.cpp文件中。

然后再是 debug 端口的初始化 (一把我们用 debug=1)默认开启UART0  RX的 打印输出。

在 uart 初始化完成后 会打印输出 当前软件、芯片、flash分区大小等一些信息  hal_trace.c 中:

打印输出大致如下 :

[18:35:14.391]CHIP=best1305
[18:35:14.391]KERNEL=RTX5
[18:35:14.391]CRASH_DUMP_SIZE=0
[18:35:14.391]AUD_SEC_SIZE=0x10000
[18:35:14.391]USER_SEC_SIZE=0x1000
[18:35:14.391]FACT_SEC_SIZE=0x1000
[18:35:14.391]NV_REC_DEV_VER=2
[18:35:14.391]FLASH_BASE=0x38000000
[18:35:14.391]FLASH_SIZE=0x400000
[18:35:14.391]OTA_CODE_OFFSET=0x28000
[18:35:14.391]CRC32_OF_IMAGE=0x00000000
[18:35:14.391]BUILD_DATE=Mar 10 2021 18:21:32
[18:35:14.391]REV_INFO=:best2500i_JBL_T230
[18:35:14.391]
[18:35:14.391]
[18:35:14.391]------
[18:35:14.391]METAL_ID: 0
[18:35:14.391]------

随后 软件运行会判断当前flash实际大小与软件定义是否匹配,如果软件定义的flash size 超过芯片自带flash大小,就会打印输出

“Wrong FLASH_SIZE defined in target.mk!”

“FLASH_SIZE is defined as 0x20000 while the actual chip flash size is 0x40000” 随后死机。

如果flash无异常 后续就会启动  硬件IO 配置和模拟输入输出IO 配置

随后 跑入app_init

最后 如果初始化完成 就在一直死循环执行 线程任务

如果app_init里面初始化提前结束并且返回 非0  则直接关机

4. BES 的线程/任务消息 /定时器创建和使用。

首先说个概念理解 :1.线程是基于RTOS的一个任务调度处理 (模拟多核 占用时间片的)

2.每个线程都是独立并且不会被同一时间执行的

3.一个线程里面可以包含多个 消息模块处理.

A.线程

第一个线程os_thread_def_main就是main,接着看,在main.cpp文件中:

app_os_init()里有线程创建,这是CMSIS的风格,开发过STM32应该比较熟悉,用来定义线程、定时器和邮箱通讯等;
app_thread_tid = osThreadCreate(osThread(app_thread), NULL);

app_thread为线程loop函数,OSThread其实是一个宏,就是取地址而已
#define osThread(name) &os_thread_def_##name

所以OSThreadDef是设置线程名、优先级以及堆栈大小,通过osThread获取配置的结构体变量的指针,然后作为参数传入OSThreadCreate()。

一般在文件开头会看到这样的定义:osThreadDef其实也是一个宏
osThreadDef(app_thread, osPriorityHigh, 1, 1024, “app_thread”);

PS:早期的线程定义是这样的:

/* thread */
static osThreadId uartrxtx_tid; 
uint32_t os_thread_def_stack_uartrxtx [UART_STACK_SIZE/ sizeof(uint32_t)];
osThreadDef_t os_thread_def_app_uartrxtx = {(app_uartrxtx),(osPriorityHigh),(UART_STACK_SIZE),(os_thread_def_stack_uartrxtx)};

这里就是给一个结构体变量初始化赋值,然后把os_thread_def_app_thread的地址传给os_thread()。结构体类型是:

/  ==== Thread Management Functions ====

/// Create a Thread Definition with function, priority, and stack requirements.
/// \param         name          name of the thread function.
/// \param         priority      initial priority of the thread function.
/// \param         instances     number of possible thread instances.
/// \param         stacksz       stack size (in bytes) requirements for the thread function.
/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
///       macro body is implementation specific in every CMSIS-RTOS.

#define osThreadDef(name, priority, instances, stacksz, task_name) \
uint64_t os_thread_def_stack_##name [(8*((stacksz+7)/8)) / sizeof(uint64_t)]; \
const osThreadDef_t os_thread_def_##name = \
{ (name), \
  { task_name, osThreadDetached, NULL, 0U, os_thread_def_stack_##name, 8*((stacksz+7)/8), (priority), 1U, 0U } }
下面是关于线程的创建:

我们再看下线程的执行:

下面我们看一下app_thread线程里面的具体做了什么:
if (mod_handler[msg_p->mod_id])
int ret = mod_handler[msg_p->mod_id] (&(msg_p->msg_body));

我们可以看到在app_thread线程中,通过app_mailbox_get()反复的在获取邮箱信息,并传入mod_handler[]里面。
static APP_MOD_HANDLER_T mod_handler[APP_MODUAL_NUM];

看其数据类型是一个函数指针数组,再看其数组下标的定义:

关于线程的创建使用实际代码连接如下 (包含新旧版本):

https://share.weiyun.com/GUat9L7n

B:消息任务:

消息任务是基于 线程下一级的处理

目前通用的都是基于 app_thread  线程的消息任务处理 ,当然也可以在其余线程中增加任务处理 。

由上面线程讲解我们知道各个模块会注册自己的回调函数,然后app_thread()会根据get的消息回调模块对应的API进行处理。

所以任务在注册之前需要在app_os_init 之后 然后再去注册消息执行函数。

消息处理函数通用接口:

返回值为  int 类型数据  携带 APP_MESSAGE_BOY *的 结构体参数指针。

这里以我写的NTC 消息处理做讲解:

C 定时器:

定时器分为软件定时器和硬件定时器,本质上都是时间到了后执行中断处理。

区别是硬件定时器以 硬件时钟为基准 所以相对来说会更准确 测量精度更小,且硬件定时器是一次性的 。

定时器 可以重载 但不能在中断里面使用

C1:硬件定时器

头文件: #include "hwtimer_list.h"

static HWTIMER_ID app_box_det_debounce_tid = NULL;  //硬件定时器ID 定义  一般定义为全部变量

app_box_det_debounce_tid = hwtimer_alloc(app_box_det_debounce_timehanlder, NULL); //关联定时器中断执行函数。app_box_det_debounce_timehanlder会携带 void*类型参数。

hwtimer_start(app_box_det_debounce_tid,MS_TO_TICKS(200));// 启动定时器  需要注意后面不能直接填写时间,需要转为时钟

hwtimer_stop(app_box_det_debounce_tid); // 定时器可以被提前停止,移除队列 改定时器就当此就不再执行。

C2: 软件定时器:

头文件:

#include "cmsis_os.h"
#include "hal_timer.h"

typedef enum {
  osTimerOnce               = 0,          ///< One-shot timer.
  osTimerPeriodic           = 1           ///< Repeating timer.
} osTimerType_t;

static osTimerId app_battery_timer = NULL; //软件定时器ID  
static void app_battery_timer_handler(void const *param); //定时器 中断执行函数 ,可以携带 void* 类型参数
osTimerDef (APP_BATTERY, app_battery_timer_handler); //软件定时器 需要用宏关联定时器 和 执行函数

app_battery_timer = osTimerCreate (osTimer(APP_BATTERY), osTimerPeriodic, NULL); //软件定时器创建 APP_BATTERY为定时器寻址ID

第二个参数 是 定时器是否为周期性的,如果是一次性的 那么以后时间到了 执行完后就不会再被执行 ,但是ID 还是在  可以再次start.

osTimerStop(app_battery_timer); //停止该软件定时器
 osTimerStart(app_battery_timer,5000); // 重新开启软件定时器 ,并在5S后执行 定时器中断。

这一篇的系统架构 暂时说到这里  后续 子模块详细分析  请大家继续订阅 查看 ,谢谢!

QQ:1902026113

BES SDK 软件架构开发简介相关推荐

  1. 搭建DJI 无人机Onboard SDK ROS开发环境及测试

    搭建DJI 无人机Onboard SDK ROS开发环境及测试 功能包简介 开发环境搭建 测试功能包 连接设备 启动SDK 功能包简介 ROS功能包名称:dji_sdk 功能包功能:用于DJI 板载S ...

  2. 无责任Windows Azure SDK .NET开发入门(二):使用Azure AD 进行身份验证

    <編者按>本篇为系列文章,带领读者轻松进入Windows Azure SDK .NET开发平台.本文为第二篇,将教导读者使用Azure AD进行身分验证.也推荐读者阅读无责任Windows ...

  3. 大恒相机开发(大恒SDK+opencv开发)笔记1

    大恒相机开发(大恒SDK+opencv开发 一.项目简介 在大三上学期做过人脸识别的开发,刚好下学期老师手中有相机的项目,然后项目就到了我手上,下面是我开发这个项目的一些经历,进程还在调试中.笔记会按 ...

  4. 2_嵌入式软件开发简介

    文章目录 嵌入式软件开发简介 常用软件流程 轮询方式 中断驱动方式 多任务系统 C程序中的数据类型 Cortex微控制器软件接口标准(CMSIS) CMSIS简介 CMSIS-Core所做的标准化 处 ...

  5. Android下DLNA开发简介

    Android下DLNA开发简介     前端时间在博客上有写过一篇关于DLNA开发Cling开源库的使用,虽然写的不是很好但是也有几个对DLNA开发有兴趣的同仁有询问我关于这方面的知识.趁着现在有空 ...

  6. Palm OS开发简介

    Palm OS开发简介 --简单介绍Palm OS上的应用软件开发过程 篇首语:Palm OS现在的正确名字其实是Garnet OS...不过Palm OS更为人们所知... Palm OS历史 Pa ...

  7. 爱联模组接入华为hilink总结——开发简介和移植(一)

    下面我讲述的爱联固件版本都是9.0.1.131前的,131后的版本都是带有PIN码的连接的,后面也都会使用带pin码的,为啥我现在不用,因为华为APP(在2020/2/14这个时间点)还没有上线带PI ...

  8. Adreno GPU上的DirectX应用开发简介 (4)

    Adreno GPU上的DirectX应用开发简介 (4) 3 工具和资源 3.1 Microsoft Direct3D11.1 Tools 3.2 Qualcomm Adreno SDK 3.3 Q ...

  9. DeepMar-基于 MindStudio 的 MindX SDK 应用开发

    DeepMar-基于 MindStudio 的 MindX SDK 应用开发 MindX SDK 简介 MindX SDK应用开发是使用华为提供的开发套件完成模型的迅速开发以及部署人工智能应用.本文将 ...

最新文章

  1. 停车场计费算法 php,停车场收费算法,思路卡住了求补完!该如何处理
  2. WSDM 2020 | RMRN:社区问答中的深度关联推理模型
  3. Transformer模型总结
  4. 机器学习股票_使用概率机器学习来改善您的股票交易
  5. linux怎么查看数据库性能,正确评估SQL数据库性能,你必须知道的原理和方法!...
  6. 在powerDesigner中通过SQL生成pdm
  7. 20个你可能不知道的 Linux 网络工具
  8. 连接服务器打印机文件名无效,excel服务器-办公室常识——共享服务器文件报错,共享打印机无法打印的解决办法(解决word、excel不能打印))...
  9. 反编译PyInstaller打包后的exe为py源码
  10. ie 无人操作自动关闭_Win10系统下ie浏览器无响应白屏自动关闭如何修复
  11. PYTHON-音视频合并方法
  12. springboot+宿舍管理小程序 毕业设计-附源码171008
  13. Pinterest Copy to China——meterial collect
  14. Airdrop式社交:富友,你的airdrop没关
  15. 山东省淄博市谷歌高清卫星地图下载
  16. 近期整活之相关软件之安装说明
  17. ASP.NET 权限管理 页面静态化 OA系统培训 三层架构
  18. MinGW到底是个什么ghost
  19. 数据库连接的Persist Security Info参数说明
  20. 高校借助电子签章推动学生入网缴费凭证、科研项目拨款单在线签

热门文章

  1. 作业批改系统-毕业设计
  2. 谷得网诈骗 看了之后真的很震惊啊
  3. 灾难也是机遇,肺炎下的云办公股票暴涨!
  4. 支付系统中的对账处理
  5. TMS320F28388D 学习笔记1 建立工程
  6. nodejs 如何通过API 证书(权威CA颁发)下载敏感信息加密公钥证书?
  7. 数论之因子和与因子个数
  8. sql基础查询 多个字段查询——去除重复——计算列——起别名
  9. NLP-python3 translate()报错问题-TypeError: translate() takes exactly one argument (2 given)
  10. 防火墙技术之---ALG技术