2 核: CPU 中存在两条流水线,可以并行执行两个线程。
4 线程:CPU 总共提供了 4 个寄存器页,可以同时保存 4 套不同的上下文。
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 时基本可以判定系统无法及时稳定的响应中断。
ARM Cortex A 系列:大小核(big.LITTLE)结构。
- 内核指令(OpCode)
- 手动调度(编译时刻调度)(Compile-time Schedule)
轮询(Round-Robin)/状态机(FSM)
操作系统(OS)在运行时刻(Runtime)通过某种调度算法自动的进行任务拆分和调度的方式。
互有原子性的任务在同一个任务平面上。
任务平面的定义不具备传递性。
- 裸机环境下,在未开启中断嵌套的情况下,具有相同优先级的中断处理程序在同一个任务平面上。每个中断优先级都是一个任务平面。
- 裸机环境下,超级循环里阻塞运行的任务,一个任务完成之前不允许别的任务运行,因此相互具有原子性——在同一个任务平面上。
- 裸机环境下,超级循环里并发运行的任务,在每个循环周期内所有的任务均只执行一小部分,从每个任务的视角来看,任务执行的过程不停的被打断,因而这些任务彼此之间不具有原子性——处于不同的任务平面上,且每个任务都独占一个任务平面。
- 操作系统环境下,如果任务的优先级都必须不同,则每个任务都独占一个任务平面,每个优先级都是一个任务平面,例如 µcOSII。
- 操作系统环境下,如果任务的优先级允许相同,且同优先级任务彼此不能打断时,拥有相同优先级的任务在同一个任务平面上,每个任务优先级都是一个任务平面。
- 操作系统环境下,如果任务的优先级允许相同,且同优先级任务彼此能够打断,则所有任务都独占一个任务平面。这种情况我们在后续的模型中有专门的分类和讨论。
简单说就是进行多任务开发时,为了保证系统的可靠性,应该假设每个任务彼此都是可以相互打断的,在这种“最坏”假设下开发出来的代码显然适应所有的情况。
数据完整性问题的本质是操作的原子性问题,是由任务并发特性引起的。
保护共享:在访问共享资源时屏蔽上下文切换。
# define SAFE_ATOM_CODE(...) {
istate_t tState = GET_GLOBAL_INTERRUPT_STATE();
DISABLE_GLOBAL_INTERRUPT();
__VA_ARGS__;
SET_GLOBAL_INTERRUPT_STATE(tState);
}