【发布时间】:2021-02-18 19:21:00
【问题描述】:
我正在使用 ESP32 扫描 BLE 广告商,但出现内存泄漏。如果我注释掉第 94 行(pBLEScan->start),泄漏就会停止,但扫描也会停止。扫描时,它按预期工作,但每次扫描泄漏大约 148 个字节。
如何识别和修复此泄漏?
我尝试了很多变化,但都无济于事。
https://pastebin.com/TsNU02h2
#include <iostream>
#include <string>
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#define SCAN_TIME 5
// Define a struct to hold the data on a single BLE device
struct BleDevice {
char address[18];
char name[80];
char manufacturer[80];
int appearance;
int rssi;
int txPower;
};
// create a static array to hold 80 BLE Devices
static struct BleDevice BleDevices[80];
static int BleDeviceCounter = 0;
// BLE variables
BLEScan* pBLEScan;
BLEScanResults foundDevices;
static char dev_uuid[80];
static int ind = 0; // used in loop as an index
static int lastFreeHeap = 0;
static int deviceCounter = 0;
// BLE Callback
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice adDevice) {
if (adDevice.haveServiceUUID()) {
strcpy(dev_uuid, adDevice.getServiceUUID().toString().c_str());
} else {
strcpy(dev_uuid, "UNKNOWN");
}
if (adDevice.haveName()) {
strcpy(BleDevices[BleDeviceCounter].name, adDevice.getName().c_str());
} else {
strcpy(BleDevices[BleDeviceCounter].name, "");
}
if (adDevice.haveManufacturerData()) {
strcpy(BleDevices[BleDeviceCounter].manufacturer, BLEUtils::buildHexData(NULL, (uint8_t*)adDevice.getManufacturerData().data(), adDevice.getManufacturerData().length()));
} else {
strcpy(BleDevices[BleDeviceCounter].manufacturer, "");
}
if (adDevice.haveTXPower()) {
BleDevices[BleDeviceCounter].txPower = adDevice.getTXPower();
} else {
BleDevices[BleDeviceCounter].txPower = -999; // -999 means NULL
}
if (adDevice.haveAppearance()) {
BleDevices[BleDeviceCounter].appearance = adDevice.getAppearance();
} else { // clear the appearance
BleDevices[BleDeviceCounter].appearance = -999 ; // -999 means NULL
}
strcpy(BleDevices[BleDeviceCounter].address, adDevice.getAddress().toString().c_str());
BleDevices[BleDeviceCounter].rssi = adDevice.getRSSI();
BleDeviceCounter++; // increment the static device counter last
}
};
void setup()
{
Serial.begin(115200);
Serial.println("\n\n Started...\n");
// BLE setup
Serial.println("Scanning for BT Devices...");
BleDeviceCounter = 0;
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(false);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop()
{
BleDeviceCounter = 0; // Set counter to zero
foundDevices = pBLEScan->start(SCAN_TIME, false); // Start scan
deviceCounter = BleDeviceCounter;
for (ind=0; ind < deviceCounter; ind++) {
Serial.printf("[%i] {address=\"%s\", rssi = \"%i\", txPower = \"%i\", mData = \"%s\", app = \"%i\", name = \"%s\"}\n",
ind,
BleDevices[ind].address,
BleDevices[ind].rssi,
BleDevices[ind].txPower,
BleDevices[ind].manufacturer,
BleDevices[ind].appearance,
BleDevices[ind].name
);
}
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
Serial.printf("Free Heap = %i <%i> \n", ESP.getFreeHeap(), (ESP.getFreeHeap()-lastFreeHeap));
lastFreeHeap = ESP.getFreeHeap();
delay(500); // delay 1/2 second
}
//eof
【问题讨论】:
-
通过注释掉代码我已经确定泄漏来自最长的代码行:
strcpy(BleDevices[BleDeviceCounter].manufacturer, BLEUtils::buildHexData(NULL,(uint8_t*)adDevice.getManufacturerData().data(), adDevice.getManufacturerData().length()));仍然不知道为什么
标签: memory-leaks arduino bluetooth-lowenergy esp32