2.1 裸机系统

2.1.1 轮询系统

轮询系统即是在裸机编程的时候,先初始化好相关的硬件,然后让主程序在一个死循环里面不断循环,顺序地做各种事情。
任务少的时候比较好,但是增加了按键,可能会导致不及时。

  1. int main(void)
  2. {
  3. /* 硬件相关初始化 */
  4. HardWareInit();
  5. /* 无限循环 */
  6. for (;;) {
  7. /* 处理事情 1 */
  8. DoSomething1();
  9. /* 处理事情 2 */
  10. DoSomething2();
  11. /* 处理事情 3 */
  12. DoSomething3();
  13. }
  14. }

2.1.2 前后台系统

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

  1. int flag1 = 0;
  2. int flag2 = 0;
  3. int flag3 = 0;
  4. int main(void)
  5. {
  6. /* 硬件相关初始化 */
  7. HardWareInit();
  8. /* 无限循环 */
  9. for (;;) {
  10. /* 处理事情 1 */
  11. DoSomething1();
  12. /* 处理事情 2 */
  13. DoSomething2();
  14. /* 处理事情 3 */
  15. DoSomething3();
  16. }
  17. }
  18. void ISR1(void)
  19. {
  20. /* 置位标志位 */
  21. flag1 = 1;
  22. /* 如果事件处理时间很短,则在中断里面处理
  23. 如果事件处理时间比较长,在回到前台处理 */
  24. DoSomething1();
  25. }
  26. void ISR2(void)
  27. {
  28. /* 置位标志位 */
  29. flag2 = 1;
  30. /* 如果事件处理时间很短,则在中断里面处理
  31. 如果事件处理时间比较长,在回到前台处理 */
  32. DoSomething2();
  33. }
  34. void ISR3(void)
  35. {
  36. /* 置位标志位 */
  37. flag3 = 1;
  38. /* 如果事件处理时间很短,则在中断里面处理
  39. 如果事件处理时间比较长,在回到前台处理 */
  40. DoSomething2();
  41. }

加入中断提高了系统的相应能力。比如有按键来可以技术去处理按键。

2.2 多任务系统

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

  1. int flag1 = 0;
  2. int flag2 = 0;
  3. int flag3 = 0;
  4. int main(void)
  5. {
  6. /* 硬件相关初始化 */
  7. HardWareInit();
  8. /* OS 初始化 */
  9. RTOSInit();
  10. /* OS 启动,开始多任务调度,不再返回 */
  11. RTOSStart();
  12. }
  13. void ISR1(void)
  14. {
  15. /* 置位标志位 */
  16. flag1 = 1;
  17. }
  18. void ISR2(void)
  19. {
  20. /* 置位标志位 */
  21. flag2 = 1;
  22. }
  23. void ISR3(void)
  24. {
  25. /* 置位标志位 */
  26. flag3 = 1;
  27. }
  28. void DoSomething1(void)
  29. {
  30. /* 无限循环,不能返回 */
  31. for (;;) {
  32. /* 任务实体 */
  33. if (flag1) {
  34. }
  35. }
  36. }
  37. void DoSomething2(void)
  38. {
  39. /* 无限循环,不能返回 */
  40. for (;;) {
  41. /* 任务实体 */
  42. if (flag2) {
  43. }
  44. }
  45. }
  46. void DoSomething3(void)
  47. {
  48. /* 无限循环,不能返回 */
  49. for (;;) {
  50. /* 任务实体 */
  51. if (flag2) {
  52. }
  53. }
  54. }

相比前后台系统中后台顺序执行的程序主体,在多任务系统中,根据程序的功能,我们把这个程序主体分割成一个个独立的,无限循环且不能返回的小程序,这个小程序我们称之为任务。每个任务都是独立的,互不干扰的,且具备自身的优先级,它由操作系统调度管理。
加入操作系统后,我们在编程的时候不需要精心地去设计程序的执行流,不用担心每个功能模块之间是否存在干扰。加入了操作系统,我们的编程反而变得简单了。整个系统随之带来的额外开销就是操作系统占据的那一丁点的 FLASH 和 RAM。
无论是裸机系统中的轮询系统、前后台系统和多任务系统,我们不能一锤子的敲定孰优孰劣,它们是不同时代的产物,在各自的领域都还有相当大的应用价值,只有合适才是最好。

模型 事件响应 事件处理 特点
轮询系统 主程序 主程序 轮询响应事件,轮询处理事件
前后台系统 中断 主程序 实时响应事件,轮询处理事件
多任务系统 中断 任务 实时响应事件,实时处理事件