这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 后一修订版 两侧同时换到之后的修订记录 | ||
cc2640r2f:application_architecture [2017/09/01 20:34] long |
cc2640r2f:application_architecture [2017/09/02 11:39] long |
||
---|---|---|---|
行 60: | 行 60: | ||
### 介绍 ### | ### 介绍 ### | ||
- | 在<a href=" | + | 在<a href="http://docs.leconiot.com/doku.php? |
Indirect Call Framework (** ICall 消息框架**)是基于 TI-RTOS 提供服务(例如,同步线程、消息、事件)并完成 BLE 协议栈和应用程序在两个工程的消息交互的框架,它能够保证应用程序和协议栈在统一的 TI-RTOS 环境中完成高效运行、相互通信和资源共享。 | Indirect Call Framework (** ICall 消息框架**)是基于 TI-RTOS 提供服务(例如,同步线程、消息、事件)并完成 BLE 协议栈和应用程序在两个工程的消息交互的框架,它能够保证应用程序和协议栈在统一的 TI-RTOS 环境中完成高效运行、相互通信和资源共享。 | ||
- | ICall 架构的核心组件是其消息调度( dispatcher ),消息调度的帮助程序在两个镜像/ | + | ICall 架构的核心组件是其消息调度( dispatcher ),消息调度帮助程序在两个 镜像/ |
** 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 调度程序发送和/ | ||
- | 对于使用 | + | 对于使用 |
```C | ```C | ||
// | // | ||
- | ICall _registerApp | + | ICall _registerApp |
``` | ``` | ||
完成客户端注册前需要传入结构体变量 `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()调用后获得。 |
> **危险**: | > **危险**: | ||
行 183: | 行 183: | ||
![ ICall 消息传递示例](http:// | ![ ICall 消息传递示例](http:// | ||
+ | |||
+ | 通过以上理论知识储备,我们实际出发思考并解决以下问题: | ||
### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ### | ### BLE-Stack 工程是如何作为 App 中 TI-RTOS 的一个任务运行的 ### | ||
行 225: | 行 227: | ||
* 任务实体 | * 任务实体 | ||
- | arg0 的参数地址要区分工程编译选项,这点已经在< | + | arg0 的参数地址要区分工程编译选项,这点已经在< |
```C | ```C | ||
行 368: | 行 370: | ||
### 应用程序初始化功能 ### | ### 应用程序初始化功能 ### | ||
- | <a href=" | + | <a href="http://docs.leconiot.com/doku.php? |
simple_peripheral 任务函数伪代码 | simple_peripheral 任务函数伪代码 |