nrf52832学习笔记(4)修改蓝牙名称,掉电不丢失

这篇主要介绍如何在手机端修改设备参数,比如设备名称,且实现掉电不丢失。
思路:把需要修改的参数发送给设备,设备根据uuid来分辨是参数,并保存在flash中,重启服务,这样下次上电修改不会丢失。
1.flash的操作
pstorage.c中是官方提供操作flash的库函数,下面介绍几个要用的

说明:初始化flash模块,在调用flash模块之前必须先调用他一次
uint32_t pstorage_init(void);
说明:注册flash接口
[in] p_module_param 注册参数
[out] p_block_id 注册成功时标识flash存储块
uint32_t pstorage_register(pstorage_module_param_t p_module_param,
                           pstorage_handle_t *       p_block_id);                        
说明:根据块编号(block_num)获得你要操作的地址(p_block_id)
[in]  p_base_id 注册成功时标识flash存储块(基块ID)
[in]  block_num块编号,第一块编号为零
[out] p_block_id ,block_num编号块对应的地址
uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id,
                                       pstorage_size_t     block_num, 
                                       pstorage_handle_t  * p_block_id);
说明:在指定位置更新写入存储相应大小的数据
[in] p_dest 更新数据的目的地址
[in] p_src 待写入数据buff首地址
[in] size,写入长度
[in] offset,存储地址的相应偏移量
uint32_t pstorage_update(pstorage_handle_t * p_dest,
                         uint8_t * p_src,
                         pstorage_size_t   size,
                         pstorage_size_t    offset);
说明:在指定位置读取存储区相应大小的数据
[in] p_dest 读取数据的源地址
[in] p_src 读取存放数据buff首地址
[in] size,读取长度
[in] offset,读取数据的源地址的相应偏移量
uint32_t pstorage_load(pstorage_handle_t * p_dest,
                         uint8_t * p_src,
                         pstorage_size_t   size,
                         pstorage_size_t    offset);

第一步,在系统的派发函数里注册官方提供的flash的callback

static void sys_evt_dispatch(uint32_t sys_evt)
{
	//这个函数时在 pstorage 模块中实现的
	pstorage_sys_event_handler(sys_evt);
}

第二步,flash初始化

void flash_init(void)
{
	 uint32_t err_code;
	
	 err_code = pstorage_init();    //初始化flash
     APP_ERROR_CHECK(err_code);	
	
	 pstorage_module_param_t module_param;
     module_param.block_count = 1; // 申请了一个块
     module_param.block_size = 512;//(最小要求是 16)
	 module_param.cb = flash_callback;// //操作回调
	
     err_code =pstorage_register(&module_param, &block_id);//注册申请
	 APP_ERROR_CHECK(err_code);
}

flash_callback我理解是相应操作成功、失败、完成、未完成的判断依据(可以根据op_code分辨哪种状态机,根据result分辨成功失败)如下

static void flash_callback(pstorage_handle_t * handle,uint8_t op_code,uint32_t result,uint8_t * p_data,uint32_t data_len)
{
  switch(op_code)
	{
		case PSTORAGE_UPDATE_OP_CODE:
			if (result == NRF_SUCCESS)
				{
					printf("update end");
					advertising_init();//重新启动广播
				}
		break;
	}
}

这里只判断PSTORAGE_UPDATE_OP_CODE操作成功(result == NRF_SUCCESS)则打印输出update end

2.怎么判断是操作蓝牙名称呢?
可以根据uuid,GAP GATT这种服务的uuid都是SIG定义好的固定的
ble_types.h中80行可以看到设备名称uuid是0x2A00

/* GATT specific UUIDs */
#define BLE_UUID_GATT                                 0x1801 /**< Generic Attribute Profile. */
#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED  0x2A05 /**< Service Changed Characteristic. */
/* GAP specific UUIDs */
#define BLE_UUID_GAP                                  0x1800 /**< Generic Access Profile. */
#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME       0x2A00 /**< Device Name Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE        0x2A01 /**< Appearance Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPF               0x2A02 /**< Peripheral Privacy Flag Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR       0x2A03 /**< Reconnection Address Characteristic. */
#define BLE_UUID_GAP_CHARACTERISTIC_PPCP              0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
/** @} */

手机连接设备后,对BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME属性(uuid 0x2A00)写操作,设备判断是不是对这个uuid写,是的话就把写数据保存在flash中,这样下次重启就可以加载flash数据作为设备名称

static void name_change(ble_evt_t * p_ble_evt)
{
   ble_gatts_evt_write_t *p_evt_write=&p_ble_evt->evt.gatts_evt.params.write;
   //判断是对BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME这个uuid进行写操作
   if((p_evt_write->uuid.uuid==BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME) 
		  && (p_ble_evt->header.evt_id== BLE_GATTS_EVT_WRITE))
		  
	{
			printf("name change \r\n");
			device_name[0] = 0xaa;
			//写的长度
			device_name[1] = p_evt_write->len;
			//写的数据
			memcpy(device_name+2, p_evt_write->data, p_evt_write->len);
			//保存在flash中
			pstorage_update(&my_name_addr, device_name, NAME_SIZE, 0 );
	}
}

然后在蓝牙派发函数ble_evt_dispatch里包含name_change

gap_params_init函数里要对从flash加载的数据进行判断有没有手机下发的设备名字,有就用手机下发的,没有就用默认的
nrf52832学习笔记(4)修改蓝牙名称,掉电不丢失_第1张图片

你可能感兴趣的:(蓝牙,nrf52832)