Linux系统编程

2024-11-30

Linux系统编程(精选9篇)

Linux系统编程 篇1

一、Linux系统的特点

(1) 系统的尺寸较小。Linux系统的尺寸小是因为系统本身的Flash决定, 大部分系统只有几兆的Flash, 掌上电脑的Linux系统也不超过几十兆, 所以系统的尺寸必须要小。控制系统的尺寸可以从下面两方面出发:一方面是系统的内核, 一般Linux系统的内核只有1兆左右, 要想提高系统工作的效率, 应该制定更为小巧的内核;另一方面是窗口系统, Linux桌面上包含很多的图形窗口, 这些也会占据系统的内存, 所以应该设置小巧的图形窗口来加快系统的运行速度。

(2) 支持标准的系统调用。Linux系统是UNIX系统的克隆, 也实现了POSIX标准, 大部分的UNIX程序可以直接转移到Linux中, 再加上系统本身能够免费下载大量的资料, 使得这种系统受到越来越多用户的欢迎。Linux系统对于标准化的系统调用不用进行修改, 可以直接使用那些免费的软件, Linux上开发的软件也可以直接在系统中使用, 为系统的运行提供了有利的条件。

(3) 能够支持特殊的硬件设备。Linux系统中经常会使用不同的硬件设施, 但是系统本身并不具有键盘和鼠标等硬件, Linux可以直接用触屏和按键代替, 一般的掌上电脑都需要进行电源管理, 所以在Linux在操作的过程中还需要增加这方面的内容, 改变了原本的系统。

(4) 文件系统。系统启动后, 内核以及所有应用程序都需要Linux支持, 不同设备使用的文件系统也不相同, 所以需要对不同的文件进行编程。每个文件应该有对应的程序, 这样才能保证文件在使用的过程中不会出现差错。

二、Linux系统下的文件编程和时间编程

2.1文件编程

文件编程的方式可以分为系统调用和C库函数, 系统调用依附于系统本身, 但是C库函数可以单独使用。

(1) 系统调用。首先是创建文件, 常见的文件创建模式可以分为可读、可写以及可执行三种, 同时还可以利用数字来设置文件的权限;其次是对文件进行描述, 系统中每一个文件都对应一个描述符, 通过描述符来打开文件, Linux系统可以打来1024个文件;然后是关闭文件, 阅读完文件后系统会自动关闭文件, 关闭的文件也会有相应的描述符;最后是定位文件, 定位文件可以通过文件开头、结尾以及读写指针指示的位置。定位文件可以将whence移动offset个字节, 操作完成后, 文件指针会自动回到文件的开头, 要判断文件能否进行读、写等操作时, 可以使用access函数, 可以设置文件可读、文件可写、文件可执行以及文件存在等来设置权限。

(2) C库函数。C库函数的文件操作可以独立存在, 不用依靠Linux系统。首先是创建和打开文件, 打开的方式主要有只读打开和只写打开, 如果文件没有反应就需要重新创建, 不同的文件打开和创建的方式也有一定的区别。系统在编写程序时, 应该确定文件的路径, 这时候C库函数会利用getcwd来确定文件的路径。创建和打开文件之后就是建立目录, 将系统中不同的文件整理在一起, 方便使用。

2.2时间编程

Linux系统在操作的过程中经常会用到系统的输出时间、程序的执行时间以及延长的时间等等, 所以应该进行时间编程。系统中的时间可以分为世界标准时间和日历时间, 不同的时间参照的标准也不一样。Time的目的是为了获取日历时间, 计算系统从开始到结束的时间, 还可以利用gmtime将日历时间转化为世界标准时间, 转为世界标准时间后系统会保持TM结构, TM结构的时间会显示为字符。实行时间编程最主要的目的是为了促进系统的正常运行, 保证系统的安全。

三、总结

Linux系统是计算机信息技术发展的产物, 能为用户提供更多的信息资源, 它具有灵活性、小巧、方便使用等优势, 但是在实际的应用中还是要注意文件的时间的编程。但是完善后的Linux系统能够同时支持1024个文件的使用, 在同一条件下能够为用户提供更多的信息。在文件编程中也需要处理好世界标准时间与日历时间的关系, 特定的情况下还可以延迟程序的执行, 保证系统运行的安全。

参考文献

[1]丁德文.Linux系统下的文件与时间编程[J].电子世界, 2013 (1)

[2]郑仕碧.基于嵌入式Linux的数据采集系统关键模块设计[D].电子科技大学, 2013

[3]赖明壮.基于PowerPC的嵌入式Linux系统平台的应用和实现[D].成都理工大学, 2012

[4]李杰.Linux环境下FTP系统的设计与实现[D].吉林大学, 2012

Linux系统编程 篇2

A: 这里的简单命令和bash参考手册里的含义相同,形式上一般是:命令的名称加上它的参数。有三种不同的简单命令:

1.内置命令(builtin)

是shell解释程序内建的,有shell直接执行,不需要派生新的进程。有一些内部命令可以用来改变当前的shell环境,如:

cd /path

var=value

read var

export var

...

2.外部命令(“external command” or “disk command”)

二进制可执行文件,需要由磁盘装入内存执行。会派生新的进程,shell解释程序会调用fork自身的一个拷贝,然后用exec系列函数来执行外部命令,然后外部命令就取代了先前fork的子shell。

3.shell脚本(script)

shell解释程序会fork+exec执行这个脚本命令,在exec调用中内核会检查脚本的第一行(如:#!/bin/sh),找到用来执行脚本的解释程序,然后装入这个解释程序,由它解释执行脚本程序。解释程序可能有很多种,各种shell(Bourne shell,Korn shell cshell,rc及其变体ash,dash,bash,zshell,pdksh,tcsh,es...),awk,tcl/tk,expect,perl,python,等等。在此解释程序显然是当前shell的子进程。如果这个解释程序与当前使用的shell是同一种shell,比如都是bash,那么它就是当前shell的子shell,脚本中的命令都是在子shell环境中执行的,不会影响当前shell的环境。

Q2: shell脚本是否作为单独的一个进程执行?

A: 不是,shell脚本本身不能作为一个进程。如上面讲的,shell脚本由一个shell解释程序来解释、运行其中的命令。这个shell解释程序是单独的一个进程,脚本中的外部命令也都作为独立进程依次被运行。这也就是为什么ps不能找到正在运行的脚本的名字的原因了。作为一个替代方案,你可以这样调用脚本:

sh script-name

这时shell解释程序“sh”作为一个外部命令被显式地调用,而script-name作为该命令的命令行参数可以被我们ps到。

另外,如果你的系统上有pidof命令可用,它倒是可以找出shell脚本进程(实际上应该是执行shell脚本的子shell进程)的进程ID:

pidof -x script-name

Q3: shell何时在子shell中执行命令?

A: 在此我们主要讨论Bourne shell及其兼容shell。在许多情况下shell会在子shell中执行命令:

1.(...)结构

小括号内的命令会在一个子shell环境中执行,命令执行的结果不会影响当前的shell环境。需要注意是此时变量$$会显示当前shell的进程id,而不是子shell的进程id。

参考:{...;}结构中的命令在当前shell中执行,(内部)命令执行的结果会影响当前的shell环境。

2.后台执行或异步执行

command&命令由一个子shell在后台执行,当前shell立即取得控制等候用户输入。后台命令和当前shell的执行是并行的,但没有互相的依赖、等待关系,所以是异步的并行。

3.命令替换

command`(Bourn shell及兼容shell/csh),$(command)(在ksh/bash/zsh中可用)将command命令执行的标准输出代换到当前的命令行。command在子shell环境中执行,结果不会影响当前的shell环境。

4.管道(不同的shell处理不同)

cmd1和cmd2并行执行,并且相互有依赖关系,cmd2的标准输入来自cmd1的标准输出,二者是“同步”的。对管道的处理不同的shell实现的方式不同。在linux环境下大多数shell(bash/pdksh/ash/dash等,除了zshell例外)都将管道中所有的命令在子shell环境中执行,命令执行的结果不会影响当前的shell环境。

Korn shell的较新的版本(ksh93以后)比较特殊,管道最后一级的命令是在当前shell执行的。这是一个feature而非BUG,在POSIX标准中也是允许的。这样就使下面的命令结构成为可能:

command|read var

由于read var(read是一个内部命令)在当前shell中执行,var的值在当前shell就是可用的,

反之bash/pdksh/ash/dash中read var在子shell环境中执行,var读到的值无法传递到当前shell,所以变量var无法取得期望的值。类似这样的问题在各种论坛和news group中经常被问到。个人认为command|read var的结构很清晰,并且合乎逻辑,所以我认为Korn shell的这个feature很不错。可惜不是所有的shell都是这样实现的。:(如开源的pdksh就是在子shell执行管道的每一级命令。

Korn shell对管道的处理还有一个特殊的地方,就是管道如果在后台执行的话,管道前面的命令会由最后一级的命令派生,而不是由当前shell派生出来。据说Bourne shell也有这个特点(标准的Bourne shell没有测试环境,感兴趣的朋友有条件的可以自行验证)。但是他们的开源模仿者,pdksh和ash却不是这样处理。

最特殊的是zshell,比较新的zshell实现(好像至少3.0.5以上)会在当前shell中执行管道中的每一级命令,不仅仅是最后一条。每一条命令都由当前shell派生,在后台执行时也是一样。可见在子sehll中执行管道命令并不是不得已的做法,大概只是因为实现上比较方便或者这样的处理已经成为unix的传统之一了吧。;-)

让我们总结一下,不同的shell对管道命令的处理可能不同。有的shell中command|read var这样的结构是ok的,但我们的代码出于兼容性的缘故不能依赖这一点,最好能避免类似的代码。

5.进程替换(仅bash/zsh中,非POSIX兼容)

<(...)

>(...)

与管道有点类似,例子:cmd1 <(cmd2) >(cmd3), cmd1, cmd2, cmd3的执行是同步并行的。

<(command)形式可以用在任何命令行中需要填写输入文件名的地方,command的标准输出会被该命令当作一个输入文件读入。

>(command)形式可以用在任何命令行中需要填写输出文件的地方,该命令的输出会被command作为标准输入读入。两种形式中的command都在子shell环境中执行,结果不会影响当前的shell环境。

6.if或while命令块的输入输出重定向

在SVR4.2的Bourne shell中对此情况会fork一个子shell执行if块和while块中的命令;在linux下似乎其它的shell中都不这样处理。

7.协进程(ksh)

只有Korn shell和pdksh有协进程的机制(其它shell中可以用命名管道来模拟)。类似于普通的后台命令,协进程在后台同步运行,所以必须在子shell中运行。协进程与后台命令不同的是它要和前台进程(使用read -p和print -p)进行交互,而后者一般只是简单地异步运行。

Q4: 既然在当前shell中执行命令也会派生子shell,那么它与在子shell中执行命令又有什么区别呢?

A: 这种说法不准确。

在当前shell中执行内部命令不会派生子shell,因此有些内部命令才能够改变当前的shell执行环境。

在当前shell中执行外部命令或脚本时会派生子shell,所以这时命令的执行不会影响当前 的shell环境。注意:子shell中执行的内部命令只会改变子shell的执行环境,而不会改变当前shell(父shell)的环境。

Q5: 怎样把子shell中的变量传回父shell?

A: 例如(echo “$a”) | read b不能工作,如何找到一个替代方案?下面给出一些可能的方案:

1.使用临时文件

...

#in subshell

a=100

echo “$a”>tmpfile

...

#in parent

read b

2.使用命名管道

mkfifo pipef

(...

echo “$a” > pipef

...)

read b

3.使用coprocess(ksh)

( echo “$a” |&)

read -p b

4.使用命令替换

b=`echo “$a”`

5.使用eval命令

eval `echo “b=$a”`

6.使用here document

read b <`echo “$a”`

END

7.使用here string(bash/pdksh)

read b <<<`echo “$a”`

8.不用子shell,用.命令或source命令执行脚本。

即在当前shell环境下执行脚本,没有子shell,也就没有了子shell的烦恼。:)

Linux系统编程 篇3

CDIO代表构思(Conceive)、设计(Design)、实现(Implement)和运作(Operate),它以产品研发到产品运行的生命周期为载体,让学生以主动的、实践的、课程之间有机联系的方式学习工程。

CDIO教学模式本身具有与“实际产业需求、实际教学基础”天然密切关联。如何将CDIO通用标准与国内甚至是院校的具体实际相结合,是CDIO模式与实际工作进行平稳联接的关键。为此,我院借鉴兄弟院校大连东软信息学院TOPCARES-CDIO模式,组织CDIO开展运行。

Linux系统编程是嵌入式软件开发专业的一门专业课程,需要学习者有较强的综合理论知识和动手实践能力。该文以该课程为例,从三个不同的视角回答工程教育的两个核心问题:

1)当工科学生毕业时,他们学到的全部知识、能力和态度应该有哪些?掌握的水平如何?

2)如何能更好地保证学生学习到这些知识和能力。

1 Linux系统编程教学大纲

CDIO教学大纲,就是要建立一个清晰、完整、系统和详细的工程教育目标;它是一系列关于知识、能力及态度的主题内容,这些内容与当代工程实践标准是一致的;它是合理设计课程计划和进行评估的重要基础;它是由利益相关者(在校生、教职工、校友及工业界等与工程教育的直接相关者)对一系列教学效果提出的要求。

作为对CDIO能力指标的继承和创新,TOPCARES能力指标与CDIO能力大纲具有一致性。它包括8个一级能力指标,32个二级能力指标及110多个三级能力指标。

我院在各相关利益人的参与下制定了嵌入式软件开发方向专业以培养目标:即,培养嵌入式软件工程师。以TOPCARES为核心培养能力,采取“133”的模式,实施以嵌入式系统、嵌入式软件产品的构思、设计、实施、运行全生命周期为背景的工程教育。

在专业培养目标的指引下确定了本专业的一、二级项目,进而确定三级项目并形成专业鱼骨图,其中三级项目对应某门具体的课程。并将TOPCARES的能力指标分配到各个具体的项目中。Linux系统编程课程的培养目标是掌握Linux平台的文件、目录、进程(线程)、进程间通信、及网络与驱动程序设计相关的编程理论和方法。该课程对应的能力指标体系如表1所示(这里只列举一、二级能力指标)。其中编号保持与专业培养目标的能力体系编号一致。

2 教与学

CDIO是“做中学”和“基于项目教育和学习”的集中概括和抽象表达。在Linux系统编程课程教学中,把课程内容及各能力指标分布到项目的各个模块来完成。以“Linux网络数据传输”作为与课程对应的三级项目,该项目又由8个具体的4级项目组成,这些四级项目名称及内容如表2所示,对应课程的具体章节。

下面以“Linux网络数据传输”项目为例,探讨CDIO在Linux系统编程课程中的应用。

依据CDIO的标准,课程实践项目的实施主要分为以下几个阶段:

1)明确项目任务,构思设计方案

教师首先提出项目的功能及参考设计方案。各项目组在明确相关理论知识的前提下,根据具体的要求提出自己的解决方案,并对方案进行细化以及任务分工,进而确定项目的进度安排。在这一阶段,教师主要担当项目客户及项目经理的角色,提出项目要求并对解决方案提出修改建议。

2)学科体系知识的综合准备

根据三级项目分解的具体知识体系,并把这些知识体系分解成对应的四级项目。以递进的方式完成这些四级项目及相关理论知识的学习。在这一阶段教师主要担当指导者的角色,指导、组织学生学习及对解答疑难点。

3)项目开发

在这一阶段主要是完成项目的编码及调试。项目组依据第一阶段的分工,各成员并不是独立完成各自的任务,他们之间根据角色的不同(在不同的项目中各个组员担当不同的角色)存在相互协调及沟通。在这一阶段,教师主要担当老板及指导者的角色,督促按计划完成,并指导相关内容。

4)项目评估

项目完成后,项目组须提供相关的设计及使用文档,学生也须对自己的工作进行自我评估及总结。在这一阶段,教师主要担当一个苛刻的客户,对没按自己要求完成的地方提出质疑甚至要求重新开发。

3 学习评估

学习和评估是相辅相成的,许多同学都建议在课程早期设定一个评估任务以及定期在课程中设置评估任务、为评估建立明确的标准。CDIO教学模式的评估是以学习为中心的,也就是说,他是整个教学过程中的一个部分,在学生和教师共同学习的氛围中促进学习。为促进学生进行自我评估,我们在各个项目中都设有学生自我评估条目。如:

1)阐述你对项目要求的认识。对项目中难于理解的问题,你是如何解决的?

2)在本项目实践中,你运用了哪些知识,对于其中的新知识,你是如何进行学习的,与之前的学校方法相比有没有提高。

3)你理解和编制了哪些项目文档,这些文档重要吗?为什么?在编码的过程中你是严格按照这些文档来编写代码的吗?

4)你是如何制定计划的,在项目进行过程中,你有没有严格按照这一计划来执行。

等学生在完成具体的项目后,都要对这些问题进行交流及整理,并作为课程考核的一部分。

4 结束语

Linux系统编程课程是系统性、实践性较强的课程,要求学生有较强的代码编写能力及操作系统背景知识。通过在近年的教学中引入CDIO理念,采用“做中学”和“基于项目教育和学习”方式与学生实时的自我评价(包括知识和能力的评价)相结合。提高了学生的学习积极性,较好的完成了本课程的教学目标。不但培养了学生的理论知识,也培养了学生的实践能力,得到学生和专家的好评。

摘要:CDIO是“基于项目学习”的一种国际通用标准。该文以Linux系统编程课程为例,从大纲、项目教学、学习评估三个角度介绍了如何将这种通用标准本地化,从而使其符合工程人才培养规律。

关键词:CDIO,Linux系统编程,本地化

参考文献

[1]顾佩华,沈民奋,陆小华,译.重新认识工程教育——国际CDIO培养模式与方法[M].北京:高等教育出版社,2009.

[2]顾佩华,沈民奋,李升平,等.从CDIO到EIP-CDIO:汕头大学工程教育与人才培养模式探索[J].高等工程教育研究,2008(1):12-20.

[3]王旃.基于约束条件的CDIO渐进部署模式研究[J].高等工程教育研究,2009(5).

[4]万金华.基于CDIO模式的综合训练项目的探索[J].现代企业教育,2009(2):103-105.

Linux系统编程 篇4

1. 输入源代码

2. 编译,链接,运行

3. 调试程序

我们从最基本的 hello world 程序开始,实际操作一下:

1. 输入源代码

$ emacs hello.c>>>>进入emacs 编辑器环境

#include tdio.h>>>>如果你看不懂这个函数,就去好好的看c语言的书

int main()

{

printf(“Hello World. ”);>>>>Emacs环境下,按下 Tab 键,有自动缩进功能

exit(0);

}

完成输入后,按住CTRL 键,按下 x, 再按下 c , 最后松开 CTRL,

Linux下C编程从头来Linux

>>>>程序保留并退出emacs 环境。

2. 编译,链接,运行

引用

$ gcc Co hello hello.c

$ ./hello>>>>./ 指明了所执行程序的路径

Hello World.

$

一个linux平台上的c程序开发已经完成咯

3. 调试

如果要使用 gdb 调试程序,那么在上一步编译的时候,记得加上 Cg 选项

引用

$ gcc Cg Co hello hello.c

$ gdb hello>>>>进入 gdb 调试环境

Linux系统编程 篇5

1 C语言的定义及优缺点

1.1 C语言的定义

C语言作为一种结构化语言, 主要起到人类与计算机“交流”的作用, C语言可看作是最接近人类思维的语言, 也最经典的数据结构语言、最基础的软件设计语言。C语言层次清晰, 既具有高级语言的特点, 同时又具有汇编语言的特点。C语言可以作为系统设计的语言, 用来编写工作系统应用程序, 也可作为应用程序设计语言, 用来编写不依赖计算机硬件的应用程序。因此, 也使得C语言的应用范围广泛, 其不仅应用于软件开发方面, 各类科研项目也均需要C语言, 例如单片机及嵌入式系统等硬件方面便可以用C语言来开发[1]。

1.2 C语言的优点

C语言的优点诸多, 最主要的优点体现在如下几方面:

1) 灵活方便。C语言共有32个关键词和9种控制语句, 程序书写形式自由, 主要应用小写字母来表示, 具有简洁紧凑、灵活方便的应用优点。

2) 数据结构丰富。C语言的数据类型主要包括有字符型、实型、整型、结构体类型、指针类型、数组类型、共用体类型等几类。通过对以上数据类型的灵活应用, 可以实现各种复杂的数据结构运算。

3) 运算符丰富。C语言共有34例运算符, 运算符包含范围极为广泛, C语言可将赋值、括号、强制类型转换等都作为运算符进行处理, 从而使C语言的运算类型丰富, 表达式类型多样化。

4) 语法限制不严格。虽然C语言属于强类型语言, 但它的语法限制不太严格, 语法比较灵活, 使程序编写人员拥有较大的自由度。

5) 目标代码生成质量高。C语言生成的目标代码质量高, 程序执行效率高, 通常情况下, 其只比汇编程序生成的目标代码效率低10~20%左右, 由于C语言目标代码生成质量高, 也使得它在编程中得到了广泛的应用。

6) 直接操作性强。C语言允许直接访问物理地址, 可以对硬件进行直接操作, 由此可见, C语言既具有高级语言的功能, 也具备低级语言的诸多功能, 可以像汇编语言一样, 对位、字节与地址进行操作。

7) 可移植性好。C语言可适用于多个操作系统, 例如UNIX、DOS系统, 均可进行计算机C语言编程, C语言还适用于多种机型, 给编程人员提供了极大的方便。此外, C语还具有强大的绘图功能及数据处理能力, 可移植性好, 适用于编写系统软件、二维、三维图形及动画。

8) 属于结构式语言。C语言属于结构式语言, 该语言的显著特点是数据以及代码的分隔化, 即是指程序的各部分除了一些必要的信息交流外, 可处于彼此独立的状态。

1.3 C语言的缺点

在实际的编程应用中, C语言的缺点主要体现在两个方面:其一, C语言的主要缺点表现在数据的封装性上, 这一点导致C语言在数据的安全性方面存在较大的缺陷, 这也是C与C++的一大区别;其二, C语言的第二大缺点体现在程序的安全性上, 由于C语言的语法限制不太严格, 对变量的类型约束不严格, 由此影响了程度的安全性, 对数组下标越界不作检查等。由于以上两方面缺点, 导致C语言在实际应用中比其他高级语言较难掌握, 因此编程时也应该提高对C语言缺点的重点, 并采取科学、合理的措施有效规避缺点导致的不良影响。

2 Linux系统下计算机C语言的编程技巧分析

文章就以Linux系统为例, 综合C语言的优缺点, 分析总结Linux系统下计算机C语言的编程技巧, 以供参考。

2.1 源程序的编译

在Linux系统下进行C语言源程序编译时, 必须要使用到GNU的gcc编译器, 因此, 编程人员首先要学会灵活使用gcc编译器编译源程序。虽然gcc编译器有很多种选项, 但一般来说, 编程人员只了解其中最主要的几个选项, 便可编译自己所写的简单的源程序, gcc编译器的主要选顶表现在三下方面:其一, 要求gcc编译器进行编译时, 需要将程序以后在进行相关调试信息提供时, 采用-g选项来表示;其二, 要求输可以进行执行文件名时, 采用-o选项来表示;其三, 要求gcc编译器需要将相应的目标代码输出时, 采用-c选项来表示。

假设, 有一个非常简单的源程序:

对上述源程序进行编译时, 编程人员只需在命令下执行gcc -o hello hello.c, gcc hello/

编译器便会为我们生成一个可执行文件 , 执行hello便可看到程序的输出结果。上面的命令行中, gcc代表编程人员选择gcc编译器进行编译源程序, -o选项代表编程人员要求编译器输出的可执行文件名为hello, 而hello.c, 便是所需要的源程序文件。

如果编程人员Linux系统下进行计算机C语言编程时, 还需要在应用gcc编译器中的更多选项, 可以通过查看gcc编译器的帮助文档来获得其它选项的详细说明[2]。

2.2 程序库的链接

以下面程序为例:/* temp.c */#include <math.h>

尝试编译上面程序可发现, 该程序十分简单, 但是, 若编程人员采用gcc -o temp temp.c编译时, 会出现如下提示的错误信息:

导致错误信息出现的原因, 主要是因为编译器未能找到log的具体实现, 虽然编程人员偏译时使用了正确的头文件, 但是在编译的时候还是要连接确定的库, 才能避免上述错误的发生。例如上述程序, 为了使用数学函数, 必须和数学库连接, 因此, 编程人员可加入-lm选项.gcc-o temp temp.c-lm, 只有这样, 才能进行正确的编译。以此类推, 在Linux系统下进行计算机C语言编程时, 编程人员应该根据具体情况, 合理链接相应的数据库, 才可保证编程的正确性。

2.3 加强程序调试

编程人员编写C语言程序并不是一次性就会成功的, 在实际操作中, 会出现很多意想不到的错误, 为避免这种错误, 便要学会对程序的调试。Linux系统下计算机C语言的编程最常应用的调试软件为gdb, 根据界面的不同, 程序调试方法也会有所不同[3]。例如, 如需在图形界面下调试程序, 便选择xxgdb, 且要记得在编译的时候加入-g选项。关于gdb如何使用, 如下作简单叙述:

程序gdb在运行之后, 便会在计算机屏幕上看到这样的内容:

GOB is free software and you are welcome to distribute copiesof it under certain conditions;type”show copying”to see the condi-tions There is absolutely no warranty for GDB;type”show warranty”for Details.

GDB 4.13 (i481-alak-linux) ,

(gdb)

对gdb进行启动时, 还可在命令行上对多个选项进行指定, 也可采用下面的方式进行gdb:gdb<fname>

选择上述方式进行程序调时, 编程人员便可根据自己的实际需求, 指定相应类型的调试程序, 这样操作起来便更加简单、便捷。

2.4 头文件及系统求助

若编程人员进行C语言编写时, 只知道一个函数的大概形式, 却忘记了确切的表达方式, 或是不记得函数在那个头文件进行了说明, 此时便可求助于系统。例如, 编程人员想知识函数fread的确切形式, 便可执行man fread系统, 此时系统会输出函数的详细解释, 并显示出函数fread所在的头文件说明。除了man fread系统之外, Info、Howto也是重要的头文件及系统求助工具, 在Linux系统下计算机C语言的实际编程中, 只要编程人员熟练掌握了求助工具, 很多编程中遇到的难题便会迎刃而解, 进而促进编程的效率与准确性[4,5]。

2.5 灵活应用综合知识

在Linux系统下计算机C语言的编程需要借助多方面知识, 例如, 函数、指针、数组、字符串、变量等方面知识, 均有涉及。因此, C语言另一个编程技巧便是要灵活应用综合知识, 编程人员在实际编写过程中, 需要将这多方面知识整合起来, 灵活、合理、有效地应用到编程中, 才能使计算机C语言编写出来的程序更加完美。此外, 针对不同的C语言结构而言, 若需要在编写同一个C语言程序时同时执行, 必须要注意对综合知识的灵活运用。通过对与C语言编程相关知识的整合、衔接, 才可编写出科学、合理的执行命令, 进一步促进C语言程序编写的完美, 达到最佳的C语言编写效果[6]。

2.6 多上机练习程序编写

在计算机技术应用的普及下, 对于计算机C语言的编程人才也不仅仅是需要理论知识非常强的人, 还需要实践能力强的人才。因此, 在Linux系统下, 学好计算机C语言编程技巧, 便需要编程人员多上机练习程序编写, 才能真正提高计算机C语言编程能力。通过上机练习, 才可以使编程人员的理论知识与实际相联系, 并且, 编程人员在反复上机练习的过程中, 还可以发现许多理论知识掌握不到的地方, 在循序渐进中提高自己的编程能力, 最终为正确、高效地进行计算机C语言编程奠定坚实基础[7,8]。

3 结束语

Linux系统具有很强的网络安全及网络管理功能, 系统稳定性与可靠性强, 目前已经成为操作系统中的重要力量。但在Linux系统下进行计算机C语言编程时, 若对Linux系统及C语言的特点了解不全面, 也会出现编程困难的现象, 因此, 在Linux系统下进行C语言编程时, 就必须掌握一定的编程技巧, 才能提高C语言程序编辑的效果, 为进一步提升C语言编程人员的工作效率打好基础。

参考文献

[1]李俊玲.浅谈Linux操作系统下的C程序开发[J].中国科技财富, 2012, 5 (5) :314.

[2]杨海峰, 席振元, 曹立硕.基于Linux的防火墙系统的研究与开发[J].科技风, 2014, 6 (6) :32-33.

[3]王亚平.基于Linux管道技术的编程方法研究[J].科技资讯, 2012, 13 (13) :46.

[4]李斌.基于ARM-Linux的可编程自动化控制器的研究与开发[D].2012.

[5]夏凡, 陈蜀宇, 龙昌生.基于Framebuffer的嵌入式Linux图形库设计[J].计算机系统应用, 2012, 21 (5) :122-125.

[6]王晓明.计算机C语言编辑程序探讨[J].长春教育学院学报, 2014, 30 (5) :145-146.

[7]余勍, 王捷.浅谈C语言编程技巧在C语言学习中的应用[J].信息通信, 2013, 7 (7) :108.

Linux系统编程 篇6

1 学习C语言的意义

随着近几年计算机C语言技术的不断发展,以及计算机技术在各个领域的不断应用,C语言也在发生着非常大的变化,因此, 美国国家标准研究所(ANSI)为了在最大程度上降低C语言通用性的阻碍,专门制定了统一的C语言标准,目前已经在很多国家得到了广泛应用。C语言具有非常强大的功能,一方面可以用来进行一些系统软件方面的编写,另一方面,还可以进行一些应用软件方面的编写,而且随着计算机技术的不断发展,已经在各行各业得到了广泛应用,因此,C语言强大的程序编辑功能在帮助人们学习、工作以及生活方面起着非常重要的意义。尤其是对那些以后要从事计算机C语言方面工作的人来说,学好C语言编写程序能够将工作变得简单、高效,因此,学好C语言编程对将来的工作以及自己的发展来说都具有非常重要的意义。

2 Linux系统下的计算机C语言编程技巧

对于计算机C语言的初学者来说,C语言需要消耗很大的体力,学习C语言是不能只靠理论的,这需要一系列的亲身实践和上机训练来完成学习的过程,才能将C语言掌握的更好,写出更加完美的程序。书面计算机程序是需要实践来验证的,能在计算机上运行出来的程序才能说是正确的。C语言的主程序运行的流程图(如图1所示),从图1的语言编程的流程图上不难看出,我们在进行书面编写程序是时,并不能轻易地发现程序中存在的漏洞,一个有效的、能够正常运行的程序是需要通过计算机的电子检验的。因此,C语言的学习过程也就是上机练习的过程,将程序放到计算机上进行运行,再运用自已经学习到的理论知识,两者结合起来进行长期的练习,这样经过经验的积累就能够熟练地掌握C语言程序编辑的技巧。以下就简单地分析C语言程序的编辑技巧:

2.1 重视示例程序

在我们学习的过程中,理论知识的学习都是通过学习一些示例来完成的,在学习一个新知识的开始,将知识点通过示例的方式展示出来,我们通过模仿示例来进行知识的理解,最后逐渐形成了自己的思考模式,我们在进行程序的编辑时,最常用到的就是数据结构,在编辑相关的程序之前,我们需要了解各种数据结构的第一个算法的源程序,为数据结构在编辑程序上的正确应用打下坚实基础,而真正透彻地对数据结构进行了解则是正确运用数据结构对程序进行编辑的前提条件。另外,在对自己需要的程序进行编辑之前,组要通过相应的实例进行不断的模仿,从而能够对程序编辑所需的步骤有大体上的了解,针对示例程序中的一些命令的相关掌握程度,还能够在脑海中可以形成一种编写程序的固定思路,从而在遇到类似程序编写时,就可以通过脑海中的固定思路来进行编写,这将会在最大程度上有利于完成程序编写。

2.2 善于使用GCC编译器编译源程序

GNU项目编译器中一个非常重要的具有代表性的组件就是GCC,因此,可以说在Linux系统下,学好计算机C语言编程程序的重要基础就是能够充分掌握好GCC编译器编译源程序相关的方法,因此,必须要学会怎样灵活使用GNU的GCC编译器,从而能够更好的去进行C语言源程序,其中GCC编译器主要的选项表现在以下三个方面:一是,要求输出可以进行执行文件名用-o选项来表示;二是,要求编译器需要将相应的目标代码输出时,用-c选项来表示;三是,要求编译器在进行编译时,需要将程序以后在进行相关调试信息提供时,用-g选项来表示,因此,只要学习者能够将以上三种选项充分掌握好,就能够独立的进行一些比较简单一点的源程序,这也是能够正确使用编译源程序最根本的基础,另外,在进行一些比较困难的源程序时,在掌握这三项的基础上还要掌握更多地选项,我们就以一个简单的例子来说明,现在有一个test.c的源程序为:

从简单的方面来说,该源程序只要在命令下进行执行:gcc -o test test.c就可以进行编译程序,并且GCC编译器就能够自动生成一个test的执行文件,然后在经过执行./test之后,就可以将该源程序的最终解决得出。

2.3 多上机练习程序编写

随着计算机技术应用范围的不断扩大,需要真正具有一定动手能力的人才,而不仅仅是理论知识非常强的人,尤其是在计算机C语言程序学习方面,更要加强上机练习,这也是能够真正学会并提高计算机C语言程序编程能力的唯一措施。目前我国的C语言等级考试中,上机考试占到了七成,笔试仅仅只占三成,由此可见,上机练习对于学好C语言来说是多么的重要,而且C语言的程序编写大部分都是需要在计算机上才能完成,所以,在Linux系统下,学好计算机C语言编程的一个非常重要的技巧就是多进行上机练习,加强理论跟实际之间的联系,这主要是因为上机练习不仅仅是对学到的理论知识和C语言基础知识的一种实际应用,最重要的还是能够在编写过程中发现很多理论知识掌握不好的地方,进而能够使学生们更具有针对性的进行学习和练习,从而能够使学生们讲理论知识掌握的更牢固,这将会在最大程度上使学生们C语言编程能力得到提高,从而对学习计算机C语言程序编程充满兴趣,而且最主要的还是,在多次的上机练习过程中,能够帮助学生们找到编写C语言程序的感觉,再加上每次的联系就会变得越来越熟练,从而达到提高C语言程序编辑能力的目的。

2.4 加强程序调试

程序gdb在运行后,我们会在屏幕上看到这样的内容:

在对gdb进行启动后,还可以在命令行上对多个选项进行指定,当然还可以用下面的方式来进行gdb:

gdb<fname>

在选择以这种方式对gdb进行运行时,就可以根据自己的需求来指定相应的那种类型的调试程序,操作起来就显得更加简便。

2.5 重视综合知识的运用

在进行计算机C语言程序编写时,需要借助大量的各个方面的知识来进行,比如指针、结构以及函数等等,因此,在对计算机C语言进行实际工作上的编写过程中,就需要将这些方面的知识进行综合考虑,选择最合理、最有效的运用,从而使编写出来的程序更加完美。除此之外,对于不同的C语言结构来说,还可以在编写同一个C语言程序时同时执行,这些必须在顺序结构、循环结构以及选择结构的目的,而且在对计算机C语言程序进行编写时,一定要注意对综合指示灯的灵活运用,只有将这些相关的知识进行科学有效的整合,才能编写出相关的执行命令,从而能够使C语言程序编写的更加完美,从而在最大程度上提高对计算机C语言编写的技巧,使C语言程序编写的效果达到最佳。

3 结论

随着计算机技术的不断发展,已经在各行各业得到了广泛的应用,这给人们的工作和生活带来了非常大的帮助,从而对计算机C语言程序编辑提出了更高的要求,因此,加强在Linux系统下的计算机C语言编程技巧,从而在最大程度上提高C语言程序编辑的效果。

摘要:计算机C语言已经在国际上得到了广泛的流行,它是一种多程序编辑的基础语言。随着社会上对计算机C语言技术要求的不断提高,怎样加强在Linux系统下的计算机C语言编程技巧的提高,是目前一个非常严峻的问题,该文就对其进行了详细的探讨。

Linux系统编程 篇7

1. Socket编程

1.1 Socket的建立

为了建立Socket, 程式能够调用Socket函数, 该函数返回一个类似于文档描述符的句柄。Socket描述符是个指向内部数据结构的指针, 他指向描述符表入口。调用Socket函数时, socket执行体将建立一个Socket, 实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。Socket执行体为您管理描述符表。

两个网络程式之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。

1.2 Socket的配置

通过socket调用返回一个socket描述符后, 在使用socket进行网络传输以前, 必须配置该socket。面向连接的socket客户端通过调用Connect函数在socket数据结构中保存本地和远端信息。无连接socket的客户端和服务端连同面向连接socket的服务端通过调用bind函数来配置本地信息。

Bind函数将socket和本机上的一个端口相关联, 随后您就能够在该端口监听服务请求。

使用bind函数时, 能够用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号。注意在使用bind函数是需要将sin_port和sin_addr转换成为网络字节优先顺序;而sin_addr则无需转换。

1.3 建立连接

面向连接的客户程式使用Connect函数来配置socket并和远端服务器建立一个TCP连接, Connect函数启动和远端主机的直接连接。只有面向连接的客户程式使用socket时才需要将此socket和远端主机相连。无连接协议从不建立直接连接。面向连接的服务器也从不启动一个连接, 他只是被动的在协议端口监听客户的请求。

Listen函数使socket处于被动的监听模式, 并为该socket建立一个输入数据队列, 将到达的服务请求保存在此队列中, 直到程式处理他们。

accept () 函数让服务器接收客户的连接请求。在建立好输入队列后, 服务器就调用accept函数, 然后睡眠并等待客户的连接请求。

首先, 当accept函数监控的socket收到连接请求时, socket执行体将建立一个新的socket, 执行体将这个新socket和请求连接进程的地址联系起来, 收到服务请求的初始socket仍能够继续在以前的socket上监听, 同时能够在新的socket描述符上进行数据传输操作。

1.4 数据传输

Send () 和recv () 这两个函数用于面向连接的socket上进行数据传输。

Send () 函数返回实际上发送出的字节数, 可能会少于您希望发送的数据。在程式中应该将send () 的返回值和欲发送的字节数进行比较。当send (返回值和len不匹配时, 应该对这种情况进行处理。

1.5 结束传输

当任何的数据操作结束以后, 您能够调用close () 函数来释放该socket, 从而停止在该socket上的任何数据操作。

调用shutdown () 函数来关闭该socket。该函数允许您只停止在某个方向上的数据传输, 而一个方向上的数据传输继续进行。如您能够关闭某socket的写操作而允许继续在该socket上接受数据, 直至读入任何数据。

2、linux socket的性能优化

2.1 最小化报文传输延迟

禁止使用Nagle算法, 通过设置TCP_NODE-LAY socket选项来禁止它。

2.2 最小化系统调用负载

通过socket来读写数据时, 都必须会用到read和write系统调用, 它跨越了kernel与user空间的边界。另外, 在进入kernel之前, 会通过C库来进入kernel的通用函数system_call () , 从这个函数中会进入文件系统层, kernel在文件系统层中确定正在处理的是哪种设备, 最好进入socket层, 进行数据读取和输出操作, 无法避免这些system call, 因此要力图最小化使用这些call的次数。

所以, 在将数据写入一个socket的时候, 尽量一次写入所有的数据, 不要执行多次写数据的操作;对于读操作来说, 最好传入可支持的最大缓冲区, 因为如果没有足够的数据, kernel也会试图填充整个缓冲区。

2.3 为Bandwidth Delay Product调节tcp窗口

影响TCP性能的两个最重要的因素是连接带宽和往返时间或者RTT。

Sockets API提供了几个socket选项, 其中两个可以用于修改socket的发送和接收缓冲区的大小。尽管socket缓冲区的大小确定了通告TCP窗口的大小, 但是TCP还在通告窗口内维护了一个拥塞窗口。因此, 由于这个拥塞窗口的存在, 给定的socket可能永远都不会利用最大的通告窗口。

2.4 动态优化GNU/linux TCP/IP协议栈

GNU/Linux提供了很多可调节的内核参数, 可以使用这些参数为您自己的用途对操作系统进行动态配置。

在/proc虚拟文件系统中存在一些可调节的内核参数。这个文件系统中的每个文件都表示一个或多个参数, 它们可以通过cat工具进行读取, 或使用echo命令进行修改。

给出了几个可调节的参数, 可以帮助提高Linux TCP/IP栈的性能。

Linux系统编程 篇8

Linux经过了20多年的发展,已经成为一个功能强大而稳定的操作系统,它支持很多硬件平台,目前已经发展到2.6的内核。而Linux下的网络编程应用也是极为广泛,其中套接字的编程最为流行。Linux2.6内核采用了新的线程库Nation POSIX Thread Library(NPTL),该线程库符合POSIX的规范,提供企业级的线程支持。下文将结合Linux下线程的特点来讨论它在网络编程中的应用。

1 套接字编程的基本原理

1.1 socket的类型

在Linux中的网络编程是通过socket接口来进行的。socket也叫做套接字,是一种网络API。它定义了许多函数,我们可以用它来开发网络应用程序。socket接口提供了一种进程间通信的方法,使得在相同主机或不同主机上的进程能以相同的规范进行双向信息通信。进程通过调用socket接口API来实现相互之间的通信,socket接口又利用下层的网络通信协议功能和系统调用实现实际的通信工作。它们之间的关系如图1所示。

常见的socket有3种类型:

(1)流式socket(SOCK_STREAM)。流式套接字提供可靠的、面向连接的通信流,它使用TCP协议。

(2)数据报socket(SOCK_DGRAM)。数据报套接字提供了一种无连接的服务,它使用数据报协议UDP。

(3)原始socket。

1.2 TCP套接字的工作流程

在这里,使用TCP套接字来讨论Linux网络编程。TCP套接字分为服务器端和客户端两个部分。TCP套接字的通信流程如图2所示:

在建立TCP服务器和TCP客户的时候,有两个非常重要的函数:socket()和bind()。

socket()函数用于建立一个socket连接,函数原型为:

int socket(int family,int type,int protocol),其中参数family为协议族,type为套接字类型,protocol为此socket请求所使用的协议。在建立了socket连接之后,就对sockaddr_in进行初始化,以保存所建立的socket信息。

其中sockaddr_in为保存地址结构的结构体,它的结构定义如下:

bind()函数是将将套接字和地址信息相关联,建立地址与套接字的对应关系。函数原型为:int bind (int sockfd,struct sockaddr*my_addr,int addrlen),其中参数socktd为函数socket()返回的套接字描述符,my_addr为本地地址,addrlen为地址长度。

在服务器与客户端都建立起socket连接并与本地地址绑定后,服务器端就利用listen()函数进行监听操作,使客户端连接到该服务器,客户端就可以使用connect()函数来配置套接字来与服务器建立一个TCP连接。服务器端利用accept()函数让服务器收到客户端的连接请求。在建立好输入队列后,服务器就调用accept()函数,然后睡眠并等待客户的连接请求。当accept()函数监视的套接字收到连接请求时,系统核将建立一个新的套接字,系统核将这个新套接字和请求连接进程的地址联系起来,收到服务请求的初始套接字仍可以继续在以前的套接字上监听,同时可以在新的套接字描述符上进行数据传输操作。建立连接完成后,服务器和客户就可以进行双向的数据传输,套接字提供recv()和send()函数来传输数据。当完成数据传输之后,服务器和客户用close()函数来终止连接以释放资源。

2 Linux多线程在网络编程中的应用

2.1 并发服务器

当服务器完成基本配置后,它每次只能处理一个客户的请求,处理完当前客户后,才能处理下一个客户请求。在实际应用中,服务器要处理大量的客户请求,所有客户都访问绑定在某一特定套接字地址的服务器上,因此,服务器需求满足并发的请求。

2.2 多线程的应用

在Linux服务器中,进程与线程都能支持并发,但由于线程占用更少的系统资源,并且线程之间的切换速度更快,所以在这里使用多线程来讨论并发服务器。

Linux2.6内核采用Native POSIX Thread Library (NPTL)线程库,它是与POSIX兼容的。在Linux服务器中实现并发的思路是:主线程循环调用accept()函数,当与客户端连接后,产生子线程来处理客户请求,它的处理流程如图3所示:

在Linux系统中,产生子线程需要调用pthread_create()函数,其函数原型为:

int pthread_create ((pthread_t*thread,pthread_attr_t*attr,void*(*start_routine)(void*),void*arg)),其中参数thread为线程标识符,attr为线程属性设置,start_routine为线程函数的起始地址,arg为传递给start_routine的参数。

服务器运行后,程序首先创建TCP套接字,然后绑定套接字并监听,主线程就循环调用accept()函数,来接受一个客户的连接请求,相关代码如下:

主线程完成与客户的连接后,会返回一个新的套接字描述符connectfd,这时程序再生成一个新的线程,来完成与连接上的客户的通信工作,而主线程仍然在继续监听,以接受新的客户的连接请求。

新的线程生成后,程序会将新的套接字描述符connectfd以及客户的地址信息参数&client传递给新的线程,因为pthread_create()函数每次只能传递新线程一个参数,所以需将上述两个参数封装在一个结构中,结构定义如下:

将结构体信息传递给新线程后,新的线程就可以与客户通信。但这又带来了新的问题,因为变置arg是所有线程共用的,如果主线程接收了新的客户的连接,它就会修改arg的内容,而新线程的arg信息也会被修改。因此,解决上述问题的一种方法是为每个新的线程分配存储arg的空间,在将arg传递给新的线程,新的线程处理完客户信息后再释放arg空间。相关代码如下:

至此,新线程的初始化工作就已完成,新线程将调用recv()和send()函数来实现与客户的通信工作。

3 结束语

讲述了套接字编程的原理,并讨论了Linux多线程在并发服务器中的应用,希望本文对实际的Linux网络编程有所帮助。

参考文献

[1]孙琼.嵌入式Linux应用编程[M].北京:人民邮电出版社,2006.

Linux系统编程 篇9

Blackfin537(BF537)是一款能够运行Linux操作系统的单电路板计算机。Analog Devices 74761(AD7476)是一个插于BF537之上的小型外围电路板。它能够将模拟数据转换为数字数据。其转换速率高达每秒一百万次采样(SPS)。每次采样精度为12位。

在《QEX》杂志中,雷·迈克(Ray Mack)已经介绍过Linux-BF537-AD7476组合,它是一种软件定义无线电原理实验平台。见图1。

我将在本文中详细介绍LinuxBF537环境下的AD7476编程。我会描述BF537上Linux用户空间里所运行的软件。在Linux环境中,串行外围设备(SPI)AD7476对于用户来说看被抽象为文件系统空间。这是Linux一项很有趣的特性。由于硬件外围设备被描述为文件抽象,所以大多数文件操作指令都可以用于它们。这在一定程度上保证了接口的统一性。

首先,让我们考察一下SPI接口,然后再浏览程序,了解AD7476在Linux-BF537环境下的局限与功能。文章还提供了源代码,网上还附有适于BF537的Linux内核安装。

串行外设接口

AD7476接收的是模拟型号输入。它通过一种被称为SPI的接口协议与BF537相连接。见图2。SPI定义了几根连接线以及线上信号的格式。其中三根关键连线为串行时钟(SCK)、芯片选择(CS)以及串行数据(SDATA)。SCK线载有BF537到AD7476的时钟信号。CS线触发模数转换的信号对话。SDATA线载有AD7476到BF537的数字信号采样。

SCK、CS和SDATA间的信号关系描绘于图3中。CS信号的下降沿触发模数转换对话。对话进行期间CS先始终保持低电平。每次采样AD7476产生一个12位的数据,但是发送的确实16位信号。首先发送的是四个零位,接着从最高位到最低位依次发送12位数据。BF537逐位接收信号,并将数据储存进一个16位字的内存中。考虑到CS信号,每次对话需要17个SCK周期。

Linux中的SPI

为了能够使用SPI接口进行用户及编程,需要内核版本为2.6.22或者更高的Linux系统。BF537开发板自带2.6.19版本的内核。如果你想知道当前Linux内核的版本,可以使用以下指令:

root:/>uname–a

它会返回类似以下的文本信息:

Linux blackfin 2.6.22.19-ADI-2008R1.5-svn

我的网页上提供2.6.22版本的内核镜像。你需要在PC上安装TFTP服务以上传镜像至开发板。目前我发现最好的选择方案(无成本)是Weird Solutions4。务必记得关闭电脑上所有防火墙(包括Windows防火墙以及安全软件自带防火墙)。我的网页上还提供了完整的内核加载与启动范例。请注意这些操作不会产生破坏。原镜像仍然保留在BF537上。任何时候复位开发板都可以还原。

采样率设置

接下来我们讨论一下AD7476的SDATA线上串行数据流输出的数据速率计算。首先,必须要了解一下串行数据流的格式。

AD7476的采样率时可变的,记为s。根据数据手册,最大采样率为100万SPS,最小则为0,因为AD7476可以保持闲置状态。采样速率取决于程序设定,但也间接取决于后文描述的一个公式。方程中的参数为系统时钟频率和经过计算的波特数。系统时钟频率,记为f,是一个固定数值,由调用系统函数获得:

ioctl(fd,CMD_SPI_GET_SYSTEMCLOCK,&f);

函数ioctl()能够读取或者设置系统变量。系统时钟频率就是能够使用的变量之一。函数ioctl()有三个参数。第一个代表AD7476设备。第二个是代表使用方式的常数与系统变量名称。第三个参数代表储存ioctl()返回值的用户变量。在BF547中,ioctl90返回100MHz。注意到数值上系统时钟频率要高于采样率。

波特数,记为b,是一个范围从1至65535波特的16位数值。其具体数值要精确选择以便计算出的采样率尽可能的与理想采样率相吻合。首先,系统时钟频率与波特率决定了串行时钟频率,也就是sck,根据公式:

每个系统时钟周期包含两个脉冲,一个低脉冲和一个高脉冲。换而言之,它包含两个波特。分母2b表示串行时钟每跳之前系统时钟必须跳的次数。系统时钟每跳2b波特次,串行时钟跳一次。系统如下调用ioctl()来设置系统时钟频率:

ioctl(fd,CMD_SPI_SET_BAUDRATE,f/(2*b))

每个模数转换对话需要17个系统时钟周期。响应的采样率以单位SPS描述如下:

剩下的问题是b的计算,使得计算采样率尽可能的与理想采样率接近。如果我们将公式1代入公式2,可以得到如下关系:

既然f固定,那么和可能找不到一个合适的b使得计算采样率完全符合理想采样率s’。波特数应该选择为满足以下关系的最小整数。

此式可改写为:

如果选择b为以下值即可满足公式:

此处使用了向下取整符号。x的向下取整,记为返回x的整数部分。在C语言编程中,可如下编写(假设所有变量都为整数):

b=f/(34*s);

范例1:

如果f等于100MHz,s’等于1MSPS。那么表达式等于2。计算采样值s=f/34b或者1,470,588SPS。

范例2:

如果f等于100MHz,s’等于900kSPS。表达式等于3。串行时钟频率sck=f/(2×3)=16666666Hz。计算采样频率为s=f/34b或者980,392SPS。

根据范例1,如果我们选择b等于2,AD7476时钟过快,结果可能回不正确。范例2告诉我们b至少等于3,这样一来BF537-AD7476组合的可达到的设计采样频率最高为980,392SPS。

AD7476开发板的核心元件是一片也称为AD7476的小型集成电路。该IC的输出电压标记是Vdd。这个电压有两个角色。它为集成电路供电,同时还可作为参考电压。当输入信号电平为0时,采样电压最小,为0。当信号电平与Vdd相同时,采样电压最大(2的12减1次方或4095)。对于AD7476开发板,该电压为4.11V。

编程

接下来我们讨论在Linux环境中从AD7476中读取数据的C语言编程。该范例是根据网页(http://docs.blach fin.vclinux.org/doku.php)中范例所编写。我们用一个名为Data的结构体来描述AD7476代表的信息。

AD7476既可以工作于交流模式,也可以工作于直流模式。具体模式取决于AD7476输入线上的模拟信号类型。字段mode记录了程序员的相关选择。所需采样频率储存于字段s中。依照Linux,每一个硬件外设,比如硬盘或者网卡,在系统中被描述为一个硬件抽象。每种硬件都有个名称。所有的硬件设备都在目录/dev下列出。AD7476在其中显示成名为/dev/spi的设备。在程序中,所有的名称必须被映射到称为文件描述符的具体数值上,字段fd即为该参考值。程序员还必须分配内存空间以储存来自AD7476的采样数据。字段samples储存了指向该内存的指针。它被定义为C语言中一个指向缓冲区的无符号短整型指针,即16位无符号值。长度单位是字节。缓冲区的长度以字节单位储存于字段nsamples中。该结构定义在一个.h文件中,并被主程序所包含。接下来我们考察主程序:

首先,生命了一个Data型的变量,名为data。本例中,选择输入模式为AC。采样频率设置为980,392SPS。采样缓冲区长度定义为NSAMPLES。实际缓冲区域由函数AllocateMemory()动态分配。它使用一个参数指针指向变量data。该函数分配空间,并储存一个指向变量data中samples字段的指针。接下来,函数Sample()使用一个指向变量data的指针参数实现对AD7476的读取功能。最后函数PrintSamples()将结果打印成兼容工具Octave和MATLAB的格式。有必要考察一下函数Sample()的代码,附录1见本刊网站(www.ele169.com)。

该函数从AD7476读取采样。简化起见,函数省略了错误校验与处理。第一步调用了系统函数open()。其参数使用了Linux对AD7476的系统抽象名称,以便接下来使用该设备。函数setSckFreq()用于设置AD7476的串行时钟频率,参数分别是第一参数、所需采样率和第二参数。函数setSckFreq()实现了采样率设置一节中所描述的算法。调用系统函数read()从AD7476获得采样数据。具体参数为设备参考数值、指向缓冲区的指针以及缓冲区长度字节。注意到存储空间比所需采样数多一个。由于某种原因,第一次采样并不连续,其读取结果在稍后被忽略。参看附录1中完整代码。

采样绘图

上一篇:民主竞争下一篇:固体绝缘环网柜