设为首页收藏本站

爱吱声

 找回密码
 注册
搜索
查看: 6156|回复: 17
打印 上一主题 下一主题

[工程技术] 从丰田车控谈工控编程

[复制链接]

该用户从未签到

楼主
发表于 2014-1-17 12:51:02 | 显示全部楼层
要说爱坛就是好,大家都是谦谦君子。晨老大的帖子发出这么多天,除了[意广才疏]的那一只靴子悬在半空中外,其它基本上都是附和之声。今天我做恶人,上来拍砖。' t% k8 Q0 P8 e1 \3 m! G+ v

' U1 K8 J  I% C0 H4 m2 w5 O  X先说晨帖中有价值的一面,晨老大最大的功绩是说清楚了为什么丰田车载控制系统写成了这个样子:时间紧、公司中地位不高(晨语:后娘养的)、历史积累太多改动困难、等等... ... 这些都是非身处一线而不能深刻体会的。但对于Michael Burr法庭证词的主要目的,即丰田车载控制系统是不是reliable software,晨文则或观点错误,或罔顾左右而言他。借用电视剧《潜伏》打个比方,不发生横向联系是地下工作的纪律。晨枫在国军桂系中成功潜伏十八年,对此条纪律有异议,云:我都干了十八年,根据经验有没有这条都没事;桂系中的人事关系特殊,那些对付军统的方法在这里不适用... ... 而被晨枫批驳的原文(以下简称原文)则说的是:组织研究后认定,鉴于晨枫小组未能严格遵守工作纪律,因此不能将晨枫小组视为可靠情报来源。
: O0 f' t8 X2 `
4 G* B3 u1 E& F! E) k下面逐条评论一下晨文。
9 S3 ~/ \  _# `* }( q
0 l8 I7 k: M2 `第一个问题:模块复杂度过高,不便于查错、修复和扩展,有的已经达到“非可维护程度”了。' u0 \# s& I' y
这点上晨枫其实并不反对Machael Barr,只是在强调:理想很丰满,现实很骨感。4 N0 T$ g9 R6 V
: y$ t% b5 q" o: S, h' Q
第二个问题:全局变量过多。
  S8 j  s. r* l- x5 L无论多么深层的子程序,全局变量都可以拿起来就用,很简捷、高效,不是吗?就像[萨苏]主持的节目《国宴》中提到的一件事:周总理直接打电话给礼宾司的一名小职员讨论宴会坐次安排问题。但是这么做绝对是有前提条件的:一是要求负责人有很高的智力水平和责任心。周恩来一杆到底没问题,林彪这么做效果也很好,但到了常凯申那里就是杯具。二是环境恶劣场合不适用,想一想周恩来一个电话打给余成则会怎么样。回到丰田车载控制系统,这两条全占了。环境恶劣是一定的,汽车发动机舱内可没有空调间,火花塞那个高压放电呀一分钟好几千次。至于丰田那帮developer的心智水平,比之于常公那又是差了十万八千里。
  U, D3 N2 K3 q
! |. s/ O+ z- K" \6 W: ~所以一般人写程序,最好学余成则们,尽量保持单线联系。而全局变量过多,往往会给各个模块之间带来一些不必要的横向联系。这不仅造成程序运行时结果不可測,就是开发本身也困难重重。设想一下,航天部某研究所承担嫦娥三号任务,一天8 u5 Q" B9 s# }5 {  x% E
领导:小王,你那月球车遮阳板做得怎么样了?
' k8 m' _" s  `小王:做好了。
( x0 Q* }* v1 w领导:很好。抓紧时间赶快测试一下。# v/ R0 V" J3 ?9 W' |) Y; Z0 J
小王:月球车的其它部分还没有做完你让我怎么试?9 v0 c* E1 \& T, V# y
领导:?@#%¥&!!!- M6 k$ k, {1 i# d# l

/ W# U  K# R, b3 J/ M! ?6 o可笑吗?很多spaghetti程序就是这样,写出来后模块A等模块B,模块B等模块C,根本无法单独测试。等到所以模块都出来后放在一起才发现糊成一锅粥了。
: c4 o9 D) e6 x1 Z9 M, E# z5 V" s% \0 P1 Z# _% r
说了怎么多那么我们如何面对晨枫难题,即控制软件所需要的大量数据。这里晨大显然将全局变量(global variable)与全局数据(global data)混在一起了。全局变量可以承载全局数据,但全局数据并不一定依赖于全局变量,没有全局变量一样可以获取全局数据。以C语言为例,可以定义一个结构(struct)涵盖全局数据区的所有数据,然后把这个结构的指针作为参数传递给子程序。如果数据真的很多很复杂,还可以考虑轻量级的in-memory数据库(不是所有的数据库都像Oracle、DB2那样巨无霸),保证酸味(ACID)纯正。0 P. ]4 b# h* D. }; B3 d3 E' `1 q
  n! l. A8 x6 S( g% N6 b/ W- T
第三个问题:违反丰田和行业的编程规范。
% b$ J8 D8 c, n没啥好说的。自己定下的编程规范自己不遵守,那么编程规范就是糊弄外人的样子货。
4 w# L. F% o4 \" A* X% |2 _2 J
7 r4 d) Z2 C0 s% S  e第四个问题:使用递归。
0 c* U+ K( ^  m/ w  Y" i3 u( n2 y' K- x递归简单地说就是函数自己调用自己。这种表达很简洁,在自控的理论研究中也多有采用。但在计算机中运行时会大量消耗系统资源。解决方法不是晨大所提出的调用计数器(有限层调用也会消耗不少堆栈资源,而且计数器本身恐怕也要靠全局变量实现),而是应将递归(recursion)问题先转化成迭代(iteration)再写代码。' x: D  Z$ k2 b' N' e/ d

# [7 j( L% h& r4 S第五个问题:缺乏关键变量出错保护。" y" L( s* x: _/ J
晨文中的变量保护与原文说的是两回事。晨文讨论的是传感器给我坏数据怎么办;原文关注的是好数据在内存中放着放着自己就坏了怎么办。一般人可能不理解,数据又不是草莓,还能放着自己就长霉不成?这个嘛需要一点内存的小知识。现在计算机的内存基本上都是SDRAM了,速度越来越快,DDR、DDR2、DDR3,一路走高。SDRAM中的D代表的动态(dynamic ),什么意思呢?先来一段小电影9 t! S. H( b  R8 G; ~) k3 U
(某宣传科)领导:小张,今天的好人好事很多,你都记下来,别落下什么。$ `9 }; z. q: ]
小张:好的。给我... ...
4 k. l; A1 P1 V' P领导:什么?( A6 ?! q; u2 K, `# _
小张:纸呀。另外墨水也用光了。
# z: s( N& ~, S9 `7 h. E领导:奥,现在经费紧张。你先毛笔蘸水写在地板上吧。4 x; y5 e' j( b3 s& c+ ]( i( N7 K# f
小张:那一会水一干不就什么都没了?
% Z0 n6 g4 E+ _# X* {* u$ d领导:嗯,这是一个问题。这样罢,你趁着水没干之前再抄一遍。
$ w2 V  v8 w# {小张:@#%¥&!!!! ^5 @5 v1 P4 D  l0 j
5 U% Y4 w7 w6 R7 J# z, \- ]! u# A
现在的内存就是这样,只不过内存的重抄的速度比小张快多了,是毫秒级的,也就是说一秒钟要成百上千次。饶是电子电路很可靠,抄多了也难免抄出错来。这时需要对数据加上校验,而且校验码短了也不行(像2008年款凯美瑞),因为短了能发现错误但改正不了。另外这些都是用硬件实现的。不存在晨文中的耗用CPU和I/O时间的问题。4 M5 e) a7 U; n) o- R
! k* }+ l( c+ ^! O
第六个问题:对操作系统的代码没有深度审核,选用的操作系统没有通过认证。" V- f: q6 v  E( f. j- `1 X  J
晨枫承认丰田使用未经认证的系统不应该。但是否对操作系统的代码进行深度审核,取决于任务的关键性和操作系统的复杂性。美国海军使用Windows NT,但火控系统的核心肯定还是固化在电路上,不能Windows一蓝屏导弹连烧火棍都不如。另一方面,丰田使用的操作系统也没有那么复杂,丰田完全雇得起像Michael Burr那样的人对其操作系统进行深度审核,但丰田没有做。
: j9 Q. c& }+ f& J! \# z
7 x. ?! o# q% T+ D3 ]先说第八个问题:内存分配容量不足,位置不合理,堆栈溢出造成任务分配表错乱。
+ H& e, t! Q! v这个问题上十有八九也是晨大错了。如果有时间读一下任何一个系统启动(boot)代码,就会知道刚开始的时候计算机内存里那真是白茫茫的一片,哪里是堆( heap)、哪里是栈 (stack)、哪里是任务分配表全是人指定的。CPU对所有内存一视同仁,并不会每走一步都做边界检查。这就是为什么“堆栈溢出”是病毒入侵的一种常用手段。所谓“堆栈溢出”入侵,指的是说病毒将恶意代码作为数据写到栈上(当然要写过界),然后过一会儿(最常见是函数返回时)CPU把这些过界的数据捡起来当代码执行。龙芯二号能够给压入栈的数据打上不可执行的记号,这已经是超过包括intel在内其它CPU的反病毒技术了。一般CPU的堆栈保护确实像[江城如画里]说的那样,就是设立专门的栈段,然后靠段自己的保护机制进行总量控制。如果设置合理,虽然并不一定能防住病毒入侵时的局部溢出,但至少也不会错误地写入与之相邻的任务分配表而不知。段保护的前提是要求CPU要有MMU(内存管理单元)。可是嵌入式系统不比家用PC机,许多CPU并不具备MMU。这样的CPU行为上更像8086,而不是80386或其后续产品。与之对应软件上要做相应的考虑,比如不能使用常见的linux,而要用它的变种μClinux。无论出于历史原因还是成本考虑,凯美瑞使用不含MMC的嵌入式系统的可能性都很高。不含MMC的系统肯定便宜。至于历史原因嘛,就像晨大所说工业界偏好“貌似老爷的系统”,早期的嵌入式系统大部分不含MMC,丰田用熟了很可能继续用下去。从那个4KB大小的堆栈我们也能看出一些端倪,这玩意儿恐怕不是什么高端大气上档次的东西。
; H9 a1 Q; e3 O* D4 j0 L$ u& r. P* X" J9 ~! p9 M1 `, l
问题七、九、十、十一放在一起谈。1 x% w6 [- q7 ^# T- E/ Z
上文说到计算机的内存不可靠,那么CPU就百分之百地可靠吗?这里我们要像余成则那样思维:朋友不可靠,父母不可靠,老婆也不可靠,一切都要有后备方案。设想一下CPU中的程序计数器(PC)出了意外会怎么样。不用多了,就是多加一个1对多字节指令也是灾难性的(把我的名字读成冗宝,这还了得)。下面呢,CPU发狂暴走,不知奔向何方,俗语说就是程序飞了。watchdog的作用是把跑飞了的程序圈回来。具体做法:在程序中嵌入对watchdog定时器清零(俗称喂狗)的指令,如果程序出现故障无法在规定的时间里执行清零指令,一旦watchdog定时器计满则触发系统重启。由此可见,用硬件时钟“喂狗”是荒唐的,但不是晨枫所说的那种荒唐。程序跑飞时不是时钟死了,恰恰相反,因为时钟活着程序才能越飞越远。丰田工程师的错误,就像潜伏时组织要求晨枫每月十五号到二十号晚上六点半到七点半之间拨打一个特殊号码,结果晨枫带着智能手机穿越回去搞潜伏。手机上一设定时,电话是每月按时拨出去了,但打电话的目的也就落空了。
, f& R' Q0 o- W- I4 q/ H8 a1 E1 {1 x$ c; L/ H4 d
所以watchdog是用来应付意外情况的,例如内部出现叛徒,组织遭到严重破坏。潜伏人员工作负担太重的问题应该另外有人负责(第十个问题)。做地下工作,领导的主要任务是搞好组织建设,而不是像Task X那样亲自动手干脏话、湿活(第九个问题)。即使领导出现了意外,也要保护好党员名单,不要让它流失或落入敌手(第七个问题)。% D+ e. W7 M4 A2 D- v

2 Q9 l$ a# d4 v" o6 f) u" ~, q( V关于系统重启,晨大反复给我们描述了其可怕的场面。我不禁在想这会不会是晨大为了加强他的论点而故意执片面之词呢。我并不否认一个连续控制系统一切从零开始的种种危险。但重启就只有这样吗?如果说晨大对计算机有可能不熟的话,那么做了那么多年自控对PLC应该再熟不过了。以西门子S7-400为例,启动可分为冷启动、暖启动和热启动:
3 y* b! M$ k- F
冷启动:所有的数据(过程映象,位存储器、定时器和计数器)都被初始化,包括数据块均被重置为存储在装载存储器(Load memory)中的初始值,与这些数据是否被组态为可保持还是不可保持无关。首先执行启动组织块OB102。
/ \& j& v: H  K" f( s" [" B
- n# A: D2 f3 b' u暖启动:从程序开始处以系统数据和用户地址区的初始设置开始进行程序处理(非保持性定时器、计数器和位存储器复位)。保持的标志存储器、定时器和计数器以及数据块的当前值保持(仅当有后备电池)。OB100中的程序执行一次然后循环程序开始执行。
: ^! Z" ?+ o, p0 S/ y5 T: g* a9 M' m  A7 {
热启动:在程序中断处重新开始执行程序(不复位定时器、计数器和位存储器)。在启动时所有数据(标志存储器、定时器、计数器、过程映像及数据块的当前值)被保持, OB101中的程序执行一次。然后程序从断点处(断电, CPU STOP) 恢复执行。

: V* h% U$ y$ z. M/ u( F* G这里不是讨论PLC,而是说一个嵌入系统的重启也可以类似地分成三类。晨大描述的可怕场面对应的是冷启动,而watchdog触发的重启则很有条件相当于热启动。由此我们也可以再次体会到保护系统关键数据的重要性(第七个问题)。$ i8 N. m9 U" G) o( W, d: G' Z$ z

( S7 a( d$ x: P& n6 K第十二和第十三个问题
* q$ a9 B$ H$ s6 O4 m  U( TBrake Echo Check是以上各种措施失效后的救命手段。那么这个救命手段什么时候能运转起来呢?change of state。丰田工程师的思路,就像奥巴马总统最喜欢唱的那首歌《除了change我们谁也不认》。什么是change呢?司机的脚不在刹车踏板上到踩下刹车是change;踩在刹车上的脚离开刹车踏板也是change ;而踩在刹车上的脚死死地停在刹车踏板上就不是change。所以如果汽车暴冲前你的脚是踩在刹车上的,那么暴冲后你的正确做法是把脚挪开刹车踏板片刻,好让Brake Echo Check发挥作用。我相信,这对舒马赫不难。
) ]& G) l8 G. o' `+ {& c& f
$ O6 }; u6 v2 X: }! B第十四个问题
- g9 A  R9 K0 ~) ]1 T; D( X1 Y- B晨大说得太多了。一句话,凯美瑞是家庭车。所有mutually exclusive action的cross check按普通人考虑即可。如果玩不了heel and toe,那人不应该抱怨丰田,而是该另买一辆车。  c. P" }! T7 }
0 y# J) V5 `$ h# z+ N" O2 _
第十五个问题:节气门大开导致刹车助力不足。
2 |9 `; E2 W8 B2 _% j$ U( a后来晨枫也承认刹车的真空助力确实和节气门有关。谁要还对此持异议,可以自己试一下。把车开上高坡,变速器到N(neutral)档,发动机熄火,汽车借重力加速下滑,到60km/h再开始踩刹车。事先声明,出事与我无关,拒绝追杀。2 ~8 T% ~0 j" S. S

7 P$ {6 s$ b) V7 y! K0 x总结:晨枫对Michael Barr的批评站不住脚。也许化工领域有特殊性,但给嫦娥三号编程会遵照Michael Barr的原则而不是认同晨枫的观念。至于丰田车该站哪一边,大伙看着办吧。

点评

补充:一个汽车软件开发者在德国 [url]http://blog.jobbole.com/57005/[/url]  发表于 2014-1-26 22:12

手机版|小黑屋|Archiver|网站错误报告|爱吱声   

GMT+8, 2024-6-2 01:34 , Processed in 0.039289 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表