再回到APP的任务框架几件重要事情的实现方法。
其一,add service.
{
int i;
if (!services[i]) {
services[i] = svc;
break;
}
}
}
从代码可以看出,仅仅是将Sevice的指针添加到数组中。但有系统服务发生时,APP会调用相关的函数,如connect发生时,会调用
{
int i;
ble_service_t *svc = services[i];
svc->connected_evt(svc, evt);
}
}
}
这时,如果对应服务存在而且有相应 处理函数时,会调用它。服务中的handle connect, read, write等事件的处理都是如此处理,这些处理函数的分派都会通过在App
的Task中会调用ble_service_handle_event来执行的。也保证也Service代码重用和独立。可以说是比较巧妙的。
其二,创建定时器。
先申明全局变量定时变量并在任务开始时创建定时器。定时器有回调函数
/* Timer used for battery monitoring */
PRIVILEGED_DATA static OS_TIMER bas_tim;
。。。。。。
/*
* Create timer for battery monitoring.
*/
bas_tim = OS_TIMER_CREATE("bas", OS_MS_2_TICKS(PX_REPORTER_BATTERY_CHECK_INTERVAL), true,
(void *) OS_GET_CURRENT_TASK(), bas_tim_cb);
有两点有意思的东西。第一,TimerID看来中以自定义,直接使用了任务的指针,相当于一个参数传递,在回调函数中可以使用。
第二,在回调函数中,没有直接处理定时器,我理解原因应该是回调函数是在Timer任务中调用的,任务优先级很高,不适合处理APP相关事情,所以定义了一个任务Notify bit,并在回调函数中向App的任务传递,将回调事宜将给App级别Task来处理。
定时器回调函数定义如下。
{
OS_TASK task = (OS_TASK) OS_TIMER_GET_TIMER_ID(timer);
}
#define BAS_TMO_NOTIF (1 << 3)
其三,任务循环。
整个任务循环都是围绕这个Notify来的。
/*
* Wait on any of the notification bits, then clear them all
*/
ret = OS_TASK_NOTIFY_WAIT(0, OS_TASK_NOTIFY_ALL_BITS, ¬if, OS_TASK_NOTIFY_FOREVER);
NOTIFY的BITS中,最低位(1<<0)默认是蓝牙相关Notify BLE_APP_NOTIFY_MASK,当有这个NOTIFY时,调用ble_service_handle_event处理各个Sevice相关工作。
其他BIT可以自定义。比如以上用到了当然Timer 回调的通知的处理。