当使用BlueNRG-1/2本身的 Flash 存储数据应用数据时,可能遇到蓝牙没有信号,或者是死机了等问题。
因为在擦除一页的过程中,中断会被关掉大概 20 多 ms,在擦除期间,radio 中断是被关掉了的,整个 radio 的状态被延时或者整个 RF 部分的状态被破坏。ST 的 SDK 虽然提供了访问 Flash 的 Demo(BLE_Beacon_FlashManagement),但是当多个 Flash 操作时,与蓝牙事件互斥就比较难处理了,特别是对于一些应用多连接或者同时用了主从,多种蓝牙事件的场景,互斥就显得更麻烦了。
为了优化这个问题, 方便用户操作 Flash,不让应用考虑互斥蓝牙事件,下面是我的做法,供参考:
使用一个双向链表来管理 Flash 操作(Flash 擦除或者是 Flash 写,Flash 读无需和 BLE 相关事件互斥),和使用一个双向链表来管理空余时间状态。在空余的时间执行 Flash 操作。 从 datasheet 可以知道,操作 Flash,特别是擦除时,会占用比较多的时间。为了避免操作 Flash 占用过多的时间片,把每次写或 者擦除 Flash,用一个列表来管理,每次写或者擦除操作,插入Flash 操作链表的最后。 在主循环中检测是否有足够的时间写,如果当前空闲的时间,如果空闲的时间足够,取出 Flash 操作链表中最前的一个节点,执行 Flash 操作,然后将节点移除。
对于如何检测空闲时刻,也用一个链表来管理空闲时刻。首先,初始化时需要设置 radio active 事件抛到应用
aci_hal_set_radio_activity_mask(0x0001|0x0002|0x0004|0x0008|0x0010|0x0020);
设置之后,重写函数 aci_hal_end_of_radio_activity_event,当有事件触发时,就会进入这个函数,然后在这个函数里面管理空闲链表。
对于何时写Flash, 主循环中有个 Flash 操作的调度函数,不停的调度是否有数据需要写入。 在 Flash 操作的调度函数中,主要做两件事情,一个是把空闲时间计算出来给到底层的 Flash 操作链表调度中。另一个是移除过期的节点。如果空闲时间足够,就从需要操作的Flash任务链表中取出一个任务执行 |