还是5个温控器走Modbus通信的例子。
1、图1(第1个扫描周期)
上面图1中,红色标记的13.02是什么意思呢?
首先解释这个X.YZ格式Code的含义如下:
X:下一个Job执行的优先等级。如果发生在当前Job即将执行之前,那就是10、11、12、13这样的。分别代表L0、L1、L2、L3优先级,数字越高,优先级越高。如果是在当前Job执行刚刚完成之后,下一个Job之前,那就是0、1、2、3这样的。10这个数量级是为了区分相对于当前Job执行的前后。
Y:上一个刚刚完成Job的优先级,可以是0、1、2、3这样的。含义同上。
Z:下一个Job是当前获得通信IO占用权的设备FB实例自己的,还是其它实例的。只有1和2两种选择。1代表是自己的Job,2代表是其它实例的Job,需要切换通信IO(也就是具体的通信指令)的占用权。
根据上面的规则解释13.02:温控器3的上一个执行完的Job优先级为L0。在执行自己的下一个Job之前,发现出现了L3优先级的下一个Job,但这个Job是其它实例的。要切换IO占用权
2、图2(第2个扫描周期)
上面图2中红色标记的13.01的解释:
首先,在这个扫描周期2中,按照上一个扫描周期1中的温控器3出现的13.02的逻辑,modbus执行权已经被转移到了温控器0。
13.01的含义:温控器0的上一个执行完的Job的优先级为L0(这里的执行权是刚从3号设备转移过来的,根本就没有它自己的上一个Job存在,所以为0)。在执行自己的下一个Job之前,发现出现了L3优先级的下一个Job,而这个Job是它自己的。所以就执行了。
3、图3(第4个扫描周期)
上面图3中红色标记的3.32的解释:
设备0刚刚完成一个L3的Job,下一个Job也是L3的,但不是自己的,需要转移执行权。
你也许会注意到,在设备0执行L3 Job期间(扫描周期3),它的数值变成了-1(看左侧Y轴刻度),而其它设备的数值都变成了-5。这是什么意思呢?
在计算机中,0这个数字往往是有确实物理动作含义的。所以我把一个实例的代码在没有派发新Job时候的数值基准设置为-1。这意味着所有的0和10都代表L0任务的出现或完成。同理,1和11,2和12,3和13也是这样。
在竞争性IO的场景中,当一个设备占用了IO,其它设备就不能用了。那么这些实例中,关于IO的执行,以及与之相关的各种调度代码,是没必要执行的,可以提前return。
既然-1是No Any Job Launch的基准,那么-2、-3、-4、-5,就分别代表其它设备获得了L0、L1、L2、L3的执行权。所以这里当设备0执行L3 Job的时候,其它设备都变成了-5,提前return了。
这类被其它实例的优先级截断的情况下,只有三分之一的实例代码会被执行,这些代码都是和设备UI有关,与IO无关。
出现-2,也就是其它实例执行L0最低等级的情况下,会有三分之二的实例代码被执行。因为这时候大家是彼此平等的,各自都在积极调度,随时任何一个设备都可能产生各种级别的高优先权去抢断别人。
通过上面的局部细节解释可以看出,在Trace图中,每一个周期的每一个线段的细节形状,都是有精确的代码逻辑与之对应。用眼睛看Trace,就等价于像看电影一个样,逐个周期的观看代码的逻辑流。所以这里的变量,我给它起名为IOCode_Flow,就是这个意含义。
现在1200的Trace,最多同时只能16个变量。如果想要在一个画面中看到关注流程的全部动态细节,就得不断的场景语义内聚。尽量用少的变量传达更多的信息,架构的解耦需要与此协同一致。只有这样,面对长时间大量细节的逻辑流量,才可以尽可能的一眼扫过尽收眼底。
如此精雕Trace和架构细节有意义吗?在此我引用华为操作系统内核实验室某人在HDC2024的一句话:没有工具链,是做不了什么的。
第一性原理不是凭空的。
上面提到的设备FB内的Return,结构如下。