文档描述有五个:
第一个 rtos的简单描述和使用。 第二个 2640的运行方式 第三个 低功耗蓝牙协议
第四个 从机的广播,收发profile。 第五个 主机的查询收发流程。
第一个rtos的简单描述和使用
关于rtos的简单描述:
第一;关于任务的开始。参考以下的一个任务开始:
Task_Params_init(&taskParams); taskParams.stack = sbcTaskStack; ①
taskParams.stackSize = SBC_TASK_STACK_SIZE;② taskParams.priority = SBC_TASK_PRIORITY;③
Task_construct(&sbcTask, SimpleBLECentral_taskFxn, &taskParams, NULL);④ 以上
①就是这个任务的栈空间。栈是用于给该任务一系列函数,子函数分配动态变量用的。他的表现形式就是一个数组。比如:Char sbcTaskStack[SBC_TASK_STACK_SIZE];
②就是代表这个栈允许的全部的局部变量的大小。如果局部变量的申请比实际的允许的空间还要大,那么分分钟就
是一个无解的死机。
③是这个任务的优先权。优先权越高,那么自动占有cpu资源的权限就越高。特别注意的是优先权的资源要及时释放。否则会导致优先权低的任务一直得不到cpu运行的资源。
第二;关于任务的通信与等待。
如果任务没有特别的事情。我们就让他保持沉睡的状态,pend。以下是让他保持沉睡状态的接口:
Queue_empty(appMsgQueue)msg队列的等待。 Semaphore_PendState 信号等待
ICall_wait(ICALL_TIMEOUT_FOREVER); 这个是蓝牙协议栈的接口。实质上里面的是一个信号或者队列
从沉睡状态变成运行状态,需要一个外部任务或者中断服务的信号或者通知。比如: Semaphore_post(sem);致位一个信号 Queue_insert;插入一个消息
还有rtos_timer_delay(2)实现一个软件延时。也可以让当前运行任务释放cpu资源。
2640的运行方式
第一个,是关于gap_role与simple的关系。
Gap_role的作用就是把一些无关紧要,或者我们不需要的蓝牙协议栈的消息,过滤掉。 ICall_wait(ICALL_TIMEOUT_FOREVER);这个是所有的蓝牙消息的发起点。 参考代码:
// Pass event to app 把经过我们洗选的消息发送到app
if (pGapCentralRoleCB && pGapCentralRoleCB->eventCB) {
return (pGapCentralRoleCB->eventCB((gapCentralRoleEvent_t *)pMsg)); }
其中:下面这个就是废掉无用的消息。 if (pMsg && safeToDealloc) {
ICall_freeMsg(pMsg); }
第二个,关于ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg) 与Queue_empty(appMsgQueue) simple应用里面这两个个流程里面的区分。
㈠ICall_fetchServiceMsg(&src, &dest, (void **)&pMsg)实质上就是Gap_role过滤后的一些蓝牙协议栈的消息。以下为案例: if (ICall_fetchServiceMsg(&src, &dest,
(void **)&pMsg) == ICALL_ERRNO_SUCCESS) {
if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) {
// Process inter-task message
SimpleBLECentral_processStackMsg((ICall_Hdr *)pMsg); }
if (pMsg) {
ICall_freeMsg(pMsg); } }
SimpleBLECentral_processStackMsg((ICall_Hdr *)pMsg)是对蓝牙协议栈的消息进行的分派与响应。按照GAP_MSG_EVENT,GATT_MSG_EVENT ,HCI_GAP_EVENT_EVENT等不一样的消息进行处理。其中在GATT_MSG_EVENT 下面的ATT_HANDLE_VALUE_NOTI,就是主从机通信的重要的信息。GAP_MSG_EVENT里面的GAP_DEVICE_INFO_EVENT对应从机信息,GAP_LINK_ESTABLISHED_EVENT建立连接信息等等。
㈡Queue_empty更多的是在Gap_role里面发送过来的蓝牙协议信息: 一般我们在simple里面先向Gap_role注册一个回b比如: GAPCentralRole_StartDevice(&SimpleBLECentral_roleCB);
Gap_role收到蓝牙信息后,通过回调,通知simple,形成一个有意思的分工。从而产生一系列的消息队列。
if (pGapCentralRoleCB && pGapCentralRoleCB->eventCB) {
return (pGapCentralRoleCB->eventCB((gapCentralRoleEvent_t *)pMsg)); }
第三个:Util_constructClock时钟信息。
时钟信号是系统提供给我们一个非常有意义的接口。当一定的时间达到,就发一个我们指定的事件,让我们在任务里面进行对应的运作。
Util_constructClock(&startDiscClock, SimpleBLECentral_startDiscHandler,
DEFAULT_SVC_DISCOVERY_DELAY, 0, false, SBC_START_DISCOVERY_EVT); startDiscClock是一个标准的Clock_Struct结构体。用于给系统装载时间信息。
SimpleBLECentral_startDiscHandler则是时间到了,给系统的回调,在这个回调里面我们设定信号。让pend的任务运行起来。
DEFAULT_SVC_DISCOVERY_DELAY是时间的delay。
SBC_START_DISCOVERY_EVT则是给系统的回调时,由系统发送过来的事件标签。
以上是2640整个的运作方式,与架构。主要是蓝牙消息,自己定义消息的一个事件响应系统。希望大家加深理解。并完全掌握。另外,中断服务我没有做测试。大家自己要把中断服务搞下来。
低功耗蓝牙协议
第一个,关于gap与gatt。Gap与gatt在蓝牙协议里面的层级都是平级的。但大家分管不一样的事情。 GAP 一共有四种角色:Broadcaster ,Observer,Peripheral ,Central
在这四种角色中他实质做的事情就是广播,发现广播,建立连接,定时询查的行为。
.先经过GAP协议,再有GATT协议连接(GATT协议定义了service和 Characteristic 两个东西在进行通信。)
第二个关于gatt的通信。Gatt务必要有至少一个服务。服务里面有UUID,通过UUID判断各种服务。
服务下就有不同的特征,进行数据的传输。传输的大小目前据了解只能是20byte。别问我为什么,这个是“共产党”定的。一个包含完整的service和多个characteristic就是我们平时说的GATT profile。
第三个,关于广播定制。自己看代码,就是定时给外部发广播包。
// GAP - SCAN RSP data (max size = 31 bytes) static uint8_t deviceName[7] = {
// complete name
1+5, // length of first data structure (11 bytes excluding length byte) 0x09, // AD Type = Complete local name 'M', // M 'y', // y 'T', // T 'a', // a 'g' // g };
// GAP - Advertisement data (max size = 31 bytes, though this is // best kept short to conserve power while advertisting) static uint8_t advertData[7] = {
0x02, // length of first data structure (2 bytes excluding length byte) GAP_ADTYPE_FLAGS, // AD Type = Flags
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included // in this peripheral
0x03, // length of second data structure (7 bytes excluding length byte)
GAP_ADTYPE_16BIT_MORE, // list of 16-bit UUID's available, but not complete list LO_UINT16( PROXIMITY_SERVICE_UUID ), // PROXIMITY_SERVICE_UUID (Proximity Profile) HI_UINT16( PROXIMITY_SERVICE_UUID ) };
第四个:profile就是一个服务(service)+好多个特征(char)的集合。
别问为什么,共产党定的。
从机的广播,收发profile
流程:广播-》被发现-》建立连接-》使用profile接收发送数据
第一, 关于目前公司用的profile的文档关系。
Proxreporter 是经过我们修改后的一个profile组件,可以直接发送接收数据。 Proxreporter.c 是基于gattservapp_util.c+gatt_uuid.c。
第二, Proxreporter这个profile的说明: