扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

BlueNRG-1/2 Flash 与 BLE 事件互斥处理实战指南

03/31 16:55
93
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在基于 BlueNRG‑1/2 做蓝牙项目时,几乎都会遇到同一个坑:一擦 Flash、一写 Flash,BLE 就断连、射频停摆甚至整机死机。

ST 官方 LAT1216 应用笔记把这个问题的根源、互斥规则、以及可直接工程化的解决方案讲得非常清楚。这篇文章就用最落地、去 AI 化的方式,把这套Flash 安全操作方案完整讲明白,让你以后再也不会因为存参数把蓝牙跑挂。

资料获取:【应用笔记】LAT1216 BlueNRG系列芯片Flash操作与BLE事件的互斥处理

1. 问题到底出在哪

BlueNRG‑1/2 里有两个硬件事实,决定了 Flash 和 BLE 不能同时干活:

  1. Flash 擦除会关中断 20ms 以上,擦一页 Flash 期间,芯片会关掉全局中断来保证写入稳定。而 BLE 射频、连接事件、广播、空中包收发全都靠高精度中断,中断一堵,BLE 状态机直接乱掉。
  2. Flash 与射频总线互斥,Flash 操作和 RF 收发会抢同一条硬件总线,不能同时进行,否则直接硬件异常、死机。

所以:

  • 读 Flash:不用互斥,随时可以读;
  • 写 / 擦 Flash:必须等 BLE 射频完全空闲才能做。

2. 官方标准解法:链表调度 + Radio 空闲窗口

LAT1216 给出的方案不是粗暴关蓝牙,而是:

  1. 把擦除、写入封装成任务,挂到双向链表里排队;
  2. 监听 BlueNRG 的 radio 活动事件,精准抓到射频空闲时间段;
  3. 在空闲窗口里安全执行一次 Flash 操作,做完立刻释放给 BLE。

整套机制完全不堵 BLE 协议栈,多连接、主从一体都能稳跑。

3. 4 步直接移植到你的工程

1)打开 Radio 活动事件上报

初始化 BLE 之后,调用这一句,让芯片告诉你射频什么时候忙 / 闲:

aci_hal_set_radio_activity_mask(0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020);

2)实现射频空闲回调

重写事件 aci_hal_end_of_radio_activity_event,系统每次射频结束都会进来,告诉你下一次什么时候开始忙。

void aci_hal_end_of_radio_activity_event(uint8_t last_state, uint32_t next_state_sys_time)
{
    // 更新空闲窗口,交给 Flash 调度器
    free_list_update(last_state, 0, next_state_sys_time);
}

3)主循环里跑调度

APP_Tick() 或主 while 里调用 Flash 调度:

void APP_Tick(void)
{
    BTLE_StackTick();

    // Flash 任务调度(核心)
    flash_operate_tick();
}

4)应用层只调链表 API,不直接操作 Flash

把写 / 擦变成 “任务”,丢进链表排队,由调度器自动找空闲执行:

// 擦页
flash_list_erase_page(page_addr, NULL, NULL);

// 写入
flash_list_program(write_addr, data_buf, len, NULL, NULL);

4. 调度器干了什么(看懂就不会乱改)

flash_operate_tick 里面只做三件事:

  1. next_state_sys_time 算出当前空闲多久;
  2. 如果空闲够执行一次 Flash,就从链表拿一个任务执行;
  3. 做完移除节点,超时任务直接扔掉,不拖 BLE 后腿。

5. 没有 BLE 活动时怎么写 Flash

如果设备没广播、没连接,Radio 不会出空闲事件,调度器不会跑。
这时可以强制跑一遍所有 Flash 任务:

flash_list_tick(0xFFFFFFFF);

适合上电初始化、离线配置等场景。

6. 最重要的 5 条避坑规则(LAT1216 核心)

  1. 写 / 擦必须走链表,绝对不能直接调用;
  2. 中断里、BLE 回调里绝对不能操作 Flash;
  3. 只有擦除和编程需要互斥,读 Flash 随便读;
  4. 多连接场景一定要用这套方案,不要关 BLE 等 Flash;
  5. 空闲窗口不够时,调度器会自动跳过,不会堵死蓝牙。

BlueNRG‑1/2 里 Flash 写 / 擦 ≠ 能和 BLE 同时跑,这是硬件总线与中断机制决定的。ST LAT1216 给出的双向链表 + Radio 空闲调度是官方标准、最稳定的解法:

  • 不修改协议栈
  • 不影响连接、广播、扫描
  • 多连接 / 主从一体都稳
  • 代码可直接跨工程移植

你只要按本文 4 步把链表调度加上,以后存参数、存日志、存配对信息,再也不会把 BLE 跑挂。

相关推荐