嵌入式Linux开发工具的学习

一、gcc编译器
GNU CC(简称为gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。gcc不仅功能强大,而且可以编译如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言,而且gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。
gcc实际上不是一个单独的程序,而是多个程序的集合,因此通常称为工具链。
在这里插入图片描述
1.预处理:在这一阶段,源代码中的所有与处理语句得到处理,例如include语句所包含的文件内容替换掉语句本身,所有的宏定义被展开,根据#ifdef,#if等语句的条件是否成立取舍相应的部分。预处理之后源代码中不在包含任何预处理语句。gcc预处理阶段可以生成 .i的文件,通过 选项 -E可以是编译器在预处理结束时就停止。例如:gcc hello.c -E -o hello.i

2.编译阶段:在这一阶段,编译器对源代码进行词法分析,语法分析,优化操作,最后生成汇编代码,这是整个过程中最重要的一步,因此常把整个过程成为编译。可以用过选项 -S 在gcc进行完编译后就停止,生成 .s 汇编程序。例如:gcc hello.c -S -o hello.s

3.汇编阶段:这一阶段使用汇编进行处理,生成机器语言代码,保存成后缀 .o 的目标文件中。当程序由多个代码文件构成时,每个文件都要先完成汇编工作生成 .o 文件,才能进入下一步链接操作。
目标文件已经是最终程序的一部分了,只是在链接之前还不能执行,可以用过 -c 选项生成目标文件。例如:gcc -c hello.c -o hello.o

4.链接阶段:经过汇编以后的机器代码还不能执行,为了使操作系统能够正确加载可执行文件,文件中必须包含固定格式的信息头,还必须与系统提供的启动代码链接起来,才能正常运行,这些工作都是由链接器来完成的。例如: gcc hello.c -o hello

gcc的其他选项:
-v 显示编译阶段的命令
-ansi 支持符合ANSI标准的C语言程序
-W:屏蔽所有警告
-Wall 显示所有类型的警告信息
-Werror 出现任何警告信息就停止编译
-g 产生调试信息 (使用gdb调试工具)
优化选项:-o1 -o2 -o3 -o0不进行优化
-static 使用静态链接
-library 链接library函数库文件
-L dir 指定连接器的搜索目录 dir
-share 生成共享文件

-Idir 指定头文件的搜索目录
-Ldir 指定搜索目录dir

程序库:包含了一些通用函数的数据和二进制可执行机器码的文件,其单独不能够运行,但是如果将其与其他的可执行程序结合起来就可以执行了。
静态库:是在执行程序之前就已经加入到执行代码中,成为执行程序的一部分来执行的,后缀名:.a
动态库:是在执行程序启动时加载到执行代码中,后缀名:.so

静态库和动态库的区别:动态库只有在使用它的程序执行时才被链接使用,而不是将需要的部分直接编译入可执行文件中,并且一个动态库可以被多个程序使用故可称为共享库,而静态库将会整合到程序中,因此在程序执行时不用加载静态库。 从而可知,链接到静态库会使你的程序臃肿,并且难以升级,但是可能会比较容易部署。而链接到动态库会使你的程序轻便,并且易于升级,但是会难以部署。

静态库的创建:
创建:
gcc –c 源文件.c
ar rcs 静态库名 目标文件1 目标文件2
rc:静态库不存在,就创建该库文件
s:更新库文件
静态库的使用:
静态库创建成功后,然后对全局变量和函数进行声明,在编译的时候加上库文件就行!
gcc -o file flie.c –L. -lname

动态库的创建:
gcc -shared –fPIC –o 库名.so 源文件.c
动态库的使用:
gcc 源文件.c ./ 库名.so –o 可执行文件名

二、vi/vm编辑器
Linux最常用的文本编辑器是vi或vim,vim是vi的升级版。文本编辑器是所有计算机系统中最常使用的工具。用户在使用计算机的时候往往需要创建自己的文件,无论是一般的文件、资料文件,还是编写的源程序,都离不开文本编辑器。
vi是Visual Interface 的简称,在Linux中的地位就像Edit 在 DOS 中一样,它可以执行输出、删除、查找、替换和块操作等众多文本操作。且用户可以根据自己的需要对其进行定制。vi有三种基本工作模式:命令行模式、插入模式、底行模式。
**命令行模式:**控制屏幕光标的移动,字符、字或行的删除,移动复制某区段和进入插入模式或者底行模式。
**插入模式:**只有在插入模式下才可以输入文字,按Esc键可返回命令行模式。
**底行模式:**将文件保存或退出vi,也可以设置编辑环境,如寻找字符串、列出行号等,一般实际使用时把vi简化成两个模式,也就是将底行模式算入命令行模式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三、嵌入式调试器 gdb
gdb是GNU发布的一款功能强大的程序调试工具。但gdb的缺点是没有图形调试界面。GDB主要完成下面三个方面的功能:
1、启动被调试程序。
2、让被调试的程序在指定的位置停住。
3、当程序被停住时,可以检查程序状态-变量值

通过命令
$ gcc -g hello.c -o hello
$ gdb hello
显示如下界面:
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-redhat-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1”.
(gdb)

通过一些gdb中简单的命令对程序进行调试
1.编译生成可执行文件:
gcc -g tst.c -o tst
2.启动GDB
gdb tst
3. 在main函数处设置断点
break main
4. 运行程序
run
5. 单步运行
next(不进被调函数)
step(进被调函数)
6. 继续运行
continue
list(l) 查看程序
break(b) 函数名: 在某函数入口处添加断点
break(b) 行号:在指定行添加断点
break(b) 行号 if 条件 当条件为真时,指定行号处断点生效,例b 5 if i=10,当i等于10时第5行断点生效
info break 查看所有设置的断点
delete 断点编号 删除断点
return ret 从当前函数返回
print§ 变量名 查看指定变量值
finish 运行程序,直到当前函数结束
watch 变量名 对指定变量进行监控
quit(q) 退出gdb
backtrace bt 显示调用栈
x 显示内存值
symbol-file sy 从可执行文件中加载符号表
clear 清楚断点
disable 使断点失效(断点号)
enable 激活断点(断点号)

四、工程管理器-make
一个软件工程通常会包含几十上百个文件,如果每次编译都通过命令行手动编译往往会很麻烦而且效率低下。 在Windows平台上的VC、VB等都有一个工程(Project)的概念。一旦建立了一个工程,这些开发平台会自动地维护其中的各种文件,从而可以很高效地完成编译工作。幸运的是,在Linux中同样有一个功能强大、使用方便的工程管理工具,这就是make。工程管理器,顾名思义,是指管理较多的文件 。Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件文件的内容来执行大量的编译工作 。

makefile是make读入的惟一配置文件,在一个makefile中通常包含如下内容:
a.需要由make工具创建的目标体(target),通常是目标文件或可执行文件;
b.要创建的目标体所依赖的文件;创建每个目标体时需要运行的命令(command),这一行必须以制表符(tab键)开头
makefile的格式:
target: dependency_files
< TAB >command /* 该行必须以tab键开头*/
例如:
hello: hello.o
gcc –o hello hello.o
hello.o:hello.c
gcc –c hello.c
使用makefile:
$ make
gcc –c hello.c –o hello.o
$ ls
hello.c hello.h hello.o makefile

实例:
hello: main.o func1.o func2.o
gcc main.o func1.o func2.o -o hello
main.o : main.c
gcc –c main.c
func1.o : func1.c
gcc –c func1.c
func2.o : func2.c
gcc –c func2.c
.PHONY : clean
clean :
rm –f hello main.o func1.o func2.o

在makefile 中,**规则**的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。
make命令默认在当前目录下寻找名字为makefile或者Makefile的工程文件,当名字不为这两者之一时,可以使用如下方法指定:
	make –f 文件名

Makefile中把那些没有任何依赖只有执行动作的目标称为**“伪目标”**(phonytargets)。
.PHONY : clean
clean :
rm –f hello main.o func1.o func2.o
“.PHONY” 将“clean”目标声明为伪目标

在makefile中,存在系统默认的自动化变量
$^:代表所有的依赖文件
$@:代表目标
$<:代表第一个依赖文件
Makefile中“#”字符后的内容被视作注释。
hello: hello.c
@gcc hello.c –o hello
@:取消回显

makefile的隐含规则: 隐含规则能够告诉make使用传统的标准方法完成任务。例如,生成一个目标文件的方法是使用C编译器编译C语言源程序,这个步骤所用到的命令基本都是相同的。使用隐含规则就无须详细指定这些命令,而make能按照文件名的后缀的变化,决定所采用的规则。
makefile中的赋值操作:在这里插入图片描述
makefile中使用变量时用的是$(),如果变量名只是一个字符,则小括号可以省略。

简单的示例:
objects = main.o mouse.o command.o display.o
CC = gcc
CFLAGS = -Wall -O2 -g
game : $(objects)
$(CC) -o edit $(objects)
main.o : defs.h
mouse.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
.PHONY : clean
clean :
$(RM) edit $(objects)

五、shell脚本

Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。
Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它互动式地解释和执行用户输入的命令;
作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。
shell的种类:
Bourne shell(sh)
Korn shell(ksh)
Bourne Again shell(bash)
C shell(包括csh and tcsh)
TENEX/TOPS C shell(tcsh)

程序必须以下面的行开始(必须方在文件的第一行):
#!/bin/sh
#!用来告诉系统它后面的参数是用来执行该文件的程序。
Shell将符号#后面的部分认为是注释,但这一行是有实际作用的。感叹号!后面的部分指明了要使用sh作为执行脚本的解释器。
脚本中的每一行是一条命令,多条命令也可以写在同一行,用分号;隔开。
要使脚本可执行:
chmod +x filename
然后,您可以通过输入: ./filename 来执行您的脚本

1.变量:
在其他编程语言中您必须使用变量。在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:
变量名=值
取出变量值可以加一个美元符号($)在变量前面
=两边不能有空格,一行语句后不能加分号,除非将两行写到同一行,可以用分号隔开。
#!/bin/sh
#对变量赋值:
a=“hello world”
echo “A is:”
echo $a

可以用{}将要打印的变量括起来,以免变量和其他单词混淆。
默认变量:
$#:传入脚本的命令行参数个数
$*:所有命令行参数值,在各个参数值间留有空格
$0:命令本身(shell文件名)
$1:第一个命令行参数
$2:第二个命令行参数
local 定义一个局部变量

2.分支语句
If [expression]
then
#code block
fi
If [expression]
then
#code block
else
#code block
fi
或者
If [expression]
then
#code block
else if [expression]
then
#code block
else
#code block
fi
fi
不论前面有几个if,最后只写两个fi。
在这里插入图片描述
在这里插入图片描述

例如:
比较整数a和整数b是否相等:if[ $a = $b ]
比较整数a是否大于整数b:if[ $a –gt $b ]
比较字符串a和b是否相等: if[ $a = $b ]
判断字符串a是否为空:if[ -z $a ]
比较整数变量a是否大于b:if[ $a –gt KaTeX parse error: Expected 'EOF', got '#' at position 157: …户可以执行 **例如:** #̲!/bin/sh fold…folder" ] && echo “Can read f o l d e r “ [ − f " folder“ [ -f " folder[f"folder” ] || echo “this is not file”

3.循环语句
for循环与C语言中有所不同,在BASH中for循环的基本结构是:
for var in [list]
do
#code block
done
其中var是循环控制变量, [list]是var需要遍历的一个集合,do/done包含了循环体,相当于c语言中的大括号。另外do和for被写在同一行,必须在do前面加上“;”如: for var in [list];do

While循环的结构是:
while [condition]
do
#code block
done
until循环的结构是:
until [condition]
do
#code block
done
while和until的区别在于while为真时执行,until为假时执行;

BASH语句中的case和c语言中的类似可以用于进行多项分支控制:
case “$var” in
contidion1)
;;
contidion1)
;;
*)
default statements;;
esac

例如:
#!/bin/bash
echo “Hit a key, then hit return.“
read Keypress
case “$Keypress” in
[A-Z] ) echo “Uppercase letter”;;
[a-z] ) echo “Lowercase letter”;;
[0-9] ) echo “Digit”;;
* ) echo “Punctuation, whitespace, or other”;;
esac

4.函数
脚本中支持定义函数,例如:
print3 () {
echo $1 $2 KaTeX parse error: Expected 'EOF', got '#' at position 4: 3 #̲ 显示第一、第二、第三个参数的…加一个数字替换为调用函数时相应位置上的参数,$*则会替换所有参数。
定义函数之后就可以调用它:
print3 embedded linux program # 将显示embedded linux program

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习嵌入式Linux开发时,可以按照以下脉络进行学习: 1. 了解嵌入式系统基础知识:首先,了解嵌入式系统的基本概念和特点,了解硬件平台、操作系统和应用程序之间的关系,以及嵌入式Linux系统的组成部分。 2. 学习Linux基础知识:掌握Linux的基本命令行操作和文件系统管理,了解Linux的目录结构、文件权限和用户管理等。这是嵌入式Linux开发的基础。 3. 学习交叉编译和工具链:了解交叉编译的概念和原理,学习如何配置和使用交叉编译工具链,以便在主机上开发和编译嵌入式Linux应用程序。 4. 掌握Linux内核原理和驱动开发:深入学习Linux内核的原理和结构,了解设备驱动的开发流程和机制。学习如何编写和调试设备驱动程序,以及如何将驱动程序集成到Linux内核中。 5. 理解嵌入式Linux系统启动过程:学习嵌入式Linux系统的启动过程,包括引导加载程序(Bootloader)、内核启动、根文件系统挂载等。了解嵌入式Linux系统的启动流程对于系统的调试和优化非常重要。 6. 学习嵌入式Linux应用程序开发:掌握使用嵌入式Linux平台上的开发工具和库函数开发应用程序。学习如何编写多线程程序、网络编程、文件I/O等常用的嵌入式Linux应用程序。 7. 了解嵌入式系统的性能优化和调试技巧:学习如何对嵌入式Linux系统进行性能优化,包括内存管理、CPU占用、IO等方面。掌握常用的调试工具和技巧,如GDB调试器、性能分析工具等。 8. 实践和项目开发:通过实践和参与项目开发,巩固所学知识。可以尝试构建一些嵌入式Linux应用程序或者参与开源项目,锻炼编程能力和解决问题的能力。 记住,学习嵌入式Linux开发需要不断地实践和深入理解系统原理,同时也需要不断地学习和跟进新的技术和发展趋势。祝您在嵌入式Linux开发的旅程中取得成功!如果您有具体的问题,随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值