Kernel crashed when rotate the M5dial encoder fast



  • Hi Team

    I was working on a small BLE-related project with M5Dial.
    Basically, the code allows you to select services with M5Dial's encoder, then press btnA to advertise it and hold the btnA to stop advertising.

    The code works just fine when you rotate the encoder slowly, but when you do it fast, it will throw following Errors randomly

    TypeError: '' object isn't callable。  
    TypeError: 'dict_view' object isn't callable
    TypeError: 'list' object isn't callable
    

    or the kernel crashed and the device been reset.

    firmware Version: UIFlow alpha-29

    import ubluetooth
    import time
    from M5 import Widgets, Speaker, BtnA, update
    from hardware import Rotary
    
    
    class BLE_SERVER():
        def __init__(self,src_boards,dst_boards):
            self.ble = ubluetooth.BLE()
            self.isAdvertising=False
            self.rotary = Rotary()
            self.DST_APPS=dst_boards
            self.label0 = Widgets.Label("label0", 16, 101, 1.0, 0xf2f805, 0x000000, Widgets.FONTS.DejaVu24)
            Speaker.setVolumePercentage(0.3)
            Widgets.setBrightness(10)
            BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=self.btnA_wasClicked_event)
            BtnA.setCallback(type=BtnA.CB_TYPE.WAS_HOLD, cb=self.btnA_wasHold_event)
    
        def btnA_wasClicked_event(self,state):
            try:
                if not self.isAdvertising:
                    print('click0')
                    self.isAdvertising = True
                    self.label0.setText(str('advertising....'))
                    self.label0.setCursor(x=20, y=100)
                    self.label0.setVisible(True)
                    Widgets.setBrightness(1)
                    adv_app=self.DST_APPS[int((self.rotary.get_rotary_value()) % len(self.DST_APPS) - 1)]
                    self.start_advertising(adv_app)
            except Exception as e:
                print('btnA_Clicked:',repr(e))
    
    
        def btnA_wasHold_event(self,state):
            try:
                if self.isAdvertising:
                    print('hold0')
                    self.isAdvertising = False
                    self.label0.setText(str('adv stoped'))
                    self.label0.setCursor(x=20, y=100)
                    Widgets.setBrightness(10)
                    self.ble.gap_advertise(None)
            except Exception as e:
                print('btnA_Holded: ',repr(e))
    
        def bt_irq(self,event, data):
            print('BLE_EVENT: ', event)
                
        def start_advertising(self,app):
            for i in range(3):
                try:
                    SERVICE_UUID_SIM = ubluetooth.UUID(0xfff0)
                    RX_UUID_SIM = ubluetooth.UUID(0xfff1)
                    TX_UUID_SIM = ubluetooth.UUID(0xfff2)
                    SERVICE_NAME_SIM = app
                    CHAR_RX = (RX_UUID_SIM, ubluetooth.FLAG_WRITE | 0x04)
                    CHAR_TX = (TX_UUID_SIM, ubluetooth.FLAG_NOTIFY)
                    SERVICE_1 = (SERVICE_UUID_SIM, (CHAR_RX, CHAR_TX,) ,)
                    SERVICES = (SERVICE_1,)
                    time.sleep(0.5)
                    self.ble.config(gap_name=app, addr_mode=1)
                    adv_data_prefix = [0x02,0x01,0x06,len(SERVICE_NAME_SIM)+1, 0x09]
                    resp_d = b'\x11\x07'  + bytes(SERVICE_UUID_SIM)
                    ((char_rx, self.char_tx), ) = self.ble.gatts_register_services(SERVICES)
                    self.ble.gap_advertise(100,adv_data = bytes(adv_data_prefix) + SERVICE_NAME_SIM.encode('utf-8'),resp_data = resp_d)
                    self.isAdvertising = True
                    print('start BLE advertising: ',app)
                    break
                except Exception as e:
                    print('------------------------------------------advertising: ',repr(e))
                    time.sleep(3)
    
    
    
        def run(self):
            self.ble.active(True)
            self.ble.irq(self.bt_irq)  #CB
            list2 = [0xff0000, 0xff9900, 0xffff00, 0x33ff33, 0x33ffff, 0x3333ff, 0xcc33cc]
            while True:
                update()
                if not self.isAdvertising and (self.rotary.get_rotary_status()):
                    print(time.ticks_ms())
                    Speaker.tone(3000, 50)
                    Widgets.fillScreen(list2[int((self.rotary.get_rotary_value()) % len(self.DST_APPS) - 1)])
                    self.label0.setText(self.DST_APPS[int((self.rotary.get_rotary_value()) % len(self.DST_APPS) - 1)])
                    self.label0.setVisible(True)
                time.sleep(0.1)
    
    if __name__ == '__main__':
        u = BLE_SERVER(['A','B'],['BLE_C','BLE_D'])
        u.run()
    
    
    <========  after the code run, rotate the encoder fastly for 50+ times. 
    26733
    26859
    27183
    27409
    click0
    start BLE advertising:  BLE_C
    <==  hold btnA here, but get an error.
    TypeError: '' object isn't callable
    TypeError: '' object isn't callable
    TypeError: '' object isn't callable
    TypeError: '' object isn't callable
    TypeError: '' object isn't callable
    TypeError: '' object isn't callable
    
    93335
    click0
    start BLE advertising:  BLE_C
    <<=======    hold btnA here, but kernel crashed.
    PROBLEM IN THONNY'S BACK-END: Exception while handling 'run' (ConnectionError: read failed: [Errno 6] Device not configured).
    See Thonny's backend.log for more info.
    You may need to press "Stop/Restart" or hard-reset your MicroPython device and try again.
    
    


  • Hi Felix, can you help? @felmue



  • Hello @codeblue

    it seems that adding a gc.collect() call after line self.ble.gap_advertise(None) prevents the crash/error.

    Thanks
    Felix



  • @felmue 我如果不用类的写法, 而直接写方法,程序跑起来就没问题, 也不需要 gc.collect()

    应该不是内存的问题, 因为崩溃的时候,或者报 TypeError: '' object isn't callable 的时候 hold0 还没输出, 说明还没进入btnA_wasHold_event函数, 有可能是btnA 设置回调的时候, 不能设置 self.xxxx 这样的对象函数?



  • @codeblue The BtnA.setCallback method causes this exception.
    A temporary workaround:
    0_1705636943825_72c94abe-d2fa-473c-845d-f323608400c5-image.png



  • @lbuque said in Kernel crashed when rotate the M5dial encoder fast:

    setCallback

    Thanks, will this be fixed in the future?



  • @codeblue It will be fixed in the next version.



  • Hi guys

    thank you for the insight - good to know.

    Thanks
    Felix