嵌入式c语言编码规范(共5篇)
李红志
程序的可读性、可扩展性、可复用性、易维护性、语法是代码的入门,算法是代码的灵魂。
第1章 编程常见错误
1.1、语法错误
1、错用函数数据类型,比如abs(x),x可能为16bit的值,如果为16bit的值,给出32bit的值就会出错。
2、内存越界访问
内存越界访问有两种:一种是读越界,即读了不属于自己的数据,如果所读的内存地址是无效的,程度立刻就崩溃了。如果所读内存地址是有效的,在读的时 候不会出问题,但由于读到的数据是随机的,它会产生不可预料的后果。另外一种是写越界,又叫缓冲区溢出,所写入的数据对别人来说是随机的,它也会产生不可 预料的后果。
3、结构的成员顺序变化引发的错误
在初始化一个结构时,老手可能很少像新手那样老老实实的,一个成员一个成员的为结构初始化,而是采用快捷方式,如:
Struct s { int l;char* p;};int main(int argc, char* argv[]){ struct s s1 = {4, “abcd”};return 0;} 以上这种方式是非常危险的,原因在于你对结构的内存布局作了假设。如果这个结构是第三方提供的,他很可能调整结构中成员的相对位置。而这样的调整往 往不会在文档中说明,你自然很少去关注。如果调整的两个成员具有相同数据类型,编译时不会有任何警告,而程序的逻辑可能相距十万八千里了。
4、栈溢出。
我们在前面关于堆栈的一节讲过,在PC上,普通线程的栈空间也有十几M,通常够用了,定义大一点的临时变量不会有什么问题。
而在一些嵌入式中,线程的栈空间可能只5K大小,甚至小到只有256个字节。在这样的平台中,栈溢出是最常用的错误之一。
1.2、编译错误 1.3、链接错误
第2章 编程知识
关键字valotile的作用是告诉编译器,不要把变量优化到寄存器里。
第3章 编程规范
1.1 整体结构
1、必须包含的两个文件:
“#include “std_inc.h”” “#include “std_defs.h””
2、一个完整的project需要有程序说明文档
3、需要有变量宏定义函数说明文档,包含变量规则命名。
4、需要有程序流程图
5、需要有硬件测试报告
6、需要有程序修改记录
7、要有软件时间控制分析
1.2 编程规范
1、定义宏定义按照功能模块来区分;
2、枚举型定义当宏定义来处理;
3、程序和数据要分开;
4、格式上要对齐;
5、空行要规范;
6、中断中调用的变量,一定要分析在计算过程中别的地方赋值是不是有非本身意义的赋值;
7、变量的意义要清晰;
8、程序要分层设计; 9、1.3 注释规范
1、变量和宏定义都要在定义的时候注释一下,作用是什么,单位,放大倍数。
2、用“#”标记需要问别人、需要改进的地方。
3、用“$”标记如果硬件改变需要进行变化的地方。
4、用“// XX”。
5、每个函数上面都要写注释;
6、程序段内不要太多的注释,多的话影响程序的可读性;
1.4 变量命名
1、变量名用小写
2、宏定义用大写
1.5 不建议使用全局变量的原因:
(1)全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元;
(2)它使函数的通用性降低了,因为函数在执行时依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件 中的变量同名时,就会出现问题,降低了程序的可靠性和通用性。在程序设计中,在划分模块时就要求模块的“内聚性”强、与其他模块的“耦合性”弱。即模块的功能要单一(不要把许多互不相干的功能放到一个模块中),与其他模块的相互影响要尽量少,而使用全局变量是不符合这个原则的。一般要求把C程序中的函数做成一个封闭体,除了可以通过“实参——形参”的渠道与外界发生联系外,没有其他渠道。这样的程序移植性好,可读性强。
(3)使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此要限制使用全局变量。
(4)如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即它不起作用。
说明:使用全局变量的作用是增加了函数间的数据联系的渠道。由于函数的调用只能带回一个返回值,因此有时可以利用全局变量增加与函数联系的渠道,从而到到一个以上的返回值。
第4章 2011-4-22:程序的矩阵化设计思想
适用于嵌入式软件设计,无操作系统,软件结构较复杂的情况。
1.6 定义
最小时延原则:软件设计过程中,在不影响其他性能的情况下,应该让数据的产生过程和使用过程之间的时延最小。
需控变量:软件运行过程中,需要控制计算顺序的全局变量。
非需控变量:软件运行过程中,不需要控制计算顺序的全局变量,比如从总线引发的中断中获取的信号。
优化矩阵:在设计函数执行顺序时,用于记录函数和函数输出变量的矩阵。1.7 软件结构的矩阵化
程序上的分层设计。层与层之间有接口。矩阵化设计。全局变量的作用范围要有设定,不能从上到下都是一种变量。分层设计后,才比较容易处理指令冲突的问题,因为指令被执行之前会有对几种指令进行判断的操作。模块化是矩阵化设计的基础,模块作为矩阵的cell,同一个层面的作为一个row,程序执行一次,就是从顶层到底层一次,只不过每次可能走的trace不同。这个trace就是程序真正运行了哪些模块。
程序应该是从模块化、发展到分层、再到矩阵。
环境识别、驾驶意图识别、干预退出预估、1.8 函数执行顺序的矩阵化
适用情况:系统信号较多,全局变量较多,在一个控制周期内,相互之间有计算先后要求。同一层次的函数较多。全局变量只在一个函数中被赋值,在多处被调用。
全局变量分为需控变量和非需控变量。
该方法是对某一层的函数进行执行顺序的设计 1.对每一个函数进行编号;
2.建立需控变量集:将每一个函数的输入全局变量和输出全局变量中的需控变量放进需控变量集。3.对需控变量集中的每个元素编号;
4.建立每个函数的输入需控变量集和输出需控变量集,变量集用需控变量集中元素编号表示;
5.逐个将函数添加至优化矩阵,每添加一个函数,调整优化矩阵,直到所有函数添加完成。得到每个函数的可存放域。
6.根据最小时延原则,调整每个函数到最优位置。7.输出可行的函数序列。第5章 编程经验
1.9 程序设计思想 控制时序的设计思想: 程序分层的设计思想: 程序的矩阵式设计思想; 变量的集中处理思想; 变量自衰减的处理思想;
估算变量的自衰减。估算变量时,由于只有满足估算条件才能进行估算,而估算条件不是持续成立的,所以只能在某些点进行估算。没有进行计算的地方,该变量就要随时间衰减,并且要给出一个health指标,表明这个被估算值的可信度。
干预退出预估的处理思想;
1.10 【2010-12-5】
1、能从CAN上获取的信号要从CAN上获取,比如发动机转速、发动机输出转矩、加速踏板位置(不知道还有用没了)、节气门开度(不知道还有用没了)、传动比(或者说档位)。
2、我觉得用115200,10ms传出100个byte没什么问题。这样的话,B+S的采集主要作用就在于同步一下压力,方向盘、横摆等信号用更高的频率采集,确认一下单片机的处理是否达到精度。
3、变量命名的规范化。全局变量中的temp,写成s32temp1,局部变量的temp,写成temp1s32.感觉不怎么好,但是总要区别一下的。
4、abs(x);的函数原型是int abs(int x)
5、尽量避免一个变量在不同程序段被幅值;
6、中断中用到的量,要小心在程序外会不会有非本身含义的短时间赋值;
7、一段代码尽量不要超过100行;
8、全局附着比局部复杂要复杂;
9、任何一段代码,要做到能用1句话描述;
10、【2011-7-4】
代码变成各种意义明确的节的优点:
1、高可靠性:每段很小,就更容易做到确认代码不会出问题,更能确认该段指令是千锤百炼的,绝对可靠的;
2、可维护性强:由于每段很小,很容易看懂,调试及修改都更方便;
3、可扩展性强:如果某一种计算有问题了,只用替换或修改某一小段,而不用到处找需要改哪些地方;
4、可复用性强:对某些小段,可能多个地方都可以用到,不用在不同的地方写很多次;
5、结构清晰:每一小段意义明确,程序结构、层次、调用关系、数据流等都更清晰;
6、可读性强:由于结构清晰,增加了可读性,另外结构清晰了,就容易写清楚注释,也增加了可读性;
7、函数无条件执行的优点:
1、结构更清晰:不用考虑是否执行了;
2、数据流更清晰:一个新的计算量由哪些变量得到,传递关系更清晰;
3、函数的模块化更好:能让函数无条件执行,表示该函数具有更高的独立性,也就是模块更完整,与其他代码的耦合程度更低,迁移更方便;
4、程序清晰之后,程序结构简单,从而增加可靠性;
5、集中处理的优点:(集中处理是只,如果一个变量的计算,在不同条件下,算法不同,那么把条件汇总到一起,在一段代码处处理这个变量)
1、结构清晰:一个变量的计算只出现在一个位置;
2、分散处理会造成同一个值在一次运算周期重复计算,后面的计算结果覆盖前面的计算结果,从而难以控制数据流;
3、【2011-7-5】
1、ESP方式的减压和泄压:开关控制方式下,两者没什么区别;
2、ABS方式的减压:减压速率和ESP减压方式差别很大;远小于ESP泄压速率,近似1/2关系;
3、Bosch 8.1的HCU,保压时有个大约90Hz的噪声,和王伟玮讨论了一下,基本上可以理解为那就是当时电机转动频率;
【2011-7-6】
1、在举升机上,两前轮确实会有转速差,并且转速差可能越来越大;
2、阀的端口,烧程序时的状态确认;没有高电平的;
3、粗略来讲,泄压速率正比于轮缸压力?
4、轮缸制动液净进入量和轮缸压力什么关系?在常用的范围内,大概是正比关系;
5、制动轮缸制动液液量增大了,谁变形了?制动盘、摩擦块、制动钳,还有谁?那个变形大?是不是制动钳>摩擦块>制动盘(最大也就0.1mm),6、主动增压时,进油速率基本恒定。HCU中的柱塞泵效率大概50%,好点儿能到60%;轮缸压力大,效率可能稍微高一点儿;轮缸压力大,电机转速稍微低一点儿。
7、【2011-7-8】
1、大型的复杂的程序,用面向对象编程效率要高得多;单就变量的private和public设定而言,就会减少很多变量赋值的误操作,相当于自动添加了一种自检验机制;其他还有很多优点。
2、应该把每个函数都做一个更新记录。这种更新记录怎么能做到比较容易看到上次的状态呢?难道只能把不同状 态都记录下来看的时候再对比?
3、【2011-7-9】
1、轴距和FMVSS126的A值之间的关系,基本上只轴距减小10%,A值减小3%(尊驰在CarSim中的仿真结果)。2DOF理论上应该成比例改变的,实际上可能悬架、轮胎的柔性有影响。
2、尊驰和C118在CarSim中仿真的A值大概都是31deg。
3、.c中的函数,必须在.h中声明,不是为了能被调用,还是为了比较直观地看到在这个.c文件中定义了哪些函数;
4、单片机上,除0,会怎样?
经测试,初步结论:正值/0 = 0xF*F,负值/0 = 1
5、坡道TCS之所以困难,就在于压力估算的偏差影响对坡度的识别,压力的持续控制也比较困难;
6、坡道对前轴载荷几乎没影响。cos(15deg)= 0.985
【2011-7-13】
1、任何一个条件执行的函数,都涉及到不满足条件时不执行了,它计算的变量清零,还是怎么处理。条件选择,都是选取一种处理方法,那么必须对任何一种处理都有对应的方法。
2、条件运算的函数改变的变量,函数不运行时也需要对变量进行赋值;函数在程序中的作用,就是为了给那几个变量赋值,不运行了,就要用其他方式赋值;
3、先分好层次,定义清楚变量和函数,画好框图再写程序;
4、定义文件之间的接口,函数之间的接口;
【2011-7-29】
1、数据后处理中用数据组合成控制信号,是不靠谱的。组合生成一些信号比较靠谱。
【2011-8-12】
1、程序要写到什么样才算好?多一个字则太多,少一个字则太少,天衣无缝,完美无暇,千锤百炼,炉火纯青。
2、一群人,怎么才能做好一个程序?首先定义清晰,规则明确,不能越俎代庖,每个人有不同的权限去维护不同的代码。每个人都要遵守其中的规则,不守规则的那个人就是系统的bug。
3、虽然说程序是调出来的,但是还是应该尽量写的时候就写完善,不能写得一塌糊涂而等调试去解决问题。写的时候,关注的只是那么几十行,而找bug的时候,关注的可是几千行,这效率能一样么?
4、大程序设计首要原则,降低各部分耦合度。
5、如果每个人负责几个文件的话,就不要轻易定义全局变量了,要尽量使用静态全局变量(作用域为本文件)。定义全局变量要先看全局变量库,并建立并进行登记。
6、以前程序很大的一个问题就是层次没分清,从而耦合度高,混乱。
7、格式上,所有的一块儿逻辑前面要有空行,比如if之类的。
8、定义一个新变量前,先检查一下是否已存在这个变量名。
9、函数中间尽量不用return,结构混乱。
10、减少调用层次;
11、程序的本质是什么?数据流;
12、函数的作用是什么?计算数据;
13、写程序的本质是什么?用矩阵化方式决定数据流的运行;
14、为什么要分层?降低耦合度;
【2012-2-5】
1、把OBJ中的一段,ID中的一段儿留给调试。也是分层的概念。
关键词:哈夫曼编码,权值,哈夫曼树,二叉树
0 引言
数据通讯中, 经常需要将传送的字符转换为由二进制字符0或1组成的二进制串, 我们称此过程为编码。而哈夫曼树可以用来构造代码总长度最短的编码方案, 将需要编码的字符作为叶节点, 字符在电文中出现的频率作为权值, 构造一颗二叉树, 规定哈夫曼树的左分支为0, 右分支为1, 则从根节点到每个叶结点所经历的分支对应的0和1组成的数列变为该结点对应的字符编码。这种总长度最短的不等长编码就叫做哈夫曼编码。利用哈夫曼编码通信可以大大提高通信利用率, 缩短通信传输时间, 降低传输成本。
1 问题描述
利用C语言编程实现哈夫曼编码。要求:用户输入各字母及使用频率 (或频数) , 用程序输出二进制表示的哈夫曼编码, 并采用菜单和会话方式的界面。
2 算法思想
(1) 哈夫曼编码根据与n个权值{w1, w2, ……wn}对应的n个结点构成n棵二叉树的森林, F= {T1, T2, ……Tn}, 其中每棵二叉树Ti (1<=I<=n) 都有一个权值为wi的根结点, 其左右子树均为空。
(2) 在森林F中选出两棵根结点权值最小的树作为一棵新树的左右子树, 且置新树的附加根结点的权值为其左右树上根结点的权值之和。
(3) 从F中删除这两棵树, 同时把新树加入F中。
(4) 重复 (2) 和 (3) 直到只含有一棵树为止, 此时便是哈夫曼树。
(5) 树从根到每个叶子都有一条路径, 对路径上的各分支约定, 指向左子树的分支表示 ‘0’ 码, 指向右子树的分支表示 ‘1’ 码 。
(6) 取每条路径上 ‘0’ 或 ‘1’ 的序列作为各个叶子对应的字符编码, 这就是哈夫曼编码。
3 逻辑设计
树的逻辑结构是层次结构, 树中有且仅有一个没有前驱的结点ht[0]称为树的根, 除根ht[0]以外的每个结点都有且只有一个前驱, 对于不是根的每一个结点ht[I]都有一个线性序列ht[0], ht[1], ……ht[I-1], ht[I] (I>=0) , 其中ht[I]是ht[I-1]的后继。
4 存储结构的设计
5 模块划分及调用关系
共划分为三大模块:建立哈夫曼树、标出路经、输出结果, 模块划分及调用关系如图1所示。
6 算法的C语言实现
7 结语
此程序是根据笔者平时积累的教学经验, 结合数据结构和C语言编程技术开发完成。该算法简单易懂, 源代码在visual C++中运行调试通过, 对哈夫曼编码理论的学习有着较大帮助。
参考文献
[1]严蔚敏, 吴伟民.数据结构:第1版[M].北京:清华大学出版社, 2003.
[2]朱站立.数据结构——使用C语言:第3版[M].西安:西安交通大学出版社, 2004.
[3]陈桂琴.用C实现完整的哈夫曼编码系统[J].河北工程技术高等专科学校学报, 2004 (4) .
从事C语言的教学也有两年了,在教学中发现学生们在编程方面有一个极不好的习惯,就是随意命名,这不仅给自己日后阅读自己程序时带来不便,也给其他的程序阅读者带来麻烦,更重要的是没有统一的规范总显得像是个游击队,没有正规军的感觉,企业也不愿意要业余选手,所以C语言的初学者最好一开始就培养一种良好的编程习惯,也许日后进入公司有些改动,需要适应,但基本的规范和规则是不需要改的,这样可以帮助你少走很多弯路,经过这些年的学习和工作,总结了一些规范的内容,为了好记,便于传播,特总结为十条,建议读者采纳。1)标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。程序中的英文单词一般不会太复杂,用词应当准确。例如不要把CurrentValue写成NowValue。
2)不允许使用汉语拼音命名,更不要使用汉语,必须使用英文来命名标识符。尽量避免名字中出现数字编号,如Value1,Value2等,除非逻辑上的确需要编号。
3)函数名、变量名从第二个单词起首字母大写。如:printName(), oldName等
4)在C 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。常量定义以大写字母K开头,字母全部使用大写,如:const int KSIZE = 100。
5)代码缩进使用4个空格,不推荐使用TAB键
6)版权和版本的声明位于文件的开头;函数头部应进行注释,列出:函数的功能、输入参数、输出参数、返回值等。关键代码注释位于被注释代码上方,且用空行与其他代码分割开,如:
文件头注释:
author: SDL team
function: testing hardware drivers and IDE
date: 2009.10
copy right: Software College Of HeBei Normal University
函数注释:
function:SDL initial
parameter: none
return: bool
true:initial SDL normally
false:initial SDL abnormally
关键代码注释:
pTemp = SDL_LoadBMP(aFileName);
//format BMP file
*aImg = SDL_DisplayFormat(pTemp);
SDL_FreeSurface(pTemp);
7)静态变量加前缀s_,如:staticints_count = 0;
8)尽量避免应用全局变量,如果有特殊情况必须定义的话,全局变量以小写g_开头,如:intg_count = 0;
9)结构体的名字开头字母要大写。如: struct Student
{
};
所以在此唠叨几句编码规范(以struts2+spring2+hibernate3架构的项目为例),大家各取所需,欢迎拍砖!
一、规范存在的意义
应用编码规范对于软件本身和软件开发人员而言尤为重要,有以下几个原因:
1、好的编码规范可以尽可能的减少一个软件的维护成本 , 并且几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护;
2、好的编码规范可以改善软件的可读性,可以让开发人员尽快而彻底地理解新的代码;
3、好的编码规范可以最大限度的提高团队开发的合作效率;
4、长期的规范性编码还可以让开发人员养成好的编码习惯,甚至锻炼出更加严谨的思维;
二、命名规范
1、一般概念
1、尽量使用完整的英文描述符
2、采用适用于相关领域的术语
3、采用大小写混合使名字可读
4、尽量少用缩写,但如果用了,必须符合整个工程中的统一定义
5、避免使用长的名字(小于 15 个字母为正常选择)
6、避免使用类似的名字,或者仅仅是大小写不同的名字
7、避免使用下划线(除静态常量等)
2、标识符类型说明
1、包(Package)的命名
Package 的名字应该采用完整的英文描述符,都是由一个小写单词组成。并且包名的前缀总是一个顶级域名,通常是 com、edu、gov、mil、net、org 等;
如: com.yjhmily.test
2、类(Class)的命名
类名应该是个一名词,采用大小写混合的方式,每个单词的首字母大写。尽量保证类名简洁而富于描述。
使用完整单词,避免缩写词(除非工程内有统一缩写规范或该缩写词被更广泛使用,像 URL,HTML)如: FileDescription
3、接口(Interface)的命名
基本与 Class 的命名规范类似。在满足 Classd 命名规则的基础之上,保证开头第一个字母为 ”I”,便于与普通的 Class区别开。其实现类名称取接口名的第二个字母到最后,且满足类名的命名规范;
如: IMenuEngine
4、枚举(Enum)的命名
基本与 Class 的命名规范类似。在满足 Classd 命名规则的基础之上,保证开头第一个字母为 ”E”,便于与普通的 Class区别开。
如: EUserRole
5、异常(Exception)的命名
异常(Exception)通常采用字母 e 表示异常,对于自定义的异常类,其后缀必须为 Exception 如: BusinessException
6、方法(Method)的命名
方法名是一个动词,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。
方法名尽可能的描述出该方法的动作行为。返回类型为 Boolean 值的方法一般由“ is ”或“ has ”来开头
如: getCurrentUser()、addUser()、hasAuthority()
7、参数(Param)的命名 第一个单词的首字母小写,其后单词的首字母大写。参数量名不允许以下划线或美元符号开头,虽然这在语法上是允许的。参数名应简短且富于描述。
如: public UserContext getLoginUser(String loginName);
8、常量字段(Constants)的命名
静态常量字段(static final)全部采用大写字母,单词之间用下划线分隔;
如: public static final Long FEEDBACK;public static Long USER_STATUS;
三、注释规范
一个很好的可遵循的有关注释的经验法则是:
问问你自己,你如果从未见过这段代码,要在合理的时间内有效地明白这段代码,你需要一些什么信息???
1、一般概念
1、注释应该增加代码的清晰度
2、保持注释的简洁
3、在写代码之前或同时写注释
4、注释出为什么做了一些事,而不仅仅是做了什么
2、注释哪些部分
1、Java 文件:必须写明版权信息以及该文件的创建时间和作者;
2、类:类的目的、即类所完成的功能,以及该类创建的时间和作者名称;多人一次编辑或修改同一个类时,应在作者名称处出现多人的名称;
3、接口: 在满足类注释的基础之上,接口注释应该包含设置接口的目的、它应如何被使用以及如何不被使用。
在接口注释清楚的前提下对应的实现类可以不加注释;
4、方法注释: 对于设置(Set 方法)与获取(Get 方法)成员的方法,在成员变量已有说明的情况下,可以不加注释;普通成员方法要求说明完成什么功能,参数含义是什么且返回值什么;另外方法的创建
时间必须注释清楚,为将来的维护和阅读提供宝贵线索;
5、方法内部注释: 控制结构,代码做了些什么以及为什么这样做,处理顺序等,特别是复杂的逻辑处理部分,要尽可能的给出详细的注释;
6、参数: 参数含义、及其它任何约束或前提条件;
7、属性: 字段描述;
8、局部(中间)变量: 无特别意义的情况下不加注释;
3、注释格式
遵循工程规定的统一注释格式,一般情况下会以 codetemplates.xml 格式的文件导入 IDE(Eclipse)或者用Eclipse默认的;
四、代码格式规范
遵循工程规定的统一代码格式,一般情况下直接使用 IDE(Eclipse)自带的默认代码格式对代码进行格式化;
五、其他规范
JSP 文件命名
采用完整的英文描述说明 JSP 所完成的功能,尽可能包括一个生动的动词,第一个字母小写,如: viewMessage.jsp、editUser.jsp 等。
六、工程特有命名规范
1、持久层
1、Hibernate 映射文件及实体
与数据库表名称完全对应;
如: Advertisement.hbm.xml、Advertisement.java
2、数据访问 DAO DAO 接口和实现类名称必须完全符合正常接口和实现类的命名规则,且最后以 ”DAO” 结尾
DAO 内的数据访问方法必须足够抽象的描述出对数据库的基本 CRUD 操作;
如: ICrossAdDAO(接口)、CrossAdDAO(实现类)
3、各种操作数据库的 HQL 配置文件
HQL 文件的个数原则上与系统的 Services 层的服务个数相等,且以服务名称命名 HQL 文件;
如: resource.hbm.xml
2、服务层
1、服务接口和实现
服务接口和实现类必须完全符合正常接口和实现类的命名规则;以工程定义的服务名为主体,并统一以 ”Serv” 结尾
如: IResourceServ(服务接口)、ResourceServ(接口实现类)
2、服务接口方法
方法名是一个动词,采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。
方法名尽可能的描述出该方法的动作行为。
返回类型为 Boolean 值:用“ is ”或“ has ”来开头
得到某数据: get+ 数据描述名词复数 + 数据类型;
得到所有数据: get+All+ 数据描述名词复数 + 数据类型;
通过 XXX 得到 / 查询某数据: get/query+ 数据描述名词复数 + 数据类型 +By+ 条件;
添加某数据: save/add+ 数据描述名词()更新某数据: save/update+ 数据描述名词; 删除某数据: delete/remove+ 数据描述名词;
3、业务对象
业务名称 +BO
4、查询参数对象
凡是继承 Abst***QuerySpec 的查询参数类全部满足以下规则:
Query+ 所要查询的数据描述名词 +Spec 作为参数传入时,参数名必须为:所要查询的数据描述名词 +Spec 如: QueryProgramSpec
3、MVC 层
1、Action 控制层
Action 类名:功能模块名称 +Action ;
Actoin 方法名称尽可能的描述出页面迁移的去向
如: LoginAction(登录用 action),toWelcome(转向欢迎页的 action 方法)
2、资源文件
系统全局资源文件: globalMessages_+ 字符编码类型 +.properties 功能模块内部的资源文件: package.properties
4、Spring 配置文件
1、Action 相关配置文件
文件目录: WebRoot/WEB-INF/spring/action/ 功能模块名称 +_ApplicationContext.xml
2、Services 相关配置文件
文件目录:
WebRoot/WEB-INF/spring/services/Services_ApplicationContext.xml
3、全局性配置文件
文件目录: WebRoot/WEB-INF/spring/工程名+_ApplicationContext.xml
5、JSP 文件
自1978年AMI公司发布世界上第一个单片DSP芯片及1980年日本NEC公司推出第一块单片DSP器件以后, 美国TI公司于1982年推出了第一代DSP芯片即TMS32010系列, 到目前为止已研发了第六代DSP芯片——TMS320C62X/C67X、TMS320C64X等;而美国Analog Device公司也推出了一系列有自己特色的定点、浮点的DSP芯片。随着芯片生产技术的发展, DSP嵌入式系统也相应得到大力发展, 无论是国际或是国内, 对于DSP系统的研发都有了一定成就。
1.1 国外发展现状
最早的DSP嵌入式系统是从国外发展起来的, 而且随着国外先进技术的迅速发展, 国际DSP系统始终保持着良好的发展势头, 尤其是以欧美为主的国际市场, 发展极其迅猛。如美国的Pentek公司、DSP research公司、Motorola公司以及加拿大的Dy4公司等, 都是发展规模相当大的DSP生产公司, 很多DSP系统的情况都可以从这些知名公司推出的产品信息来获得。比如说Pentek公司的4293处理板, 用8片TI公司生产的300MHz、有19200MIPS处理能力的TMS320C6203芯片, 集成了同等数量的32M同步动态随机存储器 (SDRAM) , 而数据吞吐为每秒600M。
上个世纪80年代以来, DSP系统随着数字信息处理技术的发展被迅速推入市场, 伴随着日趋激烈的竞争, 各DSP生产公司不断调整、优化发展规划, 深化了DSP系统产业化进程, DSP系统进入产业化是DSP应用程序成功的一个重要标志。
1.2 国内发展现状
近些年来, 随着我国信息技术产业的飞速发展, DSP嵌入式系统也有了较好的发展, 并已被我国数字信号处理、数字通信、雷达以及图像处理等高科技领域广泛应用, 为我国高新技术产业乃至整个国民经济发展做出了很大贡献。
目前, 我国许多高校以及科研机构都在致力于DSP嵌入式系统的研发, 同时取得了相当大的成就。但是, 我国主要的核心处理器件几乎都是从国外进口, 相较于国际先进技术水平, 我国在数字信号处理理论方面以及对高速率、高性能处理器的设计和制造方面都还有很大差距。因此, 我国在半导体研究领域更要投入大量的研发力度、人才及资金等, 这就要求我国科研人员要有敢于拼搏、艰苦奋斗的精神和坚持不懈的毅力。
2 DSP嵌入式系统应用情况
目前, 全球生产DSP的公司有80多家, 而生产出来的DSP芯片也多达300多种。生产DSP的公司主要有TI公司、Lucent公司、Analog Device公司以及Motorola公司, 其中TI公司以及AD公司极具代表性, 被以高新技术生产领域为主的各个生产领域广泛使用。
自从TI公司研发了第一代DSP芯片以来, 其在业界始终处于领军地位, 尤其是到现在为止生产到第六代DSP芯片系列, 都促进了DSP系统的发展。其中以:TMS320C2000、TMS320C5000和TMS320C6000系列被我国引进并广泛投入数字信号处理领域。其中TMS320C2000系列的高性能、高效率被广泛应用于工业控制领域, 该系列处理控制能力强外, 还提供了方便与高性能外围器件相连的接口, 其主要型号有TMS320C24X/28X系列;TMS320C5000系列性能高但功耗低, 最低功耗可以达0.33mA/MHz, 而最高达到900MIPS的处理速度, 适用于移动、手持系统, 其主要有TMS320C54X/55X系列型号;TMS320C6000系列可以说是高端DSP系统的代表, 其浮点运算可达600~1 800MFLOPS、定点运算可达1 200~8 000MIPS的运算速度, 其中浮点系列主要型号为TMS320C64X, 是TI公司最新研发的高性能定点DSP处理器, 浮点系列主要型号为TMS320C67X。
另外一个DSP生产势头良好并发展迅速的是美国AD公司, 其所生产的DSP系统主要有SHARC、TigerSHARC以及Blackfin系列。其中SHARC系列被广泛应用于商用或军用雷达、声纳信号处理等领域, 虽然其单片处理能力不高, 但连接组成DSP阵列便能提高速率及性能;而从SHARC改进的TigerSHARC为高端DSP, 其不仅处理能力极高, 而且有容量极大的随机存储器 (RAM) , 适用于软件无线电领域;至于Blackfin则是功耗低但性能高的DSP, 适用于便携式的通信产品。
我国某高校研发的基于TMS320C6201的高速实时DSP处理平台, 其允许输入数据的动态范围为16比特, 若512点的FFT可以在59微秒内完成, 若是1 024点的FFT, 也可以在130微秒内完成。我国某电子技术研究所研发的DSP雷达数字信号处理通用模块用6片美国AD公司生产的ADSP21060芯片和大量可编程器件构建而成。以快速傅里叶变换 (FFT) 算法来看, 以FFT、IFFT及复数乘法3个流水处理过程实行DSP组成的并行处理, 若在33MHz的时种下, 0.7毫秒就可以实现1 024点处理, 而实现的单通道数据率是1MHz, 双通道的并行工作率是2MHz。
3 C语言开发下DSP系统应用技术分析
TI公司DSP芯片的硬件编程主要有:用汇编语言、用C语言及用DSP/BIOS可视化编程工具。其中汇编语言程序指令不易读懂, 且通用性极差, 而对于底层的硬件控制, DSP/BIOS可视化编程工具又显得极为抽象难懂, 相较于此二者, C语言适当平衡了二者的优缺点。首先, 它作为一种高级语言, 以其自上而下的模块化设计原则发挥了可移植性强、易读懂的优势, 其次, 它可以取代汇编语言的硬件控制能力, 极细致地改写硬件寄存器数值。
本文以TI公司生产的TMS320VC33为例, 介绍C语言开发下的DSP嵌入式系统在TI公司提供的与DSP芯片相匹配的软件集成开发环境Code Composer下的研发技术情况。
对TMS320VC33芯片的C语言开发, 主要从以下几个步骤来实现:
(1) 编辑C语言源程序。
在Code Composer环境下, 新建一个CSRJ.MAK工程, 然后再新建一个以C语言源程序为内容的C源代码文件CSRJ.C以及一个程序设计时对TMS320VC33寄存器定义的头文件VC33.H, 并将这两个文件添加到CSRJ.MAK工程。
(2) 编译和链接。
Code Composer环境下的汇编器及编译器建立的公共目标文件格式COFF极易于实行模块化编程, 而且提高了编写程序的可读性及可移植性, 使代码段以及存储器的管理更加灵活而有力, 也提高了C语言程序编写的便捷性。公共目标文件格式中最小单位段在COFF目标文件中是及其重要的, 它在存储器中占据着连续空间的数据块或代码。而链接器对段的处理主要是将公共目标文件中建立起的数据块以及程序块组合成可以被DSP芯片执行的COFF输出模块以及为每一个输出块指定存储地址。以下是—个TMS320VC33芯片的被命名为CSRJ.CMD的典型CMD文件:
(3) 在线仿真。
连接仿真器与目标板。打开Option菜单下的Program Load选项, 将所有选项全选, 若要编译或载入链接生成的CSRJ.OUT文件, 单击界面上Rebuild All按钮即可, 而单击界面上的Run按钮, 则为仿真运行。
(4) 固化程序。
TMS320VC33芯片要存储固化程序, 通常是外挂FLASH或EPROM, 也就是说, 固化程序前要按照外挂的具体要求, 把CSRJ.OUT文件转换为相应的格式, 然后将其写入FLASH或EPROM。
4 DPS系统发展趋势
首先, 目前生产的DSP主要基于精简指令集 (RISC) 结构, 具有功耗低性能高并且尺寸小的优点, 将MPU核、DSP核、专用处理单元以及外围电路单元并存储单元汇集在一个芯片上, 向着集成DSP方向发展是未来DSP系统的一个发展趋势;其次, 会在高性能处理器占主要地位的为单指令多数据流 (SIMD) 和多通道结构、超长指令字结构 (VLIM) 、多流水标量结构以及可并行的超级哈佛结构;并且, 为使DSP系统在各个生产、生活领域更方便应用, 进一步降低功耗和尺寸, 提高速率及性能, 尤其是便携式手持系统方面的应用, 更应在保证性能的基础上注重减小尺寸;最后, 可与可编程器件形结合, DSP系统在实际应用时经常需要借助其他器件, 比起单独的DSP系统应用, 能够更好地提高工作速率。
5结语
综上所述, 数字信号处理 (DSP) 系统在科学技术与社会经济发展中起着不可替代的作用, DSP处理器不仅速率快、性能高, 而且功耗低、尺寸小, 被许多高新技术产业广泛认可并大规模投入应用。而相较于汇编语言编写的DSP应用程序, 用高级C语言研发的DSP嵌入式系统可移植性高、可读性强, 并且易于修改及维护。因此, 以高级C语言编写的DSP应用程序有很大的可开发性, 是以后DSP系统的重要发展方向, 对高新技术产业乃至于整个国民经济建设的发展有极大的促进作用。
摘要:嵌入式系统已随着芯片制造技术的发展在计算机应用领域占有一席之地, 并成为计算机领域的一个重要的发展方向。当前, 很多嵌入式系统的开发都是以数字信号处理器 (DSP) 为核心研发DSP嵌入式系统。而用汇编语言研发DSP系统存在着一些如开发难度大、周期长及维护性极差等问题, 但若是用高级语言C语言编写的DSP应用程序, 有很高的可读性和可移植性, 并且易于维护及修改。从DSP嵌入式系统的发展现状、应用情况、研发技术以及发展趋势等方面对C语言开发下的DSP嵌入式系统进行了论述。
关键词:C语言,DSP,嵌入系统
参考文献
[1]周华.DSP嵌入式系统下的C语言开发[J].中国高新技术企业, 2010 (8) .
[2]李从宇, 王宝光.嵌入式DSP系统C语言硬件编程技术[J].测控技术, 2007 (4) .
[3]苏延川.基于ADSP-TS101的嵌入式系统混合编程及优化方法[J].现代电子技术, 2009 (20) .
[4]胡世锋, 张海涛.用C语言实现DSP程序设计的新方法[J].河北北方学院学报, 2009 (3) .
[5]张晓林, 路程, 崔迎炜.DSP技术的应用现状和发展[J].测控技术, 2004 (21) .
[6]顾颖.浅谈如何借鉴MISRA规范减少DSP程序设计的隐患[J].信息化研究, 2009 (10) .
[7]常丹华, 贺树猛.基于DSP的嵌入式视频监测系统的设计与实现[J].电子技术, 2009 (3) .
[8]肖宛昂, 曾为民.如何用C语言开发DSP嵌入式系统[J].单片机与嵌入式系统应用, 2003 (1) .
【嵌入式c语言编码规范】推荐阅读:
嵌入式毕业论文:嵌入式系统的应用06-19
嵌入式培训总结06-17
实习总结嵌入式11-11
嵌入式系统开发试题07-19
嵌入式开发学习心得11-16
嵌入式应用实践总结12-17
嵌入式软件简历下载01-10
嵌入式系统试题库09-20
构建嵌入式linux系统10-25