用户工具

站点工具


cc2640r2f:application_architecture

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
cc2640r2f:application_architecture [2017/09/01 21:21]
long
cc2640r2f:application_architecture [2019/08/29 19:55]
jaylee ↷ 页面cc2640r2f:ble_stack_app:app:application_architecture被移动至cc2640r2f:application_architecture
行 3: 行 3:
 # 应用程序 # # 应用程序 #
  
-本章节将详细讲解 CC2640R2F BLE5.0 的应用程序框架,我们希望您已经按照学习线路图储备了<a href ="http://docs.leconiot.com/doku.php?id=cc2640r2f:cc2640r2f_architecture:software_and_hardware:overview:overview"> CC2640R2F平台的软硬件架构知识 </a>,明白应用工程区分App 和 Stack 工程管理。 +本章节将详细讲解 CC2640R2F BLE5.0 的应用程序框架,我们希望您已经按照学习线路图储备了<a href ="http://docs.leconiot.com/doku.php?id=cc2640r2f:cc2640r2f_architecture:software_and_hardware:overview:overview"> CC2640R2F平台的软硬件架构知识 </a>,明白应用工程区分 App 和 Stack 工程管理。 
-本章主要内容是围绕 TI-RTOS 的 App 应用程序框架。+本章主要内容是围绕基于 TI-RTOS 的 App 应用程序框架。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/image43.jpeg) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/image43.jpeg)
 +
 +图1. 应用程序框架图
  
 以 simple_peripheral Demo 应用程序部分为例,包括以下内容: 以 simple_peripheral Demo 应用程序部分为例,包括以下内容:
行 68: 行 70:
 ** ICALL **源码在应用工程(例如本文的 simple_peripheral )的 ICALL BLE/ICALL 文件夹路径。 ** ICALL **源码在应用工程(例如本文的 simple_peripheral )的 ICALL BLE/ICALL 文件夹路径。
  
-![ICall 应用-协议栈 抽象](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/image68.jpeg)+![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/image68.jpeg) 
 + 
 +图2. ICall 应用-协议栈 抽象
  
 ### ICall BLE5 协议栈服务端 ### ### ICall BLE5 协议栈服务端 ###
  
-图所示,** ICALL **实现包含一个客户端实体(例如我们的应用程序)和一个服务器实体(即这里的 BLE5.0 协议栈)之间的通信。+如图 所示,** ICALL **实现包含一个客户端实体(例如我们的应用程序)和一个服务器实体(即这里的 BLE5.0 协议栈)之间的通信。
  
 > **注意** :正确区分** ICALL **框架的 CS 架构以及 GATT 服务器和客户端的架构,后者主要由 BLE 协议栈所定义实现。 > **注意** :正确区分** ICALL **框架的 CS 架构以及 GATT 服务器和客户端的架构,后者主要由 BLE 协议栈所定义实现。
行 172: 行 176:
 ### 示例 ICall 用法 ### ### 示例 ICall 用法 ###
  
-图显示了一个通过 ICall 框架从应用程序发送到 BLE5-Stack 的示例命令,并将相应的返回值传回给应用程序。+图 显示了一个通过 ICall 框架从应用程序发送到 BLE5-Stack 的示例命令,并将相应的返回值传回给应用程序。
  
 ICall _init()完成初始化 ICall 模块实例,ICall_createRemoteTasks()使用已知地址的入口函数为协议栈创建任务。 ICall _init()完成初始化 ICall 模块实例,ICall_createRemoteTasks()使用已知地址的入口函数为协议栈创建任务。
行 182: 行 186:
 协议命令不在应用程序的线程中执行,而是封装在ICall消息中执行,是由 ICall 框架发送到 BLE5-Stack 任务。该命令被发送到 ICALL 调度程序,它在 BLE5-Stack 上下文中调度和执行;同时应用程序线程阻塞,直到接收到相应的命令状态消息;BLE5-Stack 完成执行命令,然后通过 ICall 将命令状态消息响应发送回应用程序线程。这种交换的示例图如下所示。 协议命令不在应用程序的线程中执行,而是封装在ICall消息中执行,是由 ICall 框架发送到 BLE5-Stack 任务。该命令被发送到 ICALL 调度程序,它在 BLE5-Stack 上下文中调度和执行;同时应用程序线程阻塞,直到接收到相应的命令状态消息;BLE5-Stack 完成执行命令,然后通过 ICall 将命令状态消息响应发送回应用程序线程。这种交换的示例图如下所示。
  
-![ ICall 消息传递示例](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/IcallBlcok.png)+![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/IcallBlcok.png)
  
-通过以上理论知识储备,我们实际出发思考并解决以下问题:+图3. ICall 消息传递示例 
 + 
 +有了以上理论知识储备,我们尝试解决以下问题:
  
 ### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ### ### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ###
行 227: 行 233:
 * 任务实体 * 任务实体
  
-arg0 的参数地址要区分工程编译选项,这点已经在<a href ="..\..\cc2640r2f_architecture\software_and_hardware\software\software_architecture.html">软件架构</a>章节详细讲解过。`FlashROM_StackLirary` 链接的编译在静态库中的 `startup_entry` 函数中。+arg0 的参数地址要区分工程编译选项,这点已经在<a href ="http://docs.leconiot.com/doku.php?id=cc2640r2f:cc2640r2f_architecture:software_and_hardware:software:software_architecture">软件架构</a>章节详细讲解过。`FlashROM_StackLirary` 链接的编译在静态库中的 `startup_entry` 函数中。
  
 ```C ```C
行 343: 行 349:
 ### 如何调试协议栈任务 ### ### 如何调试协议栈任务 ###
  
-因为协议栈任务分布在另外一个工程,所以没有向原来那样直接加断点调试。经过前面的学习,我们已经了解协议栈是如何作为一个任务在应用工程中启动的,找到协议任务入口地址就是调试协议栈任务的关键+因为协议栈任务分布在另外一个工程,所以没有向原来那样直接加断点调试。已经了解协议栈是如何作为一个任务在应用工程中启动的,那么调试协议栈任务的关键是找到协议任务入口地址。
 在调试协议栈任务之前,建议将分别设置协议栈和应用工程优化等级 Project -> Opitons -> C/C++ Compiler Optimizations -> Level -> None 为无,这对正常调试协议栈任务至关重要。 在调试协议栈任务之前,建议将分别设置协议栈和应用工程优化等级 Project -> Opitons -> C/C++ Compiler Optimizations -> Level -> None 为无,这对正常调试协议栈任务至关重要。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/Opitimaizations.jpg) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/Opitimaizations.jpg)
 +
 +图4 .设置优化等级
  
 `FlashROM` 编译选项的协议栈任务入口地址在 `iar_boundary.xcl` 中给出,对于 `FlashROM_StackLibrary` 编译选项,可以通过编译生成的 *.map 文件查找`startup_entry` 符号从而找到入口地址。 `FlashROM` 编译选项的协议栈任务入口地址在 `iar_boundary.xcl` 中给出,对于 `FlashROM_StackLibrary` 编译选项,可以通过编译生成的 *.map 文件查找`startup_entry` 符号从而找到入口地址。
行 352: 行 360:
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/FlashRomEntry.jpg) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/FlashRomEntry.jpg)
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/LibEntry.jpg) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/LibEntry.jpg)
 +
 +图5 .找到入口地址
  
 拿到协议栈任务的入口地址后,就可以在汇编窗口 View -> Disassembly 直接输入该地址,然后加上断点,等待协议栈任务创建后运行,从而跳转到协议栈工程进行调试。 拿到协议栈任务的入口地址后,就可以在汇编窗口 View -> Disassembly 直接输入该地址,然后加上断点,等待协议栈任务创建后运行,从而跳转到协议栈工程进行调试。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/DisassemblyWindow.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/DisassemblyWindow.png)
 +
 +图6 .如何用协议栈工程进行调试
  
 如果不知道协议栈任务的入口地址,则直接通过创建协议栈任务的任务实体入口,跳转到 `ICall_taskEntry` -> `entryfn` ,然后按** F11 **进入协议栈任务调试。 如果不知道协议栈任务的入口地址,则直接通过创建协议栈任务的任务实体入口,跳转到 `ICall_taskEntry` -> `entryfn` ,然后按** F11 **进入协议栈任务调试。
  
 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/EntryFn.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/EntryFn.png)
 +
 +图7 .如何进入协议栈任务调试
  
 >**注意**:这里 F11 Step Into 可能会优化选项跳转失败,所以建议关闭优化选项或者直接到聚焦到汇编窗口 BX R2 F11 跳转。 >**注意**:这里 F11 Step Into 可能会优化选项跳转失败,所以建议关闭优化选项或者直接到聚焦到汇编窗口 BX R2 F11 跳转。
行 370: 行 384:
 ### 应用程序初始化功能 ### ### 应用程序初始化功能 ###
  
-<a href="..\..\cc2640r2f_architecture\ti_rtos\tirtos_overivew.html"> TI-RTOS 概述</a>详细介绍如何了任务构建。构建任务并启动 SYS / BIOS 内核调度程序后,构造过程中传递的函数会在任务准备就绪时运行(例如 SimpleBLEPeripheral_taskFxn )。任务实体函数运行前这里会先运行任务初始化。+<a href="http://docs.leconiot.com/doku.php?id=cc2640r2f:cc2640r2f_architecture:ti_rtos:tirtos_overivew"> TI-RTOS 概述</a>详细介绍了任务构建。构建任务并启动 SYS / BIOS 内核调度程序后,构造过程中传递的函数会在任务准备就绪时运行(例如 SimpleBLEPeripheral_taskFxn )。任务实体函数运行前这里会先运行任务初始化。
  
 simple_peripheral 任务函数伪代码 simple_peripheral 任务函数伪代码
行 467: 行 481:
 当为一个事件选择一个事件值的时候,该值对于给定的任务必须是唯一的,并且必须是 2 的幂(只有 1 bit 被设置为 1 )。这样做的原因是 `pEvt->event` 变量被初始化为 `uint16_t` 类型,也就是最多运行允许 16 个事件。有一个不能使用的事件值是已经用于 BLE5-Stack OSAL 全局事件( bcomdef.h 中所述)的事件值。 当为一个事件选择一个事件值的时候,该值对于给定的任务必须是唯一的,并且必须是 2 的幂(只有 1 bit 被设置为 1 )。这样做的原因是 `pEvt->event` 变量被初始化为 `uint16_t` 类型,也就是最多运行允许 16 个事件。有一个不能使用的事件值是已经用于 BLE5-Stack OSAL 全局事件( bcomdef.h 中所述)的事件值。
  
-清单49. BLE OSAL事件在 bcomdef.h 中定义。+清单1. BLE OSAL事件在 bcomdef.h 中定义。
  
 ```C ```C
cc2640r2f/application_architecture.txt · 最后更改: 2021/06/22 23:14 (外部编辑)