单片机擦Flash时为啥非要关中断?不关会出大问题!
摘要:单片机擦写Flash时必须关闭中断,否则可能导致CPU卡死或数据混乱。这是因为CPU和Flash控制器无法同时处理读指令和擦写操作。当擦写Flash时若发生中断,CPU可能因无法获取中断服务程序指令而卡住,或读取到不完整的混合数据。有两个替代方案:1)使用多Bank Flash结构,将中断程序与数据存储分开;2)将中断相关代码加载到SRAM中运行。但最简单可靠的方法仍是擦写时禁用中断,这是确
单片机擦Flash时为啥非要关中断?不关会出大问题!
你有没有过这样的疑惑?在捣鼓单片机程序时,只要涉及到往Flash里写数据或者擦除数据,代码里总会冒出一句“禁用中断”的操作。就像你正专心致志搭积木,有人突然把你手里的积木拿走了一样,为啥非要在这个时候“禁止打扰”?今天咱们就来扒一扒这背后的门道,搞懂单片机这波“操作”到底在怕啥。
要弄明白这个问题,咱们得先聊聊单片机里两个关键“角色”的工作方式——CPU和Flash控制器。咱们都知道,单片机程序能跑起来,全靠CPU不停“干活”:从存储指令的地方拿指令(取指)、搞明白指令要干啥(译码)、再动手执行指令,一套流程下来像个不知疲倦的小工人。
而CPU拿指令的“仓库”,很多时候就是Flash。这里得说个小细节:CPU和Flash之间不是直接打交道,中间隔着个“Flash控制器”,就像仓库门口的管理员,所有拿东西、放东西的请求都得经过它。而且这个管理员有点“死板”——它同一时间只能处理一件事,要么帮CPU从Flash里读指令,要么帮程序往Flash里写数据、擦数据,绝对不能“一心二用”。
更关键的是,CPU和Flash控制器的“工作速度”差得不是一点半点。CPU执行指令快得离谱,单位都是纳秒、微秒级,眨个眼的功夫能跑几十上百条指令;可Flash擦写数据就慢多了,动辄要几微秒甚至几毫秒,对CPU来说,等Flash擦写完,都够它“摸会儿鱼”了。
现在问题来了:如果咱们在擦写Flash的时候,没把中断关掉,会发生啥?
咱们先回忆下“中断”是啥——它就像生活里的紧急电话,不管你正在干啥,只要电话响了,就得先放下手里的活去接电话。单片机里的中断也一样,一旦有外部信号触发(比如按键按下、传感器检测到数据),CPU就得立刻暂停当前正在执行的程序,转而去执行专门处理这个中断的“中断服务程序”。
可麻烦就出在“中断服务程序”的指令,大多也存在Flash里!当CPU要执行中断服务程序时,就得再次找Flash控制器要指令。可这时候Flash控制器正忙着擦写数据呢,根本没空搭理CPU,接下来就可能出现三种情况:
第一种情况算是“运气好”——CPU之前通过“预取”功能,已经把中断服务程序的指令提前存在缓存里了。就像你提前把要用的文件下载到电脑本地,即使网盘卡了也能打开,这种时候程序还能正常跑,没什么问题。
但第二种情况就糟了——如果缓存里没存对应的指令,CPU只能干等着Flash控制器回应。可Flash控制器还在慢吞吞地擦写数据,没功夫管CPU的请求,这时候CPU就会“卡住”,像汽车熄火一样,啥也干不了,直到Flash擦写完成才能恢复。要是这期间有紧急任务要处理,那可就彻底耽误了。
第三种情况更危险——会出现“数据混乱”。比如你正在往Flash里写一组重要的配置参数,这组参数要占4个字节,结果刚写完2个字节,突然来了个中断。中断服务程序正好要读这组参数,那它读到的就是“2个新数据+2个旧数据”的混合结果,就像一碗粥里混进了米饭,根本没法用。用这种混乱的数据做事,单片机很可能会出现莫名其妙的错误,比如突然死机、功能错乱,排查起来还特别费劲。
看到这儿你就明白了吧?之所以在擦写Flash时非要禁用中断,就是为了避免出现CPU卡住、数据混乱这些麻烦事,相当于给Flash擦写操作“划了个安全区”,让它能安安稳稳完成工作。
那肯定有人要问了:就没有办法在擦写Flash时不关中断吗?毕竟有些场景里,中断可不能随便停,比如要实时检测传感器数据的设备。还真有两个办法,不过都有小前提:
第一个是从“硬件”入手,用“多Bank Flash”。简单说就是把Flash分成两个独立的“仓库”,每个仓库都有自己的“管理员”(Flash控制器)、“大门”(地址/数据线)和“操作规则”(读/写/擦除逻辑)。咱们可以把中断服务程序、中断向量表这些关键指令放在第一个仓库(Bank1),要擦写的数据放在第二个仓库(Bank2)。这样一来,擦写第二个仓库时,第一个仓库的“管理员”还能正常给CPU提供中断相关的指令,互不干扰。不过要注意,中断服务程序里可不能再操作Flash了,不然还是会出问题。
第二个是从“软件”入手,修改程序的“加载规则”。咱们可以通过修改分散加载描述文件(比如STM32里的.sct文件),把中断向量表、中断服务程序这些和中断相关的代码,直接放到SRAM里。SRAM的读写速度比Flash快,而且和Flash控制器是分开的,相当于把中断相关的指令“挪到了离CPU更近的地方”。这样即使Flash控制器在忙擦写,CPU也能从SRAM里快速拿到中断指令,完全不冲突。当然,和硬件方案一样,中断服务程序里也不能碰Flash操作,不然还是白搭。
总的来说,虽然禁用中断是擦写Flash时最“稳妥”的选择,但只要搭配合适的硬件设计或软件配置,也能在保证安全的前提下,实现“擦写Flash不关中断”。不过对大多数普通场景来说,直接禁用中断既简单又靠谱,毕竟咱们写程序时,“稳定”永远是第一位的嘛!
更多推荐



所有评论(0)