goal可以理解为一个模型(可以类比linux的驱动模型),这个模型(代码中的体现为procedure_fns_t)中包含了两个操作:start,cancel。 猜测这样做的目的是,可以使上层只以目标为导向,不用关心底层实现,这样上层的逻辑会更加清晰。 定义了这样一个模型之后,也有更多的组合使用方式,可以单独使用,也可以将有相关性的模型进行组合形成一个SCRIPT。相关性可以举个例子类比:比如进配对的时候实际上是开启可连接和可发现,将这两个模型组合成一个script,在我们进配对的时候只需要调一个脚本,就同时实现了可连接和可发现功能,简化上层逻辑。估计这就是为什么会衍生script的原因了。 将一些单个模型与script放到一起进行管理,最终也就出现了goal_entry_t,一个goal集合的实体。目前sdk中共有两个goal的实体,分别定义在tws_topology_goals.c与headset_topology_goals.c中
const goal_entry_t goals [] ={...}
下面我们以FindRole start的goal流程举例说明
(注:由于SDK在持续更新,所以有些接口可能会有些变化,所以仅供参考)
RULE(TWSTOP_RULE_EVENT_STATIC_HANDOVER_FAILED, ruleTwsTopTwmPriFindRole, TWSTOP_PRIMARY_GOAL_FIND_ROLE) RULE(TWSTOP_RULE_EVENT_OUT_CASE, ruleTwsTopTwmPriFindRole, TWSTOP_PRIMARY_GOAL_FIND_ROLE), TWSTOP_PRIMARY_GOAL_FIND_ROLE GoalsEngine_ActivateGoal(tws_topology_goal_find_role) goalsEngine_StartGoal goal_entry->proc_fns->proc_start_fn(proc_result_task, proc_start_cfm_fn, proc_complete_cfm_fn, goal_data) TwsTopology_ProcedureFindRoleStart根据GoalsEngine_ActivateGoal的参数tws_topology_goal_find_role我们可以在goal entry中定位到具体的模型为proc_find_role_fns
/*tws_topology_goals.c*/ const goal_entry_t goals[] = { ... GOAL(tws_topology_goal_find_role, tws_topology_procedure_find_role, &proc_find_role_fns, tws_topology_goal_none), ... }由于是start,根据proc_find_role_fns的实现,所以最终调用的就是TwsTopology_ProcedureFindRoleStart函数了
const procedure_fns_t proc_find_role_fns = { TwsTopology_ProcedureFindRoleStart, TwsTopology_ProcedureFindRoleCancel, };这里也简单说明一下gaol_entry_t结构体成员的意义,便于理解
typedef struct { /*! 要执行的goal的id号.见tws_topology_goal_id与headset_topology_goal_id_t */ procedure_id proc; /*! 当加入新goal时,该如何处理与已经运行的goal的竞争关系 */ goal_contention_t contention; /*! 该参数指定的goal与将要运行的goal为互斥关系,所以运行新goal时,立即取消改参数指定的goal */ goal_id exclusive_goal; /*! 当goal成功执行之后,将要发送的系统事件(EVENT) */ rule_events_t success_event; /*! 当goal由于超时导致的失败时,将要发送的系统事件(EVENT) */ rule_events_t timeout_event; /*! 当 goal未成功执行时,将要发送的系统事件(EVENT)*/ rule_events_t failed_event; /*! goal指向的函数指针数组实体(通常为start+cancel函数) */ const procedure_fns_t* proc_fns; /*! goal脚本指针,指向一个脚本实体. */ const procedure_script_t* proc_script; /*! 参数为mask,指明那些goal可与当前的goal并行 */ const goal_id* concurrent_goals; } goal_entry_t;最后这里对一些goal entry中的一些宏定义简单做一下说明,方便理解
/*运行procedure_fns_t指向的start函数*/ #define GOAL ... /*运行procedure_fns_t指向的start函数,能与其他goal并行*/ #define GOAL_WITH_CONCURRENCY ... /*运行procedure_fns_t指向的start函数,能与其他goal并行,成功发送预定义的event*/ #define GOAL_WITH_CONCURRENCY_SUCCESS ... /*运行procedure_fns_t指向的start函数,失败或者超时分别发送预定义的event*/ #define GOAL_WITH_TIMEOUT_AND_FAIL ... /*运行procedure_fns_t指向的start函数,能与其他goal并行,超时发送预定义的event*/ #define GOAL_WITH_CONCURRENCY_TIMEOUT ... /*运行procedure_fns_t指向的start函数,成功发送预定义的event*/ #define GOAL_SUCCESS ... /*运行procedure_fns_t指向的cancel函数*/ #define GOAL_CANCEL ... /*脚本goal,实际上是procedure_fns_t数组,运行脚本的时候,将每个数组中procedure_fns_t指向的start(目前有两类:start和cancel)函数运行一遍*/ #define SCRIPT_GOAL ... /*运行脚本,成功发送预定义的event*/ #define SCRIPT_GOAL_SUCCESS ... /*取消现有脚本,取消成功之后运行新脚本,成功发送预定义的event*/ #define SCRIPT_GOAL_CANCEL_SUCCESS ... /*运行脚本,超时或者失败分别发送预定义的event*/ #define SCRIPT_GOAL_TIMEOUT_FAILED ... /*取消现有脚本,取消成功之后运行新脚本,成功或者失败分别发送预定义的event*/ #define SCRIPT_GOAL_CANCEL_SUCCESS_FAILED ... /*运行脚本,成功、超时或者失败分别发送预定义的event*/ #define SCRIPT_GOAL_SUCCESS_TIMEOUT_FAILED ... /*取消现有脚本,取消成功之后运行新脚本,成功、超时或者失败分别发送预定义的event*/ #define SCRIPT_GOAL_CANCEL_SUCCESS_TIMEOUT_FAILED ... /*取消现有脚本,取消成功之后运行新脚本,失败发送预定义的event*/ #define SCRIPT_GOAL_CANCEL_FAILED ... /*运行脚本,超时发送预定义的event*/ #define SCRIPT_GOAL_TIMEOUT ... /*与SCRIPT_GOAL相反,数组中的所有cancel函数运行一遍*/ #define SCRIPT_GOAL_CANCEL ... /*取消现有脚本,取消成功之后运行新脚本,失败或者超时分别发送预定义的event*/ #define SCRIPT_GOAL_CANCEL_TIMEOUT_FAILED ...
相关的工具资料等,请到我的博客<qcc514x_qcc304x开发调试笔记>最下面的网盘链接中下载。