char *初始化_02蓝牙外设初始化

说明:

1、蓝牙协议栈版本:1.5.1.1

2、蓝牙IC:CC2540或者CC2541

3、IDE版本:IAR For 8051 10.20.1

4、采用截图的方式,将整个实验过程还原出来,附带行号,便于学习的小伙伴们能依据图文完全重复实验结果。

本文目标:弄清楚广播前的初始化。

正文:

1、了解OSAL:

OSAL直译就是操作系统抽象层。它是一个类操作系统的事件驱动型软件框架。每建立一个任务,都会分配一个唯一任务ID,同时对应一个任务事件处理函数,用来处理不同的事件。然后不断地轮询每个任务,判断其是否有事件需要处理,如此往复。

建立任务,如加粗的SimpleBLEPeripheral_Init( taskID )就是官方例程建立的一个Demo应用任务,该初始化在文件OSAL_SimpleBLEPeripheral.c中:

void osalInitTasks( void )

{

uint8 taskID = 0;

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

if (tasksEvents != NULL)

{

osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

}

else

{

HAL_ASSERT_FORCED();

}

LL_Init( taskID++ );

Hal_Init( taskID++ );

HCI_Init( taskID++ );

#if defined ( OSAL_CBTIMER_NUM_TASKS )

osal_CbTimerInit( taskID );

taskID += OSAL_CBTIMER_NUM_TASKS;

#endif

L2CAP_Init( taskID++ );

GAP_Init( taskID++ );

SM_Init( taskID++ );

GATT_Init( taskID++ );

GAPRole_Init( taskID++ );

GAPBondMgr_Init( taskID++ );

GATTServApp_Init( taskID++ );

SimpleBLEPeripheral_Init( taskID );

}

以上任务集对应一个事件处理函数表,该表中存放的是事件处理函数指针:

bd89860a8f7078ba24d0ed577218495c.png

图1(操作文件:OSAL_SimpleBLEPeripheral.c)

2、关注(暂时)两个初始化

8ade63a81e50d1eb854d241c5417c2e7.png

图2(操作文件:OSAL_SimpleBLEPeripheral.c)

在GAPRole_Init()中会确定gap角色状态为初始态,gap角色为外设等

4b3b713fbf8297d9494f855f15285c07.png

图3(操作文件:peripheral.c)

而在SimpleBLEPeripheral_Init()中则进行各种参数的初始化,详见源码。

3、关注(暂时)两个任务(由OSAL调度执行)

47f4e1c81c15ee76670f8069c9f3af3e.png

图4(操作文件:OSAL_SimpleBLEPeripheral.c)

这两个任务(所有任务都是)是轮询执行的,OSAL一直在轮询所有的任务,查看是否有需要处理的事件。先说第二个任务SimpleBLEPeripheral_ProcessEvent,这是个OSAL调度任务,会随着系统的运行,不断地产生各类事件来触发不同的执行流程。在外设初始化SimpleBLEPeripheral_Init()的最后会触发启动设备事件,如下图:

e48a1da060a573d9311dd3a3eb1c0afd.png

图5(操作文件:simpleBLEPeripheral.c)

于是在SimpleBLEPeripheral_ProcessEvent()中进行了如下处理:

d57d12fc0fb2aab4c7d953a2b903602e.png

图6(操作文件:simpleBLEPeripheral.c)

即启动设备,启动绑定管理,设置周期运行事件。而设备一旦启动,就执行各类初始化动作,当初始化完成时就会产生SYS_EVENT_MSG事件,并通知OSAL进行相关处理,这就引出了第一个任务GAPRole_ProcessEvent,如下:

f37ba4e304f782a653ae4a4fb9a6f084.png

图7(操作文件:peripheral.c)

调用函数gapRole_ProcessOSALMsg()处理消息:

c02db5da7def3dc02c99ff30eccf04a4.png

图8(操作文件:peripheral.c)

再调用函数gapRole_ProcessGAPMsg()处理gap消息:

0b0666a6d9b71520b26fc4550905c157.png

图9(操作文件:peripheral.c)

至此,设备初始化完成,保存密钥、设备地址,并更新广播数据。GAP状态变为GAPROLE_STARTED,触发回调函数peripheralStateNotificationCB(),显示本机地址以及初始化完成标识:

8c92d82611ee5c184cd112d17b14f35b.png

图10(操作文件:simpleBLEPeripheral.c)

4、输出提示信息

由于官方例程用LCD进行输出显示,为了学习的各位小伙伴们能更加简单地学习,我们之后的所有实验测试都是基于串口来实现的,这样只要你有个蓝牙模块就可以实现所有我们讲述的例程。

在不改变源码结构的基础上,我们来实现串口输出提示信息。首先在hal_lcd.c中加入引用串口的头文件:

bce076c1c3e4b43a961a8fc84600e6e4.png

图11(操作文件:hal_lcd.c)

接着,修改LCD显示字符串函数void HalLcdWriteString ( char *str, uint8 option),在该函数最后添加串口输出函数:

6f1d69b4ae9ab70817ab40c8e66b52f8.png

图12(操作文件:hal_lcd.c)

5、编译下载

014f2c2ba92672a5bb0bf5892164265d.png

图13(实验结果)

6、扩展说明:

GAP: Generic Access Profile,即通用访问规范(当然还有其他译法,暂且这么翻译)。具体相关概念自己查阅。这里要说明的是,作为初学者,我们只要知道GAP是干嘛的就行,简单来说就是负责设备配置,设备初始化,安全管理,设备发现,建立连接,断开连接等,都是与连接相关的(准备、建立,管理,终止等)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include "main.h"#include "stdio.h"#include "string.h"UART_HandleTypeDef huart1;GPIO_InitTypeDef GPIO_InitStruct;void LED_Control(uint8_t state) { HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, state);}void USART1_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); }}void MX_GPIO_Init(void) { GPIO_InitStruct.Pin = LED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);}void AT_SendCommand(char *cmd, char *response) { uint8_t buffer_rx[100]; uint8_t buffer_tx[100]; memset(buffer_rx, 0, sizeof(buffer_rx)); memset(buffer_tx, 0, sizeof(buffer_tx)); sprintf((char *)buffer_tx, "%s\r\n", cmd); HAL_UART_Transmit(&huart1, buffer_tx, strlen((char *)buffer_tx), 1000); HAL_UART_Receive(&huart1, buffer_rx, sizeof(buffer_rx), 5000); if (strstr((char *)buffer_rx, response) == NULL) { printf("AT Command Failed: %s", response); }}int main(void) { HAL_Init(); USART1_Init(); MX_GPIO_Init(); char buffer_rx[100]; memset(buffer_rx, 0, sizeof(buffer_rx)); AT_SendCommand("AT", "OK"); AT_SendCommand("AT+CWMODE=1", "OK"); AT_SendCommand("AT+CWJAP=\"ssid\",\"password\"", "OK"); while (1) { AT_SendCommand("AT+CIPSTART=\"TCP\",\"server_ip\",80", "OK"); AT_SendCommand("AT+CIPSEND=4", ">"); AT_SendCommand("test", "SEND OK"); HAL_Delay(1000); }}
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值