《嵌入式系统设计与应用》——学习笔记04(第四章 嵌入式Linux程序开发基础)

第四章 嵌入式Linux程序开发基础

本章要点
⑴嵌入式Linux编译器GCC的使用。
⑵“文件包含”处理。
⑶Make命令和Makefile文件。
⑷Linux Shell编程方法。
⑸位运算。

4.1嵌入式Linux编译器

4.1.1 Linux下C语言编译过程

Linux下C语言程序设计与在其他环境中的C语言程序设计一样,主要涉及编辑器、编译链接器、调试器及项目管理工具。

1.编辑器:常用的是vi和gedit等。
2.编译链接器:常用的是GCC编译器。
3.调试器:方便程序员调试程序。
4.项目管理器:常用的是make,类似于VC里的“工程”。

4.1.2 GCC编译器

1.GCC编译器
Linux系统下的GCC(GNU C Compiler)是GNU项目推出的功能强大、性能优越的多平台编译器。GCC是可以在多种硬件平台上编译出可执行程序的超级编译器,与一般的编译器相比其平均执行效率要高20%~30%。
GCC编译器能将C、C++语言程序、汇编语言源程序和目标程序编译、链接成可执行文件;如果没有给出可执行文件的名字,GCC将自动生成一个名为a.out的文件。

2.GCC的执行过程
一般要经历4个相互关联的步骤:预处理(也称预编译,Preprocessing),编译(Compilation)、汇编(Assembly)和链接(Linking)。

3.GCC的基本用法和选项
GCC最基本的用法:
gcc [options] [filenames]
其中,options为编译器所需要的参数;filenames纹相关的文件名称。

-c:只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。

-o output_filename:确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,GCC就给出预设的可执行文件a.out。

-g:产生符号调试工具(GNU的gdb)所必须的符号资讯,要想对源代码调试,就要加这个选项。

-o:对程序进行优化编译、链接。

-o2:比-o更好的优化。

4.GCC使用的函数库
1)函数库
函数库可以看作是实现编写好了的函数集合,它与主函数分离,从而增加程序开发的服用性。Linux中的函数库可以分为3种:静态函数库、共享函数库和动态函数库

2)相关路径选项
由于通常库文件不是在系统默认的路径下,因此,GCC在编译时要指定库文件的位置,就需要用到相关路径选项:
-I dirname
将dirname所指定的目录加入到程序头文件目录表中,这时GCC就会到相应的位置查找对应的目录。

4.2“文件包含”处理

1.头文件
在C语言中,需要利用头文件来定义结构、常量以及声明函数的原理,大多数C的头文件都存放在/usr/include及其子目录下。

2.“文件包含”处理
“文件包含”处理是把一个源文件的内容包含到本程序中。其作用是减少编写程序的重复劳动,即把一些要重复使用的代码编写到一个“头文件”(*.h)中,然后在程序中用#include 命令来实现“文件包含”的操作。这个操作就是为了适应较大规模的程序设计,为了适应模块化编程的需要,可以将组成C语言程序的各个功能函数分割到多个程序文件中,分别由不同人员负责编程,最后用#include 命令将它们嵌入到一个总的程序文件中去。

4.3 make命令和makefile工程管理

4.3.1 认识make

一个简单的例子来看make和makefile文件的作用,该例子涉及mysum.h、mysum.c和ex_sum.c 3个文件,编写一个makefile文件如下:

sun: ex_sum.c mysum.c
	gcc ex_sum.c mysum.c -o sum
ex_sum.o: ex_sum.c
	gcc -c ex_sum.c
mysum.o: mysum.c mysum.h
	gcc -c mysum.c

注意,每个命令换行前面不是空格,二是按下的Tab键的制表符号位。将其保存为makefile,文件名没有后缀。然后在Linux环境下执行make命令,其运行结果如下:

[root@localhost sum]# make
gcc -c ex_sum.c
gcc -c mysum.c
gcc ex_sum.o mysum.o -o sum

将ex_sum.c和mysum.c编译成在Linux环境下的可执行文件sum。从这个例子可以看出,makefile是make命令读入的配置文件。在一个makefile中,通常包含以下内容:
1)需要由make工具创建的目标体(target),通常是目标文件或可执行文件。
2)要创建的目标体所依赖的文件(dependency_file)。
3)创建每个目标时需要运行的命令(command)。

4.3.2 makefile变量

为了进一步简化编辑和维护makefile,make允许在makefile中创建和使用变量。变量是在makefile中定义的名字,用来代替一个文本字符串,该文本字符串称为该变量的值。定义变量的方式有两种:一种是递归展开方式;一种是简单的方式。

递归展开方式定义的变量是在引用该变量时替换的,即如果该变量包含了对其他变量的应用,则在引用该变量时一次性将内嵌的变量全部展开。
简单扩展型变量的值在定义处展开,并且只展开一次,因此它不包含对其他变量的引用,从而消除变量的嵌套引用。

递归展开方式的定义格式为:

VAR = var

简单扩展方式的定义格式为:

VAR: = var

make中的变量无论采用哪种方式定义使用时,格式均为:

$ (VAR)

看例子更清楚(递归展开方式):

OBJS = main.o mytool1.o mytool2.o
CC = gcc
main: $(OBJS)
	$(CC) $(OBJS) -o main
main.o: main.c
	$(CC) -c main.c
mytool1.o: mytool1.c mytool1.h
	$(CC) -c mytool1.c
mytool2.o: mytool2.c mytool2.h
	$(CC) -c mytool2.c

makefile中常见的自动变量
makefile中常见的自动变量

4.3.3 makefile规则

makefile的规则是make进行处理的依据,它包括了目标体、依赖文件及其之间的命令语句。一般地,makefile中的一条语句就是一个规则。为了简化makefile的编写,make定义了两种类型的规则,即隐式规则和模式规则

1.隐式规则
使用makefile时,有一些语句经常使用,而且使用频率非常高的语句,隐式规则就是告诉make使用默认的方式来编译任务。如上面的例子就可以写成:

OBJS = main.o mytool1.o mytool2.o
CC = gcc
main: $(OBJS)
	$(CC) $^ -o $@

省略了后面6句。==因为隐式规则指出:所有“.o”文件都可自动由“.c”文件使用命令

$(CC) -c <file.c> -o <file.o>

生成。这样main.o、mytool1.o和mytool2.o就会分别调用“$(CC) -c $ < -o $@”来生成。

2.模式规则
为了让隐式规则适合更普遍的情况,模式规则规定,在目标文件的定义时需要用“%”字符。“%”表示一个或多个任意字符,与文件名匹配。在依赖文件中同样可以使用“%”,只是依赖文件中的“%”取值,取决于目标文件。
例如,“%.c”表示以“.c”结尾的文件名(文件名的长度至少为3),而“s.%.c”则表示以“s.开头”、“.c”结尾的文件名(文件名的长度至少为5)
对于上面的代码,使用模式规则:

OBJS = main.o mytool1.o mytool2.o
CC = gcc
main: $(OBJS)
	$(CC) $^ -o $@
%.o: %.c
	$(CC) -c $< -o $@

4.3.4 make命令的使用

make的命令行选项

4.5 嵌入式Linux Shell编程

Shell是用户与Linux系统间的接口程序,它允许用户向操作系统输入需要执行的命令。当用户在终端窗口输入命令时,系统会利用解释器解释这些命令,从而执行相应的操作。

4.5.1 Shell语法基础

1.Shell脚本文件

1)Shell脚本文件结构
Shell脚本文件的结构是固定的,直接看简单的示例:

#! /bin/bash
echo "Hello World!"

将文件保存为 hello.sh。Shell文件的第一行必须以“#!”开头,这是用来告诉系统它后面的参数是用来执行该文件的解释器。在这个例子中,要使用/bin/bash解释器来解释并执行程序。

2)编译Shell脚本文件
编译命令为:
chomd + x[文件名],例如:

chmod + x hello.sh

3)执行已经编译过的Shell文件

[root@localhost shell] # ./hello.sh
Hello World!

也可以不经过编译,直接使用sh命令来执行:

[root@localhost shell] # sh hello.sh
Hello World!

4)Shell脚本文件的注释语句
在Shell脚本文件中,以#开头的语句表示注释。但第一行“#!”的语句不是注释。

2.Shell的变量及配置文件
Shell脚本文件的变量共有3种,即用户变量、环境变量和系统变量
1)用户变量
变量赋值。给变量赋值时,要使用赋值符号(=)。例如:

a="hello world"		//给变量a赋值

赋值号=的两边不允许有空格
获取变量的值。获取变量值时,要在变量前面添加$符号,例如:

echo $a			//就会打印变量a的值

2)环境变量
由关键字export说明的变量叫环境变量。例如:

[root@localhost shell] # export abc=/mnt/shell
[root@localhost shell] # echo $abc
/mnt/shell

3)系统变量(Shell内部定义的变量)
用的地方不多,主要在表示参数时使用。

系统变量作用
$0当前程序的名称。
$n当前程序的第n个参数,n=1,2,…9。
$*当前程序的所有参数(不包括程序本身)
$#当前程序的参数个数(不包括程序本身)
$$当前程序的PID
$!执行上一个指令的PID
$?执行上一个指令的返回值

注意:单引号’'与双引号“”不同。区别是:
单引号’ '中包括字符串,如果字符串中包含保留字符,则保留字符失效,按原样输出。如:

x=5
echo 'x=$x'

输出结果为 x=$x。

双引号" "中包括字符串,如果字符串中包含保留字符,则保留字符生效。如:

x=5
echo "x=$x"

输出结果为 x=5。

4.5.2 Shell的流程控制语句

Shell脚本文件中用条件语句和循环语句来控制程序的执行流程。

1.条件语句
从if开始,到fi结束。格式为:

if((条件表达式))
then
	#语句块
fi

注意:条件表达式要用双括号括起来

2.循环语句
格式为:

for((循环变量=初值;循环条件表达式;循环变量增量))
do
	#循环体语句块
done

注意:for循环的条件要用双括号括起来

Shell编程示例

例1:编写显示20以内能被3整除的数的Shell脚本程序。
应用vi编辑工具编写:

#! /bin/bash
for((i = 1; i < 20; i++))
do
	if((i%3 == 0))
	then
		echo $i;
	fi
done

将其保存为test1.sh,然后再编译并执行程序。

[root@localhost shell] # chmod +x test1.sh
[root@localhost shell] # ./test1.sh
3
6
9
12
15
18

例2:编写一个“按任意键继续…”的SHell脚本文件。

#! /bin/bash
get_char()
{
	stty - echo
	stty raw
	dd if = /dev/tty bs = 1 count = 1 2>/dev/null	#块大小bs为1,数目也为1;/dev/null表示空设备
	stty -raw
	stty echo
}
echo "Press any key to continue..."
get_char

将其保存为test2.sh,然后再编译并执行程序。

[root@localhost shell] # chmod +x test2.sh
[root@localhost shell] # ./test2.sh
Press any key to continue...

本程序的核心语句是第六行,dd命令是用指定大小的块复制一个文件,并在复制的同时进行指定的转换。在本语句中的“bs=1”表示指定数据块的大小为1个字节。/dev/null表示空设备,语句中的“2>/dev/null”表示输出到空设备中,即没有任何输出。

4.6 位运算

在嵌入式Linux的程序设计中经常要求在位一级进行运算,即位运算。按位操作运算的运算符称为位运算符,C语言提供了6种运算符,即&(按位与)、|(按位或)、^(按位异或)、~(取反)、<<(左移)、>>(右移)。位运算的操作数是整数类型或字符型

这在学习C语言基础的时候应该有所涉略了,这里不做具体运算举例了,可以看这篇博客:
https://blog.csdn.net/c20180630/article/details/57076374

习题
1.编写一个简单的C程序,输出“Hello, Linux.”,在Linux下用GCC进行编译。
2.编写一个计算1+2+3+4…+100de 求和运算程序,编写一个makefile文件,并对其进行编译。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值