假如你所开发的BLE项目出现了用nrf connect这个app来连接nordic蓝牙,read方法可以读取,但是notify出现了:
在使用工作队列的情况下:
1.第一次点击notify enable按钮只能读取1-2个数据
2.第二次点击notify enable按钮可以读到几秒到几十秒数据(随蓝牙信号强度而变化),然后卡死
在只用定时器的情况下:
KERNEL报错,自动reset
那么,很有可能,你是遇到了本问题.
问题出现的原因是nrf connect sdk自身的bt_gatt_notify_cb()函数有bug,
该函数底层调用了bt_conn_tx()函数,使得它在conn层发送的时候,调用了下面的函数:
return k_fifo_get(&free_tx, K_FOREVER);
这个函数会在free_tx这个FIFO里以阻塞方式(K_FOREVER)读取数据.你的定时器可能会在其读数据前打断,并塞入新数据.
请注意,问题根源并不在于有些人所说的线程死锁,而是FIFO本身存储空间太小,要发送的包只能存储三个(BT_CONN_TX_MAX默认设置为3),导致您:
1.第一次要发的包过多,FIFO只能存储前三个,k_fifo_get()函数想要读取FIFO超过三次来发送,而导致阻塞.
2.后面有几次发包被定时器打断,导致送给FIFO存储的包大于三个,但是FIFO只能存三个,k_fifo_get()函数想要读取FIFO超过三次来发送,导致阻塞.
在只有定时器的情况下(即中断处理时运行),则会导致崩溃.
解决方法:
方法1:设置CONFIG_BT_CONN_TX_MAX=255[力大砖飞]
方法2:多线程,在另一个线程中进行bt_gatt_notify_cb()[不建议,线程lock与resume需要时间]