所谓多线程都是模拟的,本质都是单线程,因为cpu同一时刻只能执行一段代码。
模拟的多线程就是任务之间快速切换,看起来像同时执行的样子。
据说最近有多核的单片机,不过成本应该会高很多。
对于模拟的多线程,我知道的有两种方式:
1.基于时间片的轮询系统
我自己就写过这样一个系统,原理就是用systick给系统提供一个时间基准,一般我用10ms。
然后把整体产品功能成不同的任务(线程),并且为每个任务分配一个时间片。
我红色框标注的每个任务调度的时间,1代表10ms,50则代表500ms,每个任务执行的频率可以不同,方便释放cpu资源给更需要的任务。
主函数的循环里一直判断每个任务的状态。
这里我把任务直接封装成结构体,通过函数指针的方式去调用,方便不同的任务集中管理。
如果任务就绪,就执行,等该任务执行完,下一个任务才能执行,所以本质还是轮询。
只是每个任务可以灵活分配调度时间,不重要的任务执行次数少,重要的任务执行次数多,看起来像多线程的效果。
这种方式比传统的while(1)去轮询在程序架构上会好一点,任务管理和调度也灵活很多。
缺点就是任务在执行过程中无法被打断,不能马上切换到别的任务去执行。
这套系统我录制过教程,现在暂时开放给大家学习,后面可能会删掉。
想参考的找无际单片机就可以了,或者看下我下面这篇文章的开头。
《单片机入门到高级开挂学习路径(附教程+工具)》
《单片机入门到高级开挂学习路径(附教程+工具)》
《单片机入门到高级开挂学习路径(附教程+工具)》
如果是实时性要求非常苛刻的产品,这个就不是很适合。
2.RTOS
RTOS应该是单片机最接近多线程的系统了,目的就是提高系统的实时响应能力。
比如说你正在主持一个电台节目,并且有一个播报天气的环节,你希望天气播报每隔 10 分钟播报一次,但是电台节目时间是1小时。
如果你使用while(1)轮询的方式去做,你可能会遇到这样的情况:天气播报被其电台节目占用了,导致它不能按照预定的时间进行。
但是,如果你使用的是 RTOS,它会把天气播报分配到高优先级,并且它会保证每隔 10 分钟就运行一次天气播报程序。
播报完以后继续回到电台节目,这样即使有其他任务占用了大量的资源,也不会影响到天气播报程序的正常运行。
这就是 RTOS 的工作原理,它通过分配任务的优先级,保证任务按照预定的时间计划进行。
但本质也是模拟多线程,因为播报电台节目的时候,cpu资源被天气预报抢占了,它们两个任务并没有同时执行。
单片机实现多线程技术是一个比较复杂的技术,不仅需要掌握单片机的相关知识,还需要掌握多线程技术的相关知识,比如任务调度、任务同步、任务资源分配、任务通信等等。
一般都是用现成的RTOS,自己手写一个难度太大了。
对于单片机多线程技术的学习,我不建议新手刚开始就去学RTOS。
应该多做一些基于单片机的项目,把编程基础打扎实。
到那个时候,再去学RTOS时间成本会低很多,理解也会更深刻。