裸机系统与操作系统

目录


前言

裸机系统与操作系统存在什么区别,两者都适合在什么场景下使用,我们今天我们一起来探讨一下这个问题,

一、裸机系统通常分成轮询系统和前后台系统(中断)

1.轮询系统

轮询系统中是最简单的一种软件结构,就像一条流水线一样是顺序循环执行的,可以看下下边的范例,嵌入式开发过程中一般都是先将硬件结构初始化,之后再加上一个循环控制来执行业务,这就是最简单的流程

int main(void)
{
 /* 硬件接口初始化 */
 HardWareInit();

 /* 无限循环 */
 for (;;) {
   /* 处理事情 1 */
   DoSomething1();

   /* 处理事情 2 */
   DoSomethingg2();

   /* 处理事情 3 */
   DoSomethingg3();
 }
}

这种流程控制比较简单,能处理的业务也有相应的局限性,我们可以看到上面主要执行了3个业务,这3个业务是顺序执行的,这种实现方式的实时性不是很好,比如说我们现在需要一个按键事件及时响应,这种系统设置就不能满足我们的需求。总的来说,轮询系统只适合顺序执行的代码,对于一些外部触发事件的实时性相对较低。

2.前后台系统

前面我们已经讲过轮询系统的实时性较差,别担心,我们还有前后台系统,前后台系统就是在轮询系统的基础上加上了中断操作,我们都知道中断的处理优先级是很高的,我们可以把需要快速执行的逻辑放到外部事件的响应中断里面完成,或者说可以在中断中添加标志位然后在主程序执行响应逻辑代码。我们可以把中断成为前台,main函数中的处理成为回台。

int flag1 = 0;
int flag2 = 0;
int flag3 = 0;

int main(void)
{
 /* 硬件接口初始化 */
 HardWareInit();

 /* 无限循环 */
 for (;;) {
   if (flag1) {
     /* 处理事情 1 */
     DoSomething1();
   }

   if (flag2) {
     /* 处理事情 2 */
     DoSomethingg2();
   }

   if (flag3) {
     /* 处理事情 3 */
     DoSomethingg3();
   }
 }
}

下面是响应的中断处理函数,我们可以根据实际情况来判断是在中断函数执行逻辑代码,还是设置标志位返回主程序执行,这两种方式都是可以的。嵌入式开发中确实存在一些处理是不能再中断中执行的,这个我们根据实际情况来判断就行了

void IRQ1(void)
{
 /* 置位标志位 */
 flag1 = 1;
 DoSomething1();
}

void IRQ2(void)
{
 /* 置位标志位 */
 flag2 = 2;
 DoSomething2();
}

void IRQ3(void)
{
 /* 置位标志位 */
 flag3 = 1;
 DoSomething3();
}

在顺序执行主程序的时候,如果有中断来临,那么中断会打断主程序的正常执行流,转而去执行中断服务程序,如果事件要处理的事情很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台程序里面处理。 相比轮询系统,这种前后台系统模式的实时性更好,并且中断具有可嵌套的功能,我们可以根据各个任务的优先级要实现中断的嵌套,这样能大大提高程序的实时响应能力。

二、多线程系统

相比前后台系统,多线程系统的事件响应也是在中断中完成的,但是事件的处理是在线程中完成的。在多线程系统中,线程跟中断一样,也具有优先级,优先级高的线程会被优先执行。

当一个紧急的事件在中断被标记之后,如果事件对应的线程的优先级足够高,就会立马得到响应。相比前后台系统,多线程系统的实时性又被提高了。多线程系统大概的伪代码具体见代码清单 1-3所示:

相比前后台系统中后台顺序执行的程序主体,在多线程系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为线程。

每个线程都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流,不用担心每个功能模块之间是否存在干扰。

int flag1 = 0;
int flag2 = 0;
int flag3 = 0;

int main(void)
{
 /* 硬件接口初始化 */
 HardWareInit();

 /* OS 初始化 */
 RTOSInit();

 /* OS 启动,开始多线程调度,不再返回 */
 RTOSStart();
}

void IRQ1(void)
{
 /* 置位标志位 */
 flag1 = 1;
}

void IRQ2(void)
{
 /* 置位标志位 */
 flag2 = 2;
}

void IRQ3(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 那点开销。


总结

轮询、前后台和多线程系统软件模型区别:

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值