DSP

对我维护的TI 2406 DSP程序的一些想法

2019-07-13 15:52发布

做了一些修改,隐去了项目的真实名称。 1 概述
这里想进一步谈谈软件编程中的想法
我期望的编程方法为如下方法的结合:信号驱动、状态机、模式、面向对象、分层 现在24xx的方法为固定周期的处理方法,
我想先谈谈目前软件优缺点、我们期望的软件框架是什么样的(或者框架的改进方向),最后谈谈基于信号驱动、状态机编程模式的优缺点。
这篇文章,是在参加完公司年终会议,提出对目前软件框架有改进的意愿的情况下写的,也是对20080123写的一些东西的整理。


2 目前的软件框架
2.1 目前的软件框架是什么样的
我们目前的软件框架,x project 2406上的软件框架,是无操作系统、基于控制流程划分模块、固定周期调用模块入口函数的框架。
2.2 优点
1 简单。符合大多数人的思维习惯。
2 程序空间、RAM空间的利用比较有效。
3 固定周期调用模块入口函数,系统负荷稳定。不会出现系统计算能力不够的情况,
即1ms内无法跑完一个主循环的情况,这个情况比较容易控制。
2.3 缺点
1 模块的划分方式有改进的余地。基于流程的模块划分方式,当流程变更时,会导致程序大量修改。
也会导致多个模块的耦合严重。
2 硬件层和业务层没有隔离。例如:在缝制模块内直接读写IO口,使代码紧紧的约束在2406这个CPU上,
很难迁移,从而代码的复用也困难。
3 非C语言。汇编语言的学习、维护难度大。
4 固定周期调用模块入口函数,带来了性能上的不确定性。例如:
原来缝制模块是1ms调用1次,会造成某些处理不及时,一个信号来了,例如用户踩下踏板,则踏板模块
置起踏板踩下的变量标志,但缝制模块处理该信号,会等待0~2ms,等待的时间虽然不超过2ms,但仍然有
时间的不确定性。这种情况,是降低停针精度、系统控制性能无法进一步提高的原因之一。
5 会浪费一部分CPU计算能力。如下的情况,在这种架构下比较常见:固定周期到后,某个模块的函数被
调用,进入较深的层次后,检查标志后,发现没有什么事情,就退出。则无形之中浪费了CPU资源,
延缓了其他信号的的处理。
6 文档的维护比较困难。流程图比较复杂,主要的流程淹没在分支的跳转上。
看懂、看清楚比较困难。软件修改后,流程图的同步更新也比较困难。


3 期望的软件框架
我们从两个方面来谈理想的软件框架,一是软件设计过程如何划分步骤,二是理想的软件框架。两者有一定的关系,
如果软件框架在一定程度上能够反映设计步骤,则我们的框架应该是反映了软件设计的本质的,说明软件框架是正确的。
3.1 软件设计步骤
我们将软件设计过程分为如下步骤:
了解CPU + 了解控制对象 + 了解需求-> 设计流程 -> 考虑例外 -> 写成文档 -> 写成软件 -> 测试
(1) 了解CPU: 指我们要看CPU的手册,知道CPU提供了哪些硬件资源,这些资源的极限条件是多少,例如RAM多少,
Flash多少,通讯的最大速度是多少;还要了解编程环境。
(2) 了解控制对象:例如电磁铁,我们要知道吸合的延迟时间是多少,释放的延迟时间是多少,chopping
的占空比多少;对于电机来说,就是速度最高是多少,电流最大是多少,加速度是多少等等,这些都是控制对象的了解。
(3) 了解需求:需求,就是用户期望做什么。
(4) 设计流程:根据以上的内容,根据各种约束条件,为了实现用户期望的目标,我们如何设计一个过程,
来实现用户的目标。
(5) 考虑例外:这一条本来是“设计流程”的一部分,单独拿出来,是为了强调。任何流程,都有一条主线,即一般
情况是什么样的,同时,应该有例外情况的考虑。例外情况也就是相对主要情况的差异,也就是说,这里强调
使用按照差异来进行设计。
(6) 写成文档:将以上对各种了解、流程、以及例外情况,写成文档。
(7) 写成软件:软件应该是对文档的一个翻译,将文字语言(往往是更适合计算机表达的文字语言,例如流程图)
翻译成计算机的语言,例如C语言。
(8) 测试:根据测试的结果,再返回到前面的环节,做进一步的修正。
3.2 理想的软件框架
下面谈谈我们期望的软件框架。理想的框架,应该能够反映软件设计过程,解决部分原来软件框架的缺点。
(1) 软件的底层和应用达到一定的解耦。这个步骤,也是将CPU的理解,和对需求、控制对象的理解分开。
例如缝制模块,和用的CPU无关。而且底层模块,也和具体的应用没有紧密的关系。
则会增强软件的复用,使公司的投入得到最大限度的重复使用。而且,软件从一个
CPU更换到另外一个CPU也比较容易。
(2) 文档的编写和软件的编写达到更加一致的地步。一个人写完文档,另外一个人即可以根据文档实现软件。
(3) 使编程人员比较容易思考。要形成一种一致的、固定的模式让软件人员去思考,从而使软件设计人员
比较容易表达出自己对控制流程的理解。
(4) CPU的计算能力达到按需分配的地步。比较理想的是:哪个模块有事情发生,其接口就会被调用;否则,就不调用。
不会将CPU资源浪费在无效的标志查询上。
(5) 软件的设计,对测试要有支持。即用软件来测试软件,而且软件框架要能够支持这种情况,
能够比较容易插入、删除测试代码。
(6) 按照控制对象划分模块。我们去理解一个系统时,是按照控制对象为单元去理解的,例如:倒缝电磁铁、剪线电磁铁、
机头、电机、HMI,是当作一个个独立的对象去理解的,硬件人员也会这样去测试及获取这些对象的特性,但在软件
编写时,传统方式却是按照流程去控制这些对象的,将所有对象的控制混合在一个流程中,因此,有个转换的过程,
这个转换就会造成思考和编程的困难。
能否软件设计反映人理解这些对象的过程呢?即软件中也是按照对象去划分模块的,实际上面向对象
就是解决这个问题的软件思想工具。
(7) 为了解决以上问题,会消耗部分RAM和Flash,但增加的部分,应该是受控而且是可以承受的。
天下没有免费的午餐,实际上,随着CPU技术的发展,硬件资源相对宽裕
(例如28xx,它的flash和ram对平缝应用是用不完的),而软件复杂度的增加,是我们更难以控制的方面,
如何用一定的硬件资源来换取复杂度的降低,这是软件框架要做的事情。


4 我期望的编程框架
我期望的编程框架为如下方法的结合:分层、面向对象、信号驱动、状态机、模式
(1) 分层。分层的设计方法,能够隔离CPU和应用层,更换一个CPU,就不用更改缝制流程的代码了。
当然,合理的划分更多的层次,可以带来更多的好处。我一般将程序分为CPU层、驱动层、应用层。
(2) 面向对象。这是现代软件发展的方向,不仅仅是只有PC机编程可以用这种思想,单片机也一样可以用,这种思想将人去理解被控对象和编程方法一致起来,使代码的编写、维护难度都降低。这种方式的另外一个好处,促使软件人员不要将编码和对对象的理解混合在一起。
(3) 信号驱动。我们可以设想,如果一个信号来了,就去调用对应模块入口函数;信号密集,则入口函数调用得频繁;信号少,则入口函数调用频率低;没有信号,则对应的模块入口函数不会被调用;实现CPU计算能力的最大利用,按需分配计算资源。
(4) 状态机。按照状态去思考流程,会使编程人员的思维集中在当前的状态上,是程序员的思维更集中;同时,使文档的描述和代码的编写一致起来。
(5) 模式。模式是前人编程经验的总结,是软件结构的模板。信号驱动、状态机是模式当中的两个模式,是模式的子集。模式的学习相对来说有难度,但如果掌握了,按照模式的方式去思考、设计、编写软件,去思考软件框架,将会极大的促进软件质量。


总之,按照分层的方式去组织代码,按照面向对象的方式去划分模块,按照信号驱动-状态机模式去实现软件框架,将使我们的软件框架具有更好的性能、可移植性、可维护性,编码起来也更容易。