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加載的數據進行判斷有沒有手機下發的設備名字,有就用手機下發的,沒有就用默認的
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章