系统地写一本书的难度是非常大的,即使有完整的提纲,也会经常陷入思想中断不连续的尴尬状态,毕竟我的文学水平是比较低的,常常有想法而又不能及时表达在书面上。所以这里会尽可能采用博客的风格:写网络日记的方式,将小问题一个个表达出来,到最后再整理形成完整的书本。所有出现思想及主题出现大的跃变的时候,希望大家能接受。 教科书上有很多错误的观点,对时间的描述就是非常重大的败笔,很少能见到对时间特性有正确描述的书,这可能和现在流行的互相抄袭成书的风气有关系吧,没能力出书的人做没能力办到的事情,通常就一个字:抄,不管精华还是糟粕。教科书上对延时的程序和使用定时器精确定时时采用的软件补偿方式的程序,已经残害了老一代人,现在还继续残害着新生代,流毒不浅啊。
发了这么多牢骚,我这里就说明时间的特性,从理论的高度来描述时间:
时间特性具备精确性、模糊性、可丢失性,这三个特性是从应用时间的不同角度来描述的。精确性应用在精确地定时、计时的场合,它是个强实时的概念,比如测量频率。模糊性应用在需要稳定计时的场合,它追求的是长时间的稳定性,而忽略定时每刻发生的时刻,比如显示日期时间。可丢失性是非重要的计时,它只要求阶段性时间符合而不要求一定时间到达就必定发生,比如LED闪烁的时间控制、倒计时执行某些功能性操作,通常是使用时间系统的时间发生标志。
教科书上说到定时,就非常片面的追求时间的精确性,对精确的定时竟然采用软件时钟周期精确计算来完成,是理论上的错误。在构成程序的时候,首先是考虑系统的构成,然后才是具体任务的实现,而不是先实现具体的任务再堆积为系统的构成。如果用软件循环计算时钟周期,那么我们只要提出一个最基本的观点,这个做法就被轻易地攻破了:如果我们想增加其它的程序或中断控制该怎么办?这个做法下几乎无办法,唯一能做的就是关中断,但关中断这种做法在时间长的时候简直就是开玩笑,不是做嵌入软件设计:中断是保证实时性的重大要素,怎么能说关就关?下面就用C51的代码来进一步表达。
为什么我们把嵌入式设计单独从普通软件开发区分开?构成的嵌入式于通常的通用操作系统有何区别?
这就和MCU设计特点是密切相关的。MCU设计中,中断是极其重要的,中断的响应非常有别于通用操作系统。但反过来说,通用操作系统就对中断要求不高吗?不是的,通用操作系统是把中断的处理非常好的屏蔽了,也非常好的支持了高级软件设计的扩展,而嵌入式操作是要亲身去设计中断的相关处理,用尽量简洁高效率的代码去代替适合一切场合的通用操作系统控制模式。这是两者最大的区别:中断的处理方式。
通用操作系统对中断的虽然‘庞大’,但其中包含的理论是非常优秀的,把这些优秀的观点尽量融入MCU设计中,可以进一步建立MCU的设计理论和标准。从这个角度出发,应该可以把嵌入式设计分为三个层次:
©对‘强’中断响应处理的实时处理,称为实时处理设计,通常就是中断处理。比如串口数据接收。
©对需要在一定时间内必须完成的处理,称为弱实时处理设计,通常是中断处理之后需要的处理,比如串口数据接收下来后的数据处理(协议解释),进一步把数据转为非实时处理。
©在主循环中可以处理的任务,称为非实时任务设计,通常是显示、计算....等等大量常规处理。比如把串口数据解析提出了需要的数据后,需要的计算、控制、反馈、显示。
分清楚这个基本观点,对MCU设计就可以认为开始登堂入室了。
实时处理、弱实时处理、非实时处理是嵌入式设计的三个层次,每一层次都代表不同的处理方式和不同的思想方法。
我们用PC上软件开发为例来描述这三个层次先:实时处理设计和PC上的驱动程序设计一样,几乎是同一种东西。弱实时处理是我们在PC上使用的线程,用来监测驱动程序的结果并把它们转为我们要显示的内容。非实时就是我们要PC上写的最普通的代码。
实时一般和队列是紧密联系在一起的,中断把驱动结果放入队列中就可以认为是完成了实时(驱动)的设计要求了,后面就紧跟着弱实时处理。
弱实时处理就是对实时的队列进行处理的过程,但这个过程可以在小程序设计中可以省略掉,就和PC上小程序可以不使用线程处理一样,不一定要求必须的,主循环中能及时处理掉就行。弱实时处理就是把接收到的队列数据进一步转换为我们所需要的数据(数据流量大大减少了),然后也放入一个队列,通常这时候就开始使用消息系统,通过消息传向所需要的任务模块,开始了非实时处理过程。
非实时处理就是前后台系统中的前台,处理大量主要的控制任务,而实时处理和弱实时处理合起来才是前后台系统中的后台。 时间系统指的是MCU软件设计中对定时器使用的分配策略。这里不讲定时器的重要性和特殊性,只讲在前后台系统中如何发挥定时器的作用。 在开始前,我们必须认真考虑这一点:我们做的时间发生器模块,如何在完成后能支持未知的模块,既编写新的模块的时候,如何能直接使用这个时间发生器模块产生的20ms(大小都可以)?这个要求蛮高的,特别在前后台系统中。思考这个时间发生器模块,联系到我以后在其它专题中将提到的任务转移方法(状态机),这个问题的解决方法的轮廓就浮现出来了: 推荐//-------------------------------------------------- //-------------------------------------------------- bool fSysTimer_Latch;
//==1时表示20MS时间到,发生 4、在前面三篇,提到时间系统的构成,可能大家会提出这样一个疑问:随着程序规模的扩大,程序的模块数目的增多,单个模块完全有可能超过20MS,也有可能是40MS、60MS,对这问题是如何解决的?
这个问题是非常实在的,确确实实是会发生的,所以这里又必须引申出另一个重要的认识和两个重要的设计观点:
认识就是必须遵守任务转移(状态机)机制,在超过N倍的20MS时候,必须分割任务。N是>3或4
1、 教科书上有很多错误的观点,对时间的描述就是非常重大的败笔,很少能见到对时间特性有正确描述的书,这可能和现在流行的互相抄袭成书的风气有关系吧,没能力出书的人做没能力办到的事情,通常就一个字:抄,不管精华还是糟粕。教科书上对延时的程序和使用定时器精确定时时采用的软件补偿方式的程序,已经残害了老一代人,现在还继续残害着新生代,流毒不浅啊。
发了这么多牢骚,我这里就说明时间的特性,从理论的高度来描述时间:
时间特性具备精确性、模糊性、可丢失性,这三个特性是从应用时间的不同角度来描述的。精确性应用在精确地定时、计时的场合,它是个强实时的概念,比如测量频率。模糊性应用在需要稳定计时的场合,它追求的是长时间的稳定性,而忽略定时每刻发生的时刻,比如显示日期时间。可丢失性是非重要的计时,它只要求阶段性时间符合而不要求一定时间到达就必定发生,比如LED闪烁的时间控制、倒计时执行某些功能性操作,通常是使用时间系统的时间发生标志。
、、 |