用户工具

站点工具


cc2640r2f:application_architecture

差别

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

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
后一修订版 两侧同时换到之后的修订记录
cc2640r2f:application_architecture [2017/09/01 20:34]
long
cc2640r2f:application_architecture [2017/09/02 11:39]
long
行 60: 行 60:
 ### 介绍 ### ### 介绍 ###
  
-在<a href="..\..\cc2640r2f_architecture\software_and_hardware\software\software_architecture.html">软件架构</a>章节阐述了由于历史兼容原因会把整个应用工程区分 App 和 Stack 两个工程管理。因此,无法采用常规 API 调用和全局变量方式完成消息传递,App 和 Stack 之间的通信就需要重新考虑了。TI 引入了 ICALL 消息机制完成 App 和 Stack 独立工程管理的相互通信,接下来就着重理解原理和代码实现。+在<a href="http://docs.leconiot.com/doku.php?id=cc2640r2f:cc2640r2f_architecture:software_and_hardware:software:software_architecture">软件架构</a>章节阐述了由于历史兼容原因会把整个应用工程区分 App 和 Stack 两个工程管理。因此,无法采用常规 API 调用和全局变量方式完成消息传递,App 和 Stack 之间的通信就需要重新考虑了。TI 引入了 ICALL 消息机制完成 App 和 Stack 独立工程管理的相互通信,接下来就着重理解原理和代码实现。
  
 Indirect Call Framework (** ICall 消息框架**)是基于 TI-RTOS 提供服务(例如,同步线程、消息、事件)并完成 BLE 协议栈和应用程序在两个工程的消息交互的框架,它能够保证应用程序和协议栈在统一的 TI-RTOS 环境中完成高效运行、相互通信和资源共享。 Indirect Call Framework (** ICall 消息框架**)是基于 TI-RTOS 提供服务(例如,同步线程、消息、事件)并完成 BLE 协议栈和应用程序在两个工程的消息交互的框架,它能够保证应用程序和协议栈在统一的 TI-RTOS 环境中完成高效运行、相互通信和资源共享。
  
-ICall 架构的核心组件是其消息调度( dispatcher ),消息调度帮助程序在两个镜像/工程中完成 BLE5-Stack 协议栈以及库配置中应用程序交互。尽管大多数 ICall 交互在 BLE5-Stack API(例如 GAP,HCI 等)中已经被抽象化(已经被封装为消息原语函数),但是必须理解它们在 BLE-Stack 和多线程 RTOS 环境中正常运行的基础架构。+ICall 架构的核心组件是其消息调度( dispatcher ),消息调度帮助程序在两个 镜像/工程 中完成 BLE5-Stack 协议栈以及库配置中应用程序交互。尽管大多数 ICall 交互在 BLE5-Stack API(例如 GAP,HCI 等)中已经被抽象化(已经被封装为消息原语函数),但是还是需要理解它们在 BLE-Stack 和多线程 RTOS 环境中正常运行的基础架构。
  
 ** ICALL **源码在应用工程(例如本文的 simple_peripheral )的 ICALL BLE/ICALL 文件夹路径。 ** ICALL **源码在应用工程(例如本文的 simple_peripheral )的 ICALL BLE/ICALL 文件夹路径。
行 89: 行 89:
 ### ICALL 原语服务 ### ### ICALL 原语服务 ###
  
-ICALl 一系列的原语服务都被抽象成基于 RTOS 相关的函数接口。由于共享资源和线程之间的通信,应用程序必须使用以下 ICALL 原语服务功能:+ICALl 一系列的原语服务都被抽象成基于 RTOS 相关的函数接口。由于共享资源和线程之间的通信,应用程序必须使用以下 ICALL 原语服务功能:
  
 * 消息传递和线程同步 * 消息传递和线程同步
行 98: 行 98:
 ** ICall **同协议栈的消息传递和线程同步都是是基于 TI-RTOS 多线程。 ** ICall **同协议栈的消息传递和线程同步都是是基于 TI-RTOS 多线程。
  
-** ICall **个任务在消息队列发送一个阻塞消息时实现消息传递。发送方动态分配一段内存,将消息的内容写入内存,将这段内存发送(即排队)到接收线程,然后再使用事件标志。接受任务在收到事件标志后唤醒,复制内存消息并处理,之后再将这段内存块释放。+** ICall **通过一个任务在消息队列给另外一个任务发送一个阻塞消息时实现消息传递。发送方动态分配一段内存,将消息的内容写入内存,将这段内存发送(即排队)到接收线程,然后再使用事件标志。接受任务在收到事件标志后唤醒,复制内存消息并处理,之后再将这段内存块释放。
  
 协议栈使用 ICall 通知和发送消息到应用程序,ICall 传递这些服务消息,应用程序任务接收它然后处理。 协议栈使用 ICall 通知和发送消息到应用程序,ICall 传递这些服务消息,应用程序任务接收它然后处理。
行 108: 行 108:
 ### ICALL 初始化和注册 ### ### ICALL 初始化和注册 ###
  
-要实例和初始化 ICall 服务,应用程序必须在启动 TI-RTOS 内核调度程序之前调用 main()中的代码片段中的函数:+要实例和初始化 ICall 服务,应用程序必须在启动 TI-RTOS 内核调度程序之前调用 main()代码片段中的函数:
  
 使用 ICall 的必需代码。 使用 ICall 的必需代码。
行 114: 行 114:
 ```C ```C
 /* 初始化 ICall 模块 */  /* 初始化 ICall 模块 */ 
-ICall _init ();+ICall_init();
  
-/* 启动协议栈任务 - 优先级 */  +/* 协议栈作作为任务创建 */  
-ICall _createRemoteTasks ();+ICall _createRemoteTasks ();
 ``` ```
  
-调用 ICall_init()初始化 ICALL 原语服务(例如,堆管理)和框架,调用 ICall _createRemoteTasks()创建但不启动 BLE5-Stack 任务。在使用ICall 协议服务之前,服务器和客户端分别完成登记和注册。服务端在编译的时候就需要登记一个服务,登记函数使用一个全局的唯一标识符区分每个服务并作为通信地址。例如,BLE协议使用 `ICALL_SERVICE_CLASS_BLE` 做些蓝牙协议栈 ICALL的消息交互的标识。+调用 ICall_init()初始化 ICALL 原语服务(例如,初始化堆管理)和框架,调用 ICall _createRemoteTasks()创建但不启动 BLE5-Stack 任务。在使用ICall 协议服务之前,服务器和客户端分别完成登记和注册。服务端在编译的时候就需要登记一个服务,登记函数使用一个全局的唯一标识符区分每个服务并作为通信地址。例如,BLE协议使用 `ICALL_SERVICE_CLASS_BLE` 做些蓝牙协议栈 ICALL的消息交互的标识。
  
 服务端的登记在 `osal_icall_ble.c` 文件: 服务端的登记在 `osal_icall_ble.c` 文件:
行 131: 行 131:
 客户端在 ICALL 调度程序发送和/或接收消息之前需要注册。 客户端在 ICALL 调度程序发送和/或接收消息之前需要注册。
  
-对于使用 BLE5API的客户端(例如应用程序任务),客户端必须首先向ICall注册其任务 。该注册通常发生在应用程序的任务初始化功能中。下面的代码片段是 `simple_peripheral_init` 在 simple_peripheral.c 中注册。+对于使用 BLE5 的客户端(例如这里的应用程序任务),客户端必须首先向ICall注册其任务 。该注册通常发生在应用程序的任务初始化功能中。下面的代码片段是 `simple_peripheral_init` 在 simple_peripheral.c 中注册。
  
 ```C ```C
 //ICALL客户端注册 //ICALL客户端注册
-ICall _registerApp (&selfEntity ,syncEvent +ICall _registerApp (&selfEntity ,&syncEvent)
 ``` ```
 完成客户端注册前需要传入结构体变量 `selfEntity` 和 `syncEvent` ,其值在函数返回时被初始化,服务端通过这两个变量来进行消息传递。`syncEvent` 参数表示事件标识,`selfEntity` 表示处理消息的目的任务,也是客户端实体以后通信的源地址。每个注册 ICALL 的客户端都需要使用唯一的 `syncEvent` 和`selfEntity` 。 完成客户端注册前需要传入结构体变量 `selfEntity` 和 `syncEvent` ,其值在函数返回时被初始化,服务端通过这两个变量来进行消息传递。`syncEvent` 参数表示事件标识,`selfEntity` 表示处理消息的目的任务,也是客户端实体以后通信的源地址。每个注册 ICALL 的客户端都需要使用唯一的 `syncEvent` 和`selfEntity` 。
行 151: 行 151:
 ``` ```
  
-`handle` 是构造的 Event_Handle 句柄(标识符)。+`handle` 是构造的 Event_Handle 事件句柄(标识符)。
 `andMask` 和 `orMask` 为用户选择要阻塞/挂起的事件标志。 `andMask` 和 `orMask` 为用户选择要阻塞/挂起的事件标志。
-`timeout` 是以毫秒为单位的超时周期。如果在此超时时间范围内后尚未返回,该函数将返回。+`timeout` 是以毫秒为单位的超时周期。如果在此超时时间范围内后事件尚未被Post,该函数将返回。
 `Event_pend` 函数表示阻塞当前任务等待某一事件标志位发生。 `Event_pend` 函数表示阻塞当前任务等待某一事件标志位发生。
  
行 166: 行 166:
 ``` ```
  
-以上的事件句柄 `handle` 由服务端 ICall _enrollService()和 ICall _registerApp()调用后获得。+以上的事件句柄 `handle` 由服务端 ICall _enrollService()和 ICall _registerApp()调用后获得。
  
 > **危险**:  不要从协议栈回调中调用 ICall 函数,此操作可能导致 ICall 中止(使用 ICall_abort())并中断系统。 > **危险**:  不要从协议栈回调中调用 ICall 函数,此操作可能导致 ICall 中止(使用 ICall_abort())并中断系统。
行 183: 行 183:
  
 ![ ICall 消息传递示例](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/IcallBlcok.png) ![ ICall 消息传递示例](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/app/Images/IcallBlcok.png)
 +
 +通过以上理论知识储备,我们实际出发思考并解决以下问题:
  
 ### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ### ### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ###
行 225: 行 227:
 * 任务实体 * 任务实体
  
-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
行 368: 行 370:
 ### 应用程序初始化功能 ### ### 应用程序初始化功能 ###
  
-<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 任务函数伪代码
cc2640r2f/application_architecture.txt · 最后更改: 2021/06/22 23:14 (外部编辑)