裸机系统通常分成轮询系统和前后台系统。在裸机系统中,所有的程序基本都是自己写的,所有的操作都是在一个无限的大循环里面实现。
大概的伪代码:
int main(void)
{
/* 硬件相关初始化 */
HardWareInit();
/* 无限循环 */
for (;;)
{
/* 处理事情1 */
DoSomething1();
/* 处理事情2 */
DoSomething2();
/* 处理事情3 */
DoSomething3();
}
}
轮询系统是一种很简单的软件结构,只适合顺序执行的功能代码且不需要外部事件(如中断)来驱动的就能完成的事情。
缺点很明显: 假如DoSomething3()处理非常重要的事情,这个时候代码刚好执行到DoSomething1(),不幸的是这件事儿要执行很久,那么等到执行DoSomething3()的时候已经不知道猴年马月了,系统的实时性降低。
轮询系统特点:轮询响应事件,轮询处理事件
大概的伪代码:
int flag1 = 0;
int flag2 = 0;
int count5ms = 0;
int main(void)
{
/* 硬件相关初始化 */
HardWareInit();
/* 无限循环 */
for (;;)
{
if (flag1)
{
/* 处理事情1 */
DoSomething1();
}
if (flag2)
{
/* 处理事情2 */
DoSomething2();
}
if (count5ms==5)
{
/* 处理事情3 */
DoSomething3();
}
}
}
void ISR1(void)
{
/* 置位标志位 */
flag1 = 1;
/* 如果事件处理时间很短,则在中断里面处理如果事件处理时间比较长,在回到前台处理 */
DoSomething1();
}
void ISR2(void)
{
/* 置位标志位 */
flag2 = 1;
/* 如果事件处理时间很短,则在中断里面处理如果事件处理时间比较长,在回到前台处理 */
DoSomething2();
}
// 1ms定时器
void ISR_Timer(void)
{
/* 置位标志位 */
count5ms++;
/* 如果事件处理时间很短,则在中断里面处理如果事件处理时间比较长,在回到前台处理 */
DoSomething3();
}
前后台系统是在入门学习单片机的时候最常用的一种软件结构;
其中前台指的是中断;后台指的是main函数中的无限循环。
在前台中断中打上事件标志位,在后台无限循环中不断判断标志位来决定功能是否执行;
通常会用一个1ms定时器+标志位变量->周期性执行指定功能(很粗糙)。
相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大的提高程序的实时响应能力。
在大多数的中小型项目中,前后台系统运用的好,堪称有操作系统的效果。
前后台系统特点:实时响应事件(中断),轮询处理事件(无限循环)
伪代码:
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
/* 硬件相关初始化 */
HardWareInit();
/* OS初始化 */
RTOSInit();
/* OS启动,开始多线程调度,不再返回 */
RTOSStart();
}
void ISR1(void)
{
/* 置位标志位 */
flag1 = 1;
}
void ISR2(void)
{
/* 置位标志位 */
flag2 = 2;
}
void ISR3(void)
{
/* 置位标志位 */
flag3 = 1;
}
void DoSomething1(void)
{
/* 无限循环,不能返回 */
for (;;)
{
/* 线程实体 */
if (flag1) {
}
}
}
void DoSomething2(void)
{
/* 无限循环,不能返回 */
for (;;)
{
/* 线程实体 */
if (flag2) {
}
}
}
void DoSomething3(void)
{
/* 无限循环,不能返回 */
for (;;)
{
/* 线程实体 */
if (flag3) {
}
}
}
相比前后台系统中后台的无限大循环,在多线程系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为线程;
每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。
加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流 ,不用担心每个功能模块之间是否存在干扰。我们的编程反而变得简单了。整个系统随之带来的额外开销就是操作系统占据的那一丁点的FLASH和RAM。现如今,单片机的FLASH和RAM是越来越大,完全足以抵挡RTOS那点开销。
火哥说的太好了:
无论是裸机系统中的轮询系统、前后台系统和多线程系统,我们不能一锤子的敲定孰优孰劣,它们是不同时代的产 物,在各自的领域都还有相当大的应用价值,只有合适才是最好。有关这三者的软件模型区别具体见下表。
表格:轮询、前后台和多线程系统软件模型区别
模型 事件响应 事件处理 特点 轮询系统 主程序 主程序 轮询响应事件,轮询处理事件 前后台系统 中断 主程序 实时响应事件,轮询处理事件 多线程系统 中断 线程 实时响应事件,实时处理事件
以下引自火哥原话:
在裸机系统中,所有的程序基本都是自己写的,所有的操作都是在一个无限的大循环里面实现。现实生活中的很多中小型的电子产品用的都是裸机系统,而且也能够满足需求。但是为什么还要学习RTOS编程,偏偏还要整个操作系统进来?
一是项目需要,随着产品要实现的功能越来越多,单纯的裸机系统已经不能够完美地解决问题,反而 会使编程变得更加复杂,如果想降低编程的难度,我们可以考虑引入RTOS实现多线程管理,这是使用RTOS的最大优势。
二是学习的需要,必须学习更高级的东西,实现更好的职业规划,为将来走向人生巅峰迎娶白富美做准备,而不是一味的在裸机编程上面死磕。作为一个合格的嵌入式软件工程师,学习是永远不能停歇的事,时刻都 得为将来准备。书到用时方恨少,我希望机会来临时你不要有这种感觉。
如何快速上手RTOS?
如果快速上手,最简单的就是在别人移植好的系统之上,看看RTOS里面的API使用说明,然后调用这些API实现自己想要的功能即
如何深入地学习一款RTOS?
这里有一个最有效也是最难的方法,就是阅读RTOS的源码,深究内核和每个组件的实现方式,这个过程枯燥且痛苦。但为了能 够学到RTOS的精华,你不入地狱谁入地狱?
跟着火哥,笃定前行:
从0开始,层层叠加,不断地完善,教大家怎么把一个RTOS从0到1写出来,让你在每一个阶段都能享受到成功的喜悦。
在这个RTOS实现的过程中,只需要你具备C语言的基础就行 ,然后就是跟着野火这个教程笃定前行,最后定有所成。