玩转嵌入式多任务程序设计笔记三

2019-07-12 16:02发布

  • 2 核 4 线程
2 核: CPU 中存在两条流水线,可以并行执行两个线程。 4 线程:CPU 总共提供了 4 个寄存器页,可以同时保存 4 套不同的上下文。  
  • 1MHz 就是 1us
1us 对应一个指令周期。 12MH:1us 时间内就有 12 个指令周期。 500KH:1us 时间内就有 0.5个指令周期。   假设所有指令都是单指令周期的,这样 1 个指令周期就对应一条指令,假设每条指令都是 2 个字节大小(16 位指令)。1ms 时间内 1MHz 的系统可以运行大约 2KB 的代码,一个 12MHz 的系统可以运行 24KB 的代码。 在 1MHz 的系统中对于一个 1KHz的毫秒中断,中断处理程序越接近 2KB,就说明系统越可能“丢中断“。 我们来看一个实例:评估一个 10KHz 的外中断,中断处理程序允许的理论最大安全尺寸是多少? 首先,我们要搞清楚系统的指令大小和指令集的周期数情况。以 ARM Cortex M3 为例,其指令大 部分为单周期指令,支持 16 位指令和 32 位指令。为了评估中断处理程序的尺寸上线,我们可以分别以16 位指令和 32 位指令为基础计算出两个结果作为参考范围; 其次,我们要搞清楚系统频率。假设系统频率为 72MHz,已知 10KHz 等效于 100us,则中断处理 程序的理论最大尺寸范围是(72 * 100 * 2)字节到(72 * 100 * 4)字节,即 14.4KB 到 28.8K 之间。取最小值 14.4KB。 结论,中断处理程序及其调用的子函数,其尺寸总和至少要小于 14.4KB 才能确保 10KHz 的中断得 到及时的响应。由于未考虑循环、分支以及其它任务的存在,以上结果仅用于粗略的快速评估,实际代码通常应该远小于这一上线值。当实际尺寸接近或者超过 14.4KB 时基本可以判定系统无法及时稳定的响应中断。  
  • 大小核(big.LITTLE)
ARM Cortex A 系列:大小核(big.LITTLE)结构。
  • 内核指令(OpCode)
  • 手动调度(编译时刻调度)(Compile-time Schedule)
轮询(Round-Robin)/状态机(FSM)
  • 自动调度(Runtime Schedule)
操作系统(OS)在运行时刻(Runtime)通过某种调度算法自动的进行任务拆分和调度的方式。
  • 多任务是一个概念,与是否使用操作系统无关。
  • 任务平面(Task Plane)
互有原子性的任务在同一个任务平面上。 任务平面的定义不具备传递性。
  1. 裸机环境下,在未开启中断嵌套的情况下,具有相同优先级的中断处理程序在同一个任务平面上。每个中断优先级都是一个任务平面。
  2. 裸机环境下,超级循环里阻塞运行的任务,一个任务完成之前不允许别的任务运行,因此相互具有原子性——在同一个任务平面上。
  3. 裸机环境下,超级循环里并发运行的任务,在每个循环周期内所有的任务均只执行一小部分,从每个任务的视角来看,任务执行的过程不停的被打断,因而这些任务彼此之间不具有原子性——处于不同的任务平面上,且每个任务都独占一个任务平面。
  4. 操作系统环境下,如果任务的优先级都必须不同,则每个任务都独占一个任务平面,每个优先级都是一个任务平面,例如 µcOSII。
  5. 操作系统环境下,如果任务的优先级允许相同,且同优先级任务彼此不能打断时,拥有相同优先级的任务在同一个任务平面上,每个任务优先级都是一个任务平面。
  6. 操作系统环境下,如果任务的优先级允许相同,且同优先级任务彼此能够打断,则所有任务都独占一个任务平面。这种情况我们在后续的模型中有专门的分类和讨论。
  • “任务多元化原则”
简单说就是进行多任务开发时,为了保证系统的可靠性,应该假设每个任务彼此都是可以相互打断的,在这种“最坏”假设下开发出来的代码显然适应所有的情况。
  • 数据完整性
数据完整性问题的本质是操作的原子性问题,是由任务并发特性引起的。  
  • 共享资源
保护共享:在访问共享资源时屏蔽上下文切换。 # define SAFE_ATOM_CODE(...) { istate_t tState = GET_GLOBAL_INTERRUPT_STATE(); DISABLE_GLOBAL_INTERRUPT(); __VA_ARGS__; SET_GLOBAL_INTERRUPT_STATE(tState); }