主体
1.协议栈中包含host层和controller层,其例子是在应用层上加模拟心率的GATT。
2.host层由GAP GATT ATT SM L2CAP层组成,controller由LL层组成,因为nrf52832
相当于提供了基带射频硬件部分。因此keil中文件组成也大概按照这个组成的。
3.其中host层和controller层都是使用个大循环来回接受event之类的处理。例子中使
用rt-thread的消息队列来维持。
controller层事件处理大循环
controller层的事件处理大循环,先初始化一些东西,然后进入循环处理
ble_ll.c文件
/**
* Link Layer task.
*
* This is the task that runs the Link Layer.
*
* @param arg
*/
void
ble_ll_task(void *arg)
{
struct ble_npl_event *ev;
/*
* XXX RIOT ties event queue to a thread which initialized it so we need to
* create event queue in LL task, not in general init function. This can
* lead to some races between host and LL so for now let us have it as a
* hack for RIOT where races can be avoided by proper initialization inside
* package.
*/
#ifdef RIOT_VERSION
ble_npl_eventq_init(&g_ble_ll_data.ll_evq);
#endif
/* Init ble phy */
ble_phy_init();
/* Set output power to 1mW (0 dBm) */
ble_phy_txpwr_set(MYNEWT_VAL(BLE_LL_TX_PWR_DBM));
/* Tell the host that we are ready to receive packets */
ble_ll_hci_send_noop();
ble_ll_rand_start();
//
while (1) {
ev = ble_npl_eventq_get(&g_ble_ll_data.ll_evq, BLE_NPL_TIME_FOREVER);
assert(ev);
ble_npl_event_run(ev);
}
}
host层事件处理大循环
nimble_port_rtthread.c
host层事件处理大循环,前面有好几层函数调用。
void nimble_port_run(void)
{
struct ble_npl_event *ev;
while (1) {
ev = ble_npl_eventq_get(&g_eventq_dflt, BLE_NPL_TIME_FOREVER);
ble_npl_event_run(ev);
}
}
host层大循环启动过程
其是以一个任务的形式启动的,相当于一个现成吧。利用串口控制台ble_hr\r\n来
实现任务的启动,然后并进入任务的循环处理。其调用过程是:
1.串口控制台ble_hr来启动调用 ble_hr.c 的ble_hr();
2.ble_hs_thread_startup(); keil跳进去
3.ble_hs_thread_entry();
4.nimble_port_run();
而其事件循环处理是在其初始化过程中通过调用某些函数(函数指针是真牛逼),来弄
活整个协议栈循环。
host层与controller层实现消息队列通信的那几个指针函数是真不好。。。。。
。。。。。。。。。。。。。。。
消息队列传输的是个结构体指针,然后这个结构体里面有包含事件对应的回调。。。。。这些慢慢学。。。。
回调。。。。。。。,其维持一个消息队列来实现事件的处理,里面还有一些不同,主要
是对应host层与controller层之间的各种事件类型的通信,比如 host发送evet,然
后controller回应ack等等。
//那个结构体
struct ble_npl_event
{
bool queued;
ble_npl_event_fn *fn;
void *arg;
};
//事件处理大循环
void nimble_port_run(void)
{
struct ble_npl_event *ev;
while (1) {
ev = ble_npl_eventq_get(&g_eventq_dflt, BLE_NPL_TIME_FOREVER);
ble_npl_event_run(ev);
}
}
//其内部运行,感觉这就是那个回调。。。。
void ble_npl_event_run(struct ble_npl_event *ev)
{
ev->fn(ev);
}