adafruit / Adafruit_CircuitPython_BLE

Bluetooth Low Energy (BLE) library for CircuitPython
MIT License
129 stars 58 forks source link

memory allocation error in simpletest #182

Open jerryneedell opened 1 year ago

jerryneedell commented 1 year ago

I have been testing BLE on both a feather_esp32s3 no-psram and on an itsybitsy_nrf52840 and I am seeing the same failure when running the ble_simplest.py. It scans for awhile, then crashes with a memory failure. The failure can happen immediately or after some time. Is this a known issue?

this was run with Adafruit CircuitPython 8.0.3 on 2023-02-23; Adafruit Feather ESP32S3 No PSRAM with ESP32S3 with the example from the bundle

# SPDX-FileCopyrightText: 2020 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

"""
This example scans for any BLE advertisements and prints one advertisement and one scan response
from every device found.
"""

from adafruit_ble import BLERadio

ble = BLERadio()
print("scanning")
found = set()
scan_responses = set()
for advertisement in ble.start_scan():
    addr = advertisement.address
    if advertisement.scan_response and addr not in scan_responses:
        scan_responses.add(addr)
    elif not advertisement.scan_response and addr not in found:
        found.add(addr)
    else:
        continue
    print(addr, advertisement)
    print("\t" + repr(advertisement))
    print()

print("scan done")

results

>>> import ble_simpletest
scanning
<Address 3d:98:95:8b:92:8e> <Advertisement flags=<AdvertisingFlags general_discovery > >
        Advertisement(data=b"\x0b\xff\x4c\x00\x09\x06\x03\x2c\x0a\x00\x00\xf5\x02\x01\x1a")

<Address fc:78:b2:53:3c:99> <Advertisement flags=<AdvertisingFlags general_discovery le_only > >
        Advertisement(data=b"\x10\xff\x70\x08\x03\x06\x7c\x78\xb2\x53\x3c\x99\x01\x01\x01\x0a\x01\x02\x01\x06")

<Address c8:69:cd:1c:5d:f8> <Advertisement flags=<AdvertisingFlags general_discovery > tx_power=12 >
        Advertisement(data=b"\x02\x01\x1a\x02\x0a\x0c\x0a\xff\x4c\x00\x10\x05\x09\x14\xb9\x96\xf6")

<Address 46:d8:29:f1:17:5b> <Advertisement flags=<AdvertisingFlags general_discovery > tx_power=12 >
        Advertisement(data=b"\x02\x01\x1a\x02\x0a\x0c\x0a\xff\x4c\x00\x10\x05\x05\x1c\x91\x26\x72")

<Address 40:b8:9a:cf:f5:f6> <Advertisement flags=<AdvertisingFlags general_discovery > >
        Advertisement(data=b"\x11\x07\xfc\x9d\xd0\xb3\xcb\x84\xe0\x84\x06\x42\xf3\xf7\xe1\xe0\xbf\xcb\x02\x01\x1a")

<Address 17:55:cc:7a:05:02> <Advertisement  >
        Advertisement(data=b"\x17\x16\x6f\xfd\x8f\xc5\x79\x22\x82\x28\x18\xa8\xb6\xb0\x68\x37\xff\xd3\xe4\x26\x8c\xef\x21\x51\x03\x03\x6f\xfd")

<Address 47:92:59:27:70:98> <Advertisement flags=<AdvertisingFlags general_discovery > >
        Advertisement(data=b"\x1a\xff\x4c\x00\x0c\x0e\x00\xb7\xb3\xc2\x02\x2d\x79\xc4\xa7\x80\x15\xf8\xb5\x6c\x10\x05\x4a\x1c\xed\x5a\xff\x02\x01\x1a")

<Address 35:80:f4:7e:97:48> <Advertisement flags=<AdvertisingFlags general_discovery > >
        Advertisement(data=b"\x0b\xff\x4c\x00\x09\x06\x03\x3a\x0a\x00\x00\xc9\x02\x01\x1a")

<Address 7c:fd:13:45:a2:8a> <Advertisement flags=<AdvertisingFlags general_discovery > >
        Advertisement(data=b"\x1a\xff\x4c\x00\x0c\x0e\x00\xb7\xb3\xc2\x02\x2d\x79\xc4\xa7\x80\x15\xf8\xb5\x6c\x10\x05\x4a\x1c\xed\x5a\xff\x02\x01\x1a")

<Address 47:a5:68:c1:19:81> <Advertisement flags=<AdvertisingFlags general_discovery > tx_power=12 >
        Advertisement(data=b"\x02\x01\x1a\x02\x0a\x0c\x0a\xff\x4c\x00\x10\x05\x08\x1c\x07\x3b\x90")

<Address fc:78:b2:53:76:fd> <Advertisement flags=<AdvertisingFlags general_discovery le_only > >
        Advertisement(data=b"\x10\xff\x70\x08\x03\x06\x7c\x78\xb2\x53\x76\xfd\x01\x01\x01\x0a\x01\x02\x01\x06")

<Address 40:b8:9a:cf:f5:f6> <Advertisement  >
        Advertisement(data=b"\x1d\xff\x2d\x01\x02\x00\x01\x10\x0e\x9a\xfe\x0c\xa0\x22\x46\x9c\x88\xab\xd1\x28\xde\xdf\xbd\xfa\xbc\x90\xd2\xae\xec\x54")

<Address 7c:7d:c6:54:c8:c2> <Advertisement flags=<AdvertisingFlags general_discovery > tx_power=7 >
        Advertisement(data=b"\x02\x01\x1a\x02\x0a\x07\x0b\xff\x4c\x00\x10\x06\x31\x1e\x0e\x30\x64\x72")

<Address a4:c1:38:2b:6d:3b> <Advertisement  >
        Advertisement(data=b"\x12\x16\x1a\x18\x3b\x6d\x2b\x38\xc1\xa4\x94\x07\x31\x0b\x65\x0b\x4f\x4d\x0f")

<Address 74:e4:1f:f4:ad:b7> <Advertisement flags=<AdvertisingFlags general_discovery > tx_power=7 >
        Advertisement(data=b"\x02\x01\x1a\x02\x0a\x07\x0b\xff\x4c\x00\x10\x06\x30\x1e\x25\x34\x9b\xd0")

<Address f6:e6:c2:f8:9e:27> <Advertisement  >
        Advertisement(data=b"\x07\xff\x4c\x00\x12\x02\x00\x00")

<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
        Advertisement(data=b"\x0a\xff\x05\x05\x50\x41\x00\x7c\x0f\xdd\x01\x0c\x09\x42\x4d\x41\x34\x30\x30\x5f\x44\x61\x74\x61")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ble_simpletest.py", line 15, in <module>
  File "adafruit_ble/__init__.py", line 270, in start_scan
MemoryError: memory allocation failed, allocating 62721 bytes
>>> 

I also have a test program to receive beacon packets and it has the same issue. I have implemented a try/except workaround, but is there something else I should be doing?

Adafruit CircuitPython 8.0.3 on 2023-02-23; Adafruit Feather ESP32S3 No PSRAM with ESP32S3
>>> import ble_bma400_beacon
scanning
Exception:  memory allocation failed, allocating 62721 bytes
scan done
<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
battery:  2.5  x:  0.123047  y:  -0.251953  z:  0.917969

Exception:  memory allocation failed, allocating 65179 bytes
scan done
Exception:  memory allocation failed, allocating 63127 bytes
scan done
<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
battery:  2.5  x:  0.121094  y:  -0.25  z:  0.933594

Exception:  
scan done
Exception:  memory allocation failed, allocating 65179 bytes
scan done
Exception:  memory allocation failed, allocating 52853 bytes
scan done
Exception:  memory allocation failed, allocating 52148 bytes
scan done
Exception:  memory allocation failed, allocating 65371 bytes
scan done
<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
battery:  2.5  x:  0.113281  y:  -0.248047  z:  0.923828

<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
battery:  2.5  x:  0.119141  y:  -0.257813  z:  0.933594

<Address 06:05:04:03:02:01> <Advertisement complete_name=BMA400_Data >
battery:  2.5  x:  0.103516  y:  -0.251953  z:  0.923828

Exception:  memory allocation failed, allocating 52853 bytes
scan done

using this code

# This example scans for BMA400_data advertisements from the IN100 beacon

from adafruit_ble import BLERadio

ble = BLERadio()
print("scanning")
while (True):
    try:
        for advertisement in ble.start_scan():
            addr = advertisement.address
            if advertisement.complete_name == "BMA400_Data"  :
                print(addr, advertisement)
                data= advertisement.data_dict[255]
                voltage = data[2] * .03125
                x_accel = data[4]*256 + data[3]
                y_accel = data[6]*256 + data[5]
                z_accel = data[8]*256 + data[7]
                if x_accel > 2047 :
                   x_accel -= 4096
                if y_accel > 2047 :
                   y_accel -= 4096
                if z_accel > 2047 :
                   z_accel -= 4096
                x_accel = 4* x_accel / 2048
                y_accel = 4* y_accel / 2048
                z_accel = 4* z_accel / 2048
                print("battery: ",voltage," x: ", x_accel," y: ", y_accel," z: ",z_accel)
                print()
    except Exception as e:
        print("Exception: ",e)
        ble.stop_scan()
        print("scan done")
dhalbert commented 1 year ago

Do you see the same memory issues on nRF52840 in the second case? Development on the BLE support on ESP32-S3 got stalled because we couldn't add services dynamically. We are considering how to fix this but it's a big job.

I wonder if this is a core bug.

jerryneedell commented 1 year ago

I see it on both the esp32s3 and on the nrf52840 with both programs. It is intermittent - sometimes it occurs frequently and sometimes it takes a 10s of seconds. on the last try of the simplest I saw this after quite awhile


<Address 6f:8a:18:3d:83:4b> <Advertisement  >
        Advertisement(data=b"\x17\x16\x9f\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x03\x9f\xfe")

<Address d9:fe:c2:95:3a:37> <Advertisement  >
        Advertisement(data=b"\x1e\xff\x4c\x00\x12\x19\x10\x1c\xd7\xfa\x85\xa9\xee\xbc\x47\x59\x09\x63\x37\x49\xbf\x8b\xcb\xb0\x2e\x79\xda\x2a\x5a\x02\x37")

<Address f1:46:54:ba:ea:9e> <Advertisement  >
        Advertisement(data=b"\x07\xff\x4c\x00\x12\x02\x00\x02")

<Address d5:f8:0d:66:20:3f> <Advertisement  >
        Advertisement(data=b"\x1e\xff\x4c\x00\x12\x19\x50\x32\x26\x0c\x78\x38\xd8\x49\x00\xc0\xdb\x60\x48\x4c\x82\xc2\xd2\x6e\xa9\xbf\x2c\xd5\x39\x02\xce")

<Address a4:c1:38:2b:6d:3b> <Advertisement  >
        Advertisement(data=b"\x12\x16\x1a\x18\x3b\x6d\x2b\x38\xc1\xa4\xe1\x07\x2d\x0c\x6b\x0b\x50\x59\x0f")

<Address 0c:fe:9a:0e:10:01> <Advertisement  >
        Advertisement(data=b"\x9c\x88\xab\xd1\x28\xde\xdf\xbd\xfa\xbc\x90\xd2\xae\xec\x54\x00\x8a\x98\x08\x00\x00\x00\x00\x00\xc5\xf6\xf5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "ble_simpletest.py", line 15, in <module>
  File "adafruit_ble/__init__.py", line 270, in start_scan
MemoryError: memory allocation failed, allocating 60122 bytes
>>> 

Could it be reacting to a particularly odd packet?

jerryneedell commented 1 year ago

It is working - with the try/except - on both the esp32s3 and on the nrf52840.

dhalbert commented 1 year ago

Do you see this on 7.3.3 as well, on nRF52840?

jerryneedell commented 1 year ago

So far, I have not been able to reproduce it on the nrf52840 with 7.3.3

tannewt commented 1 year ago

Is it always 60k bytes to allocate?

helpfulchicken commented 1 year ago

I have this issue on a nRF52840DK too, running a slightly modified BLE UART example:

# SPDX-FileCopyrightText: 2020 Dan Halbert for Adafruit Industries
#
# SPDX-License-Identifier: MIT

# Connect to an "eval()" service over BLE UART.

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService

ble = BLERadio()

uart_connection = None

while True:
    print("Reading adverts forever..")
    #advIter = ble.start_scan(ProvideServicesAdvertisement)
    advIter = ble.start_scan() # get any advertisements

    i = 0
    for adv in advIter:
        print("Adv %i" %i)
        i = i+1

I eventually get the memory allocation error:

Traceback (most recent call last): File "code.py", line 21, in File "adafruit_ble/init.py", line 271, in start_scan MemoryError: memory allocation failed, allocating 65293 bytes

Where line 21 was for adv in advIter: