RTOS rt-thread裸机系统与多线程系统

简介: RTOS rt-thread裸机系统与多线程系统

裸机系统与多线程系统

裸机系统

裸机系统通常分成轮询系统和前后台系统

轮询系统

轮询系统即在裸机编程过程中,先初始化相关的硬件,然后让主程序在一个死循环里面不断循环,顺序地做各种事情,大概的伪代码参见代码清单2-1。轮询系统是一种非常简单的软件结构,通常只适用于那些只需要顺序执行代码且不需要外部事件来驱动就能完成的操作。在代码清单2-1中,如果只是实现LED翻转、串口输出、液晶显示等操作,那么使用轮询系统将会非常完美。但是,如果加入了按键操作等需要检测外部信号的事件,或者用来模拟紧急报警,那么整个系统的实时响应能力就不会那么好了。假设DoSomething3是按键扫描操作,当外部按键被按下,相当于产生一个警报,这个时候,需要立刻响应,并做紧急处理,而这时程序刚好执行到DoSomething1,并且DoSomething1执行的时间会比较久,久到按键释放之后都没有执行完毕,那么当执行到DoSomething3时就会丢失一次事件。由此可见轮询系统只适合用于顺序执行的功能代码,当有外部事件驱动时,实时性就会降低。

轮询系统伪代码
int main(void)
{
  /* 硬件相关初始化 */
  HardWareInit();
  /* 无限循环 */
  for (;;) {
    /* 处理事件1 */
    DoSomething1();
    /* 处理事件2 */
    DoSomething2();
     /* 处理事件3 */
     DoSomething3();
  }
   }

前后台系统

相较于轮询系统,前后台系统是在轮询系统的基础上加入了中断。外部事件的响应在中断里面完成,对事件的处理还是回到轮询系统中完成。在这里我们称中断为“前台”,main()函数里面的无限循环称为“后台”。

前后台系统伪代码
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int main(void)
{
  /* 硬件相关初始化 */
  HardWareInit();
  /* 无限循环 */
  for (;;) {
    if (flag1) {
      /* 处理事件1 */
      DoSomething1();
    }
    if (flag2) {
      /* 处理事件2 */
      DoSomething2();
    }
        if (flag3) {
      /* 处理事件3 */
      DoSomething3();
    }
    }
 }
void ISR1(void)
{
   /* 置位标志位 */
   flag1 = 1;
   /* 如果事件处理时间很短,则在中断里面处理;
    如果事件处理时间比较长,则回到后台处理 */
   DoSomething1();
 }
void ISR2(void)
 {
   /* 置位标志位 */
   flag2 = 1;
   /* 如果事件处理时间很短,则在中断里面处理;
    如果事件处理时间比较长,则回到后台处理 */
   DoSomething2();
 }
 void ISR3(void)
 {
   /* 置位标志位 */
   flag3 = 1;
   /* 如果事件处理时间很短,则在中断里面处理;
    如果事件处理时间比较长,则回到后台处理 */
   DoSomething3();
 }

在顺序执行后台程序时,如果有中断产生,那么中断会打断后台程序的正常执行流,转而去执行中断服务程序,在中断服务程序里面标记事件。如果要处理的事件很简短,则可在中断服务程序里面处理,如果要处理的事件比较繁杂,则返回后台程序中处理。虽然事件的响应和处理被分开了,但是事件的处理还是在后台中顺序执行的,相比轮询系统,前后台系统确保了事件不会丢失,再加上中断具有可嵌套的功能,这可以大大提高程序的实时响应能力。在大多数中小型项目中,前后台系统运用得好,堪比操作系统的效果。

多线程系统

相比前后台系统,多线程系统的事件响应也是在中断中完成的,但事件的处理是在线程中完成的。在多线程系统中,线程与中断一样,也具有优先级,优先级高的线程会被优先执行。当一个紧急事件在中断中被标记之后,如果事件对应的线程的优先级足够高,就会立刻得到响应。相比前后台系统,多线程系统的实时性又被提高了。

多线程系统伪代码
 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的开销。

无论是轮询系统、前后台系统还是多线程系统,不能单纯地评定孰优孰劣,它们是不同时代的产物,在各自的领域有相当大的应用价值,只有合适的才是最好的。

相关文章
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
393 1
|
监控 Java 测试技术
Java并发编程最佳实践:设计高性能的多线程系统
Java并发编程最佳实践:设计高性能的多线程系统
265 1
|
监控 安全 算法
线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。
【10月更文挑战第6天】线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。为了解决这一问题,可以通过代码审查、静态分析、添加日志监控、设置超时机制、使用锁和同步机制、进行全面测试、选用线程安全的数据结构、限制线程数量、利用现代并发库,并对团队进行培训等方法来预防和减少死循环的发生。尽管如此,多线程编程的复杂性仍需要持续监控和维护以确保系统稳定。
268 3
|
监控 安全 算法
线程死循环确实是多线程编程中的一个常见问题,它可能导致应用程序性能下降,甚至使整个系统变得不稳定。
线程死循环是多线程编程中常见的问题,可能导致性能下降或系统不稳定。通过代码审查、静态分析、日志监控、设置超时、使用锁机制、测试、选择线程安全的数据结构、限制线程数、使用现代并发库及培训,可有效预防和解决死循环问题。
414 1
|
算法 Java 编译器
多线程线程安全问题之系统层面的锁优化有哪些常见的策略
多线程线程安全问题之系统层面的锁优化有哪些常见的策略
|
设计模式 存储 安全
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
Java面试题:设计一个线程安全的单例类并解释其内存占用情况?使用Java多线程工具类实现一个高效的线程池,并解释其背后的原理。结合观察者模式与Java并发框架,设计一个可扩展的事件处理系统
355 1
|
存储 测试技术
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
222 0
【工作实践(多线程)】十个线程任务生成720w测试数据对系统进行性能测试
|
编译器 C语言 iOS开发
iOS 16 系统键盘修复问题之确定_lock是否用于保护对_deferredTasks的多线程读写如何解决
iOS 16 系统键盘修复问题之确定_lock是否用于保护对_deferredTasks的多线程读写如何解决
|
监控 Java 测试技术
在多线程开发中,线程死循环可能导致系统资源耗尽,影响应用性能和稳定性
【5月更文挑战第16天】在多线程开发中,线程死循环可能导致系统资源耗尽,影响应用性能和稳定性。为解决这一问题,建议通过日志记录、线程监控工具和堆栈跟踪来定位死循环;处理时,及时终止线程、清理资源并添加错误处理机制;编码阶段要避免无限循环,正确使用同步互斥,进行代码审查和测试,以降低风险。
350 3
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
765 3

热门文章

最新文章